Merge "Print API updated." into klp-dev
diff --git a/Android.mk b/Android.mk
index 69d1daf..30b17f5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -142,7 +142,7 @@
 	core/java/android/net/INetworkStatsService.aidl \
 	core/java/android/net/INetworkStatsSession.aidl \
 	core/java/android/net/nsd/INsdManager.aidl \
-	core/java/android/nfc/INdefPushCallback.aidl \
+	core/java/android/nfc/IAppCallback.aidl \
 	core/java/android/nfc/INfcAdapter.aidl \
 	core/java/android/nfc/INfcAdapterExtras.aidl \
 	core/java/android/nfc/INfcTag.aidl \
@@ -535,16 +535,23 @@
     frameworks/base/docs/knowntags.txt
 
 sample_dir := development/samples
+new_sample_dir := developers/samples/android
 
 # the list here should match the list of samples included in the sdk samples package
 # (see development/build/sdk.atree)
 # remove htmlified samples for now -- samples are still available through the SDK
 web_docs_sample_code_flags := \
 		-hdf android.hasSamples 1 \
+		-samplecode $(new_sample_dir)/input/gestures/BasicGestureDetect/BasicGestureDetect \
+ 		            samples/BasicGestureDetect/ "Basic Gestures" \
 		-samplecode $(sample_dir)/AccelerometerPlay \
  		            samples/AccelerometerPlay "Accelerometer Play" \
 		-samplecode $(sample_dir)/ActionBarCompat \
- 		            samples/ActionBarCompat "Action Bar Compatibility"
+ 		            samples/ActionBarCompat "Action Bar Compatibility" \
+ 		-samplecode $(sample_dir)/BluetoothHDP \
+ 		            samples/BluetoothHDP "Bluetooth HDP Demo" \
+ 		-samplecode $(sample_dir)/BluetoothLeGatt \
+ 		            samples/BluetoothLeGatt "Bluetooth HDP Demo"
 #       -samplecode $(sample_dir)/AndroidBeamDemo \
 # 		            samples/AndroidBeamDemo "Android Beam Demo" \
 # 		-samplecode $(sample_dir)/ApiDemos \
@@ -557,8 +564,6 @@
 # 		            samples/BackupRestore "Backup and Restore" \
 #		-samplecode $(sample_dir)/BluetoothChat \
 # 		            samples/BluetoothChat "Bluetooth Chat" \
-# 		-samplecode $(sample_dir)/BluetoothHDP \
-# 		            samples/BluetoothHDP "Bluetooth HDP Demo" \
 # 		-samplecode $(sample_dir)/BusinessCard \
 # 		            samples/BusinessCard "Business Card" \
 # 		-samplecode $(sample_dir)/ContactManager \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 215d108..39742db6 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -175,6 +175,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionClient.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/os/IBattery*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/current.txt b/api/current.txt
index 3887630..87c288c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -261,7 +261,7 @@
     field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
     field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
     field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
-    field public static final int addPrintersActivity = 16843747; // 0x10103e3
+    field public static final int addPrintersActivity = 16843750; // 0x10103e6
     field public static final int addStatesFromChildren = 16842992; // 0x10100f0
     field public static final int adjustViewBounds = 16843038; // 0x101011e
     field public static final int alertDialogIcon = 16843605; // 0x1010355
@@ -289,13 +289,14 @@
     field public static final deprecated int animationResolution = 16843546; // 0x101031a
     field public static final int antialias = 16843034; // 0x101011a
     field public static final int anyDensity = 16843372; // 0x101026c
+    field public static final int apduServiceBanner = 16843758; // 0x10103ee
     field public static final int apiKey = 16843281; // 0x1010211
     field public static final int author = 16843444; // 0x10102b4
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
     field public static final int autoLink = 16842928; // 0x10100b0
-    field public static final int autoMirrored = 16843752; // 0x10103e8
+    field public static final int autoMirrored = 16843755; // 0x10103eb
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
@@ -336,7 +337,7 @@
     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 category = 16843749; // 0x10103e5
+    field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
     field public static final int centerColor = 16843275; // 0x101020b
     field public static final int centerDark = 16842952; // 0x10100c8
@@ -392,7 +393,7 @@
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
     field public static final int customNavigationLayout = 16843474; // 0x10102d2
-    field public static final int customRoots = 16843751; // 0x10103e7
+    field public static final int customRoots = 16843754; // 0x10103ea
     field public static final int customTokens = 16843579; // 0x101033b
     field public static final int cycles = 16843220; // 0x10101d4
     field public static final int dashGap = 16843175; // 0x10101a7
@@ -486,6 +487,7 @@
     field public static final int fadeScrollbars = 16843434; // 0x10102aa
     field public static final int fadingEdge = 16842975; // 0x10100df
     field public static final int fadingEdgeLength = 16842976; // 0x10100e0
+    field public static final int fadingMode = 16843745; // 0x10103e1
     field public static final int fastScrollAlwaysVisible = 16843573; // 0x1010335
     field public static final int fastScrollEnabled = 16843302; // 0x1010226
     field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
@@ -611,7 +613,7 @@
     field public static final int installLocation = 16843447; // 0x10102b7
     field public static final int interpolator = 16843073; // 0x1010141
     field public static final int isAlwaysSyncable = 16843571; // 0x1010333
-    field public static final int isAsciiCapable = 16843750; // 0x10103e6
+    field public static final int isAsciiCapable = 16843753; // 0x10103e9
     field public static final int isAuxiliary = 16843647; // 0x101037f
     field public static final int isDefault = 16843297; // 0x1010221
     field public static final int isIndicator = 16843079; // 0x1010147
@@ -844,6 +846,7 @@
     field public static final int prompt = 16843131; // 0x101017b
     field public static final int propertyName = 16843489; // 0x10102e1
     field public static final int protectionLevel = 16842761; // 0x1010009
+    field public static final int provideAssistData = 16843759; // 0x10103ef
     field public static final int publicKey = 16843686; // 0x10103a6
     field public static final int queryActionMsg = 16843227; // 0x10101db
     field public static final int queryAfterZeroResults = 16843394; // 0x1010282
@@ -868,7 +871,7 @@
     field public static final int reqKeyboardType = 16843304; // 0x1010228
     field public static final int reqNavigation = 16843306; // 0x101022a
     field public static final int reqTouchScreen = 16843303; // 0x1010227
-    field public static final int requireDeviceUnlock = 16843754; // 0x10103ea
+    field public static final int requireDeviceUnlock = 16843757; // 0x10103ed
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
@@ -967,12 +970,13 @@
     field public static final int spinnersShown = 16843595; // 0x101034b
     field public static final int splitMotionEvents = 16843503; // 0x10102ef
     field public static final int src = 16843033; // 0x1010119
-    field public static final int ssp = 16843744; // 0x10103e0
-    field public static final int sspPattern = 16843746; // 0x10103e2
-    field public static final int sspPrefix = 16843745; // 0x10103e1
+    field public static final int ssp = 16843747; // 0x10103e3
+    field public static final int sspPattern = 16843749; // 0x10103e5
+    field public static final int sspPrefix = 16843748; // 0x10103e4
     field public static final int stackFromBottom = 16843005; // 0x10100fd
     field public static final int starStyle = 16842882; // 0x1010082
     field public static final int startColor = 16843165; // 0x101019d
+    field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
     field public static final deprecated int startYear = 16843132; // 0x101017c
     field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -1016,7 +1020,7 @@
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsRtl = 16843695; // 0x10103af
-    field public static final int supportsSwitchingToNextInputMethod = 16843753; // 0x10103e9
+    field public static final int supportsSwitchingToNextInputMethod = 16843756; // 0x10103ec
     field public static final int supportsUploading = 16843419; // 0x101029b
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
@@ -1033,7 +1037,7 @@
     field public static final int targetActivity = 16843266; // 0x1010202
     field public static final int targetClass = 16842799; // 0x101002f
     field public static final int targetDescriptions = 16843680; // 0x10103a0
-    field public static final int targetID = 16843740; // 0x10103dc
+    field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetPackage = 16842785; // 0x1010021
     field public static final int targetSdkVersion = 16843376; // 0x1010270
     field public static final int taskAffinity = 16842770; // 0x1010012
@@ -1138,6 +1142,7 @@
     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 transitionOrdering = 16843744; // 0x10103e0
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
     field public static final int type = 16843169; // 0x10101a1
@@ -1156,7 +1161,7 @@
     field public static final int valueTo = 16843487; // 0x10102df
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
-    field public static final int vendor = 16843748; // 0x10103e4
+    field public static final int vendor = 16843751; // 0x10103e7
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -2347,7 +2352,6 @@
     method public abstract long getDuration();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
-    method public java.util.ArrayList<android.animation.Animator.AnimatorPauseListener> getPauseListeners();
     method public abstract long getStartDelay();
     method public boolean isPaused();
     method public abstract boolean isRunning();
@@ -6900,59 +6904,6 @@
     method public abstract void onStatusChanged(int);
   }
 
-  public class UndoManager {
-    ctor public UndoManager();
-    method public void addOperation(android.content.UndoOperation<?>, int);
-    method public void beginUpdate(java.lang.CharSequence);
-    method public int commitState(android.content.UndoOwner);
-    method public int countRedos(android.content.UndoOwner[]);
-    method public int countUndos(android.content.UndoOwner[]);
-    method public void endUpdate();
-    method public int forgetRedos(android.content.UndoOwner[], int);
-    method public int forgetUndos(android.content.UndoOwner[], int);
-    method public int getHistorySize();
-    method public android.content.UndoOperation<?> getLastOperation(int);
-    method public android.content.UndoOperation<?> getLastOperation(android.content.UndoOwner, int);
-    method public T getLastOperation(java.lang.Class<T>, android.content.UndoOwner, int);
-    method public android.content.UndoOwner getOwner(java.lang.String, java.lang.Object);
-    method public java.lang.CharSequence getRedoLabel(android.content.UndoOwner[]);
-    method public java.lang.CharSequence getUndoLabel(android.content.UndoOwner[]);
-    method public int getUpdateNestingLevel();
-    method public boolean hasOperation(android.content.UndoOwner);
-    method public boolean isInUndo();
-    method public boolean isInUpdate();
-    method public int redo(android.content.UndoOwner[], int);
-    method public void restoreInstanceState(android.os.Parcelable);
-    method public android.os.Parcelable saveInstanceState();
-    method public void setHistorySize(int);
-    method public void setUndoLabel(java.lang.CharSequence);
-    method public void suggestUndoLabel(java.lang.CharSequence);
-    method public boolean uncommitState(int, android.content.UndoOwner);
-    method public int undo(android.content.UndoOwner[], int);
-    field public static final int MERGE_MODE_ANY = 2; // 0x2
-    field public static final int MERGE_MODE_NONE = 0; // 0x0
-    field public static final int MERGE_MODE_UNIQUE = 1; // 0x1
-  }
-
-  public abstract class UndoOperation implements android.os.Parcelable {
-    ctor public UndoOperation(android.content.UndoOwner);
-    ctor protected UndoOperation(android.os.Parcel, java.lang.ClassLoader);
-    method public boolean allowMerge();
-    method public abstract void commit();
-    method public int describeContents();
-    method public android.content.UndoOwner getOwner();
-    method public DATA getOwnerData();
-    method public boolean hasData();
-    method public boolean matchOwner(android.content.UndoOwner);
-    method public abstract void redo();
-    method public abstract void undo();
-  }
-
-  public class UndoOwner {
-    method public java.lang.Object getData();
-    method public java.lang.String getTag();
-  }
-
   public class UriMatcher {
     ctor public UriMatcher(int);
     method public void addURI(java.lang.String, java.lang.String, int);
@@ -11921,6 +11872,7 @@
     field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
     field public static final java.lang.String KEY_PROXIMITY_ENTERING = "entering";
     field public static final java.lang.String KEY_STATUS_CHANGED = "status";
+    field public static final java.lang.String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
     field public static final java.lang.String NETWORK_PROVIDER = "network";
     field public static final java.lang.String PASSIVE_PROVIDER = "passive";
     field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
@@ -11947,13 +11899,14 @@
     ctor public SettingInjectorService(java.lang.String);
     method protected abstract android.location.SettingInjectorService.Status getStatus();
     method protected final void onHandleIntent(android.content.Intent);
-    field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "com.android.location.InjectedSettingChanged";
+    field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
+    field public static final java.lang.String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+    field public static final java.lang.String ATTRIBUTES_NAME = "injected-location-setting";
+    field public static final java.lang.String META_DATA_NAME = "android.location.SettingInjectorService";
   }
 
   public static final class SettingInjectorService.Status {
     ctor public SettingInjectorService.Status(java.lang.String, boolean);
-    field public final boolean enabled;
-    field public final java.lang.String summary;
   }
 
 }
@@ -12890,7 +12843,9 @@
     field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
     field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
     field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
+    field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
     field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
+    field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
     field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
     field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
     field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -15198,7 +15153,7 @@
     method public void disableReaderMode(android.app.Activity);
     method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]);
     method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
-    method public void enableReaderMode(android.app.Activity, int);
+    method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
@@ -15214,12 +15169,14 @@
     field public static final java.lang.String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
     field public static final java.lang.String EXTRA_ID = "android.nfc.extra.ID";
     field public static final java.lang.String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
+    field public static final java.lang.String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
     field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
     field public static final int FLAG_READER_KOVIO = 16; // 0x10
     field public static final int FLAG_READER_NFC_A = 1; // 0x1
     field public static final int FLAG_READER_NFC_B = 2; // 0x2
     field public static final int FLAG_READER_NFC_F = 4; // 0x4
     field public static final int FLAG_READER_NFC_V = 8; // 0x8
+    field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
     field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
     field public static final int STATE_OFF = 1; // 0x1
     field public static final int STATE_ON = 3; // 0x3
@@ -15239,6 +15196,10 @@
     method public abstract void onNdefPushComplete(android.nfc.NfcEvent);
   }
 
+  public static abstract interface NfcAdapter.ReaderCallback {
+    method public abstract void onTagDiscovered(android.nfc.Tag);
+  }
+
   public final class NfcEvent {
     field public final android.nfc.NfcAdapter nfcAdapter;
   }
@@ -15285,7 +15246,6 @@
     method public final android.os.IBinder onBind(android.content.Intent);
     method public abstract void onDeactivated(int);
     method public byte[] processCommandApdu(byte[], android.os.Bundle);
-    method public abstract deprecated byte[] processCommandApdu(byte[], int);
     method public final void sendResponseApdu(byte[]);
     field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
     field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
@@ -25484,6 +25444,119 @@
 
 }
 
+package android.transition {
+
+  public class AutoTransition extends android.transition.TransitionSet {
+    ctor public AutoTransition();
+  }
+
+  public class ChangeBounds extends android.transition.Transition {
+    ctor public ChangeBounds();
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+    method public void setReparent(boolean);
+    method public void setResizeClip(boolean);
+  }
+
+  public class Fade extends android.transition.Visibility {
+    ctor public Fade();
+    ctor public Fade(int);
+    field public static final int IN = 1; // 0x1
+    field public static final int OUT = 2; // 0x2
+  }
+
+  public final class Scene {
+    ctor public Scene(android.view.ViewGroup);
+    ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
+    method public void enter();
+    method public void exit();
+    method public static android.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
+    method public android.view.ViewGroup getSceneRoot();
+    method public void setEnterAction(java.lang.Runnable);
+    method public void setExitAction(java.lang.Runnable);
+  }
+
+  public abstract class Transition implements java.lang.Cloneable {
+    ctor public Transition();
+    method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
+    method public android.transition.Transition addTarget(android.view.View);
+    method public android.transition.Transition addTargetId(int);
+    method public abstract void captureEndValues(android.transition.TransitionValues);
+    method public abstract void captureStartValues(android.transition.TransitionValues);
+    method public android.transition.Transition clone();
+    method public android.animation.Animator createAnimator(android.view.ViewGroup, android.transition.TransitionValues, android.transition.TransitionValues);
+    method public long getDuration();
+    method public android.animation.TimeInterpolator getInterpolator();
+    method public java.lang.String getName();
+    method public long getStartDelay();
+    method public java.util.List<java.lang.Integer> getTargetIds();
+    method public java.util.List<android.view.View> getTargets();
+    method public java.lang.String[] getTransitionProperties();
+    method public android.transition.TransitionValues getTransitionValues(android.view.View, boolean);
+    method public android.transition.Transition removeListener(android.transition.Transition.TransitionListener);
+    method public android.transition.Transition removeTarget(android.view.View);
+    method public android.transition.Transition removeTargetId(int);
+    method public android.transition.Transition setDuration(long);
+    method public android.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+    method public android.transition.Transition setStartDelay(long);
+  }
+
+  public static abstract interface Transition.TransitionListener {
+    method public abstract void onTransitionCancel(android.transition.Transition);
+    method public abstract void onTransitionEnd(android.transition.Transition);
+    method public abstract void onTransitionPause(android.transition.Transition);
+    method public abstract void onTransitionResume(android.transition.Transition);
+    method public abstract void onTransitionStart(android.transition.Transition);
+  }
+
+  public class TransitionInflater {
+    method public static android.transition.TransitionInflater from(android.content.Context);
+    method public android.transition.Transition inflateTransition(int);
+    method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
+  }
+
+  public class TransitionManager {
+    ctor public TransitionManager();
+    method public static void beginDelayedTransition(android.view.ViewGroup);
+    method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition);
+    method public static android.transition.Transition getDefaultTransition();
+    method public static void go(android.transition.Scene);
+    method public static void go(android.transition.Scene, android.transition.Transition);
+    method public void setDefaultTransition(android.transition.Transition);
+    method public void setTransition(android.transition.Scene, android.transition.Transition);
+    method public void setTransition(android.transition.Scene, android.transition.Scene, android.transition.Transition);
+    method public void transitionTo(android.transition.Scene);
+  }
+
+  public class TransitionSet extends android.transition.Transition {
+    ctor public TransitionSet();
+    method public android.transition.TransitionSet addTransition(android.transition.Transition);
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+    method public int getOrdering();
+    method public android.transition.TransitionSet removeTransition(android.transition.Transition);
+    method public android.transition.TransitionSet setOrdering(int);
+    field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
+    field public static final int ORDERING_TOGETHER = 0; // 0x0
+  }
+
+  public class TransitionValues {
+    ctor public TransitionValues();
+    field public final java.util.Map values;
+    field public android.view.View view;
+  }
+
+  public abstract class Visibility extends android.transition.Transition {
+    ctor public Visibility();
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+    method public boolean isVisible(android.transition.TransitionValues);
+    method public android.animation.Animator onAppear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+    method public android.animation.Animator onDisappear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+  }
+
+}
+
 package android.util {
 
   public class AndroidException extends java.lang.Exception {
@@ -27380,7 +27453,6 @@
     method public java.lang.CharSequence getContentDescription();
     method public final android.content.Context getContext();
     method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
-    method public android.view.transition.Scene getCurrentScene();
     method public static int getDefaultSize(int, int);
     method public android.view.Display getDisplay();
     method public final int[] getDrawableState();
@@ -29657,155 +29729,6 @@
 
 }
 
-package android.view.transition {
-
-  public class AutoTransition extends android.view.transition.TransitionGroup {
-    ctor public AutoTransition();
-  }
-
-  public class Crossfade extends android.view.transition.Transition {
-    ctor public Crossfade();
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-    method public int getFadeBehavior();
-    method public int getResizeBehavior();
-    method public void setFadeBehavior(int);
-    method public void setResizeBehavior(int);
-    field public static final int FADE_BEHAVIOR_CROSSFADE = 0; // 0x0
-    field public static final int FADE_BEHAVIOR_OUT_IN = 2; // 0x2
-    field public static final int FADE_BEHAVIOR_REVEAL = 1; // 0x1
-    field public static final int RESIZE_BEHAVIOR_NONE = 0; // 0x0
-    field public static final int RESIZE_BEHAVIOR_SCALE = 1; // 0x1
-  }
-
-  public class Fade extends android.view.transition.Visibility {
-    ctor public Fade();
-    ctor public Fade(int);
-    field public static final int IN = 1; // 0x1
-    field public static final int OUT = 2; // 0x2
-  }
-
-  public class Move extends android.view.transition.Transition {
-    ctor public Move();
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-    method public void setReparent(boolean);
-    method public void setResizeClip(boolean);
-  }
-
-  public class Recolor extends android.view.transition.Transition {
-    ctor public Recolor();
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-  }
-
-  public class Rotate extends android.view.transition.Transition {
-    ctor public Rotate();
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-  }
-
-  public final class Scene {
-    ctor public Scene(android.view.ViewGroup);
-    ctor public Scene(android.view.ViewGroup, int, android.content.Context);
-    ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
-    method public void enter();
-    method public void exit();
-    method public android.view.ViewGroup getSceneRoot();
-    method public void setEnterAction(java.lang.Runnable);
-    method public void setExitAction(java.lang.Runnable);
-  }
-
-  public class Slide extends android.view.transition.Visibility {
-    ctor public Slide();
-  }
-
-  public class TextChange extends android.view.transition.Transition {
-    ctor public TextChange();
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-    method public void setChangeBehavior(int);
-    field public static final int CHANGE_BEHAVIOR_IN = 2; // 0x2
-    field public static final int CHANGE_BEHAVIOR_KEEP = 0; // 0x0
-    field public static final int CHANGE_BEHAVIOR_OUT = 1; // 0x1
-    field public static final int CHANGE_BEHAVIOR_OUT_IN = 3; // 0x3
-  }
-
-  public abstract class Transition implements java.lang.Cloneable {
-    ctor public Transition();
-    method public void addListener(android.view.transition.Transition.TransitionListener);
-    method protected void cancel();
-    method protected abstract void captureValues(android.view.transition.TransitionValues, boolean);
-    method public android.view.transition.Transition clone();
-    method public long getDuration();
-    method public android.animation.TimeInterpolator getInterpolator();
-    method public java.util.ArrayList<android.view.transition.Transition.TransitionListener> getListeners();
-    method public java.lang.String getName();
-    method public long getStartDelay();
-    method public int[] getTargetIds();
-    method public android.view.View[] getTargets();
-    method public java.lang.String[] getTransitionProperties();
-    method protected android.view.transition.TransitionValues getTransitionValues(android.view.View, boolean);
-    method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
-    method public void removeListener(android.view.transition.Transition.TransitionListener);
-    method public android.view.transition.Transition setDuration(long);
-    method public void setInterpolator(android.animation.TimeInterpolator);
-    method public void setStartDelay(long);
-    method public android.view.transition.Transition setTargetIds(int...);
-    method public android.view.transition.Transition setTargets(android.view.View...);
-  }
-
-  public static abstract interface Transition.TransitionListener {
-    method public abstract void onTransitionCancel(android.view.transition.Transition);
-    method public abstract void onTransitionEnd(android.view.transition.Transition);
-    method public abstract void onTransitionPause(android.view.transition.Transition);
-    method public abstract void onTransitionResume(android.view.transition.Transition);
-    method public abstract void onTransitionStart(android.view.transition.Transition);
-  }
-
-  public class TransitionGroup extends android.view.transition.Transition {
-    ctor public TransitionGroup();
-    ctor public TransitionGroup(int);
-    method public void addTransitions(android.view.transition.Transition...);
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-    method public void removeTransition(android.view.transition.Transition);
-    method public void setOrdering(int);
-    field public static final int SEQUENTIALLY = 1; // 0x1
-    field public static final int TOGETHER = 0; // 0x0
-  }
-
-  public class TransitionInflater {
-    method public static android.view.transition.TransitionInflater from(android.content.Context);
-    method public android.view.transition.Scene inflateScene(int, android.view.ViewGroup);
-    method public android.view.transition.Transition inflateTransition(int);
-    method public android.view.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
-  }
-
-  public class TransitionManager {
-    ctor public TransitionManager();
-    method public static void beginDelayedTransition(android.view.ViewGroup, android.view.transition.Transition);
-    method public android.view.transition.Transition getDefaultTransition();
-    method public static void go(android.view.transition.Scene);
-    method public static void go(android.view.transition.Scene, android.view.transition.Transition);
-    method public static void go(android.view.ViewGroup, java.lang.Runnable);
-    method public static void go(android.view.ViewGroup, java.lang.Runnable, android.view.transition.Transition);
-    method public void setDefaultTransition(android.view.transition.Transition);
-    method public void setTransition(android.view.transition.Scene, android.view.transition.Transition);
-    method public void setTransition(android.view.transition.Scene, android.view.transition.Scene, android.view.transition.Transition);
-    method public void transitionTo(android.view.transition.Scene);
-  }
-
-  public class TransitionValues {
-    ctor public TransitionValues();
-    field public final java.util.Map values;
-    field public android.view.View view;
-  }
-
-  public abstract class Visibility extends android.view.transition.Transition {
-    ctor public Visibility();
-    method protected android.animation.Animator appear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
-    method protected void captureValues(android.view.transition.TransitionValues, boolean);
-    method protected android.animation.Animator disappear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
-    method public boolean isVisible(android.view.transition.TransitionValues);
-  }
-
-}
-
 package android.webkit {
 
   public class ConsoleMessage {
@@ -30353,6 +30276,7 @@
     ctor public AbsListView(android.content.Context, android.util.AttributeSet, int);
     method public void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
+    method public boolean canScrollList(int);
     method public void clearChoices();
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
@@ -30394,7 +30318,7 @@
     method public int pointToPosition(int, int);
     method public long pointToRowId(int, int);
     method public void reclaimViews(java.util.List<android.view.View>);
-    method public boolean scrollListBy(int);
+    method public void scrollListBy(int);
     method public void setAdapter(android.widget.ListAdapter);
     method public void setCacheColorHint(int);
     method public void setChoiceMode(int);
@@ -32436,7 +32360,6 @@
     method public int getTotalPaddingTop();
     method public final android.text.method.TransformationMethod getTransformationMethod();
     method public android.graphics.Typeface getTypeface();
-    method public final android.content.UndoManager getUndoManager();
     method public android.text.style.URLSpan[] getUrls();
     method public boolean hasSelection();
     method public boolean isCursorVisible();
@@ -32535,7 +32458,6 @@
     method public final void setTransformationMethod(android.text.method.TransformationMethod);
     method public void setTypeface(android.graphics.Typeface, int);
     method public void setTypeface(android.graphics.Typeface);
-    method public final void setUndoManager(android.content.UndoManager, java.lang.String);
     method public void setWidth(int);
   }
 
@@ -32617,6 +32539,7 @@
     ctor public VideoView(android.content.Context);
     ctor public VideoView(android.content.Context, android.util.AttributeSet);
     ctor public VideoView(android.content.Context, android.util.AttributeSet, int);
+    method public void addSubtitleSource(java.io.InputStream, android.media.MediaFormat);
     method public boolean canPause();
     method public boolean canSeekBackward();
     method public boolean canSeekForward();
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 89accbb..129e52c 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -280,19 +280,9 @@
     }
 
     /**
-     * Gets the set of {@link AnimatorPauseListener} objects that are currently
-     * listening for pause/resume events on this animator.
-     *
-     * @return ArrayList<AnimatorListener> The set of pause listeners.
-     */
-    public ArrayList<AnimatorPauseListener> getPauseListeners() {
-        return mPauseListeners;
-    }
-
-    /**
-     * Removes all listeners from this object. This is equivalent to calling
-     * {@link #getListeners()} and {@link #getPauseListeners()} followed by calling
-     * {@link ArrayList#clear()} on the returned lists of listeners.
+     * Removes all {@link #addListener(android.animation.Animator.AnimatorListener) listeners}
+     * and {@link #addPauseListener(android.animation.Animator.AnimatorPauseListener)
+     * pauseListeners} from this object.
      */
     public void removeAllListeners() {
         if (mListeners != null) {
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 5b1a7cf..43014ad 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -636,7 +636,7 @@
     }
 
     /**
-     * The TypeEvaluator will the automatically determined based on the type of values
+     * The TypeEvaluator will be automatically determined based on the type of values
      * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so
      * desired. This may be important in cases where either the type of the values supplied
      * do not match the way that they should be interpolated between, or if the values
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index b390aa1..a2bb78c 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -702,6 +702,10 @@
      * @param start Start or stop advertising
      */
     /*package*/ void listen(boolean start) {
+        if (mContext == null || !mContext.getResources().
+            getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
+            throw new UnsupportedOperationException("BluetoothGatt#listen is blocked");
+        }
         if (DBG) Log.d(TAG, "listen() - start: " + start);
         if (mService == null || mClientIf == 0) return;
 
@@ -728,6 +732,10 @@
     /*package*/ void setAdvData(boolean advData, boolean includeName, boolean includeTxPower,
                            Integer minInterval, Integer maxInterval,
                            Integer appearance, Byte[] manufacturerData) {
+        if (mContext == null || !mContext.getResources().
+            getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
+            throw new UnsupportedOperationException("BluetoothGatt#setAdvData is blocked");
+        }
         if (DBG) Log.d(TAG, "setAdvData()");
         if (mService == null || mClientIf == 0) return;
 
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d7ca9153..dfc0412 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3300,8 +3300,10 @@
     /**
      * Optional extra for {@link #ACTION_SHUTDOWN} that allows the sender to qualify that
      * this shutdown is only for the user space of the system, not a complete shutdown.
-     * Hardware should not be shut down when this is true.  The default if not supplied
-     * is false.
+     * When this is true, hardware devices can use this information to determine that
+     * they shouldn't do a complete shutdown of their device since this is not a
+     * complete shutdown down to the kernel, but only user space restarting.
+     * The default if not supplied is false.
      */
     public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
             = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java
index 1c2db47..e9ec5a4 100644
--- a/core/java/android/content/UndoManager.java
+++ b/core/java/android/content/UndoManager.java
@@ -50,6 +50,8 @@
  * undo/redo them without needing to impact edits in other objects; while
  * within the larger document, all edits can be seen and the user must
  * undo/redo them as a single stream.</p>
+ *
+ * @hide
  */
 public class UndoManager {
     private final HashMap<String, UndoOwner> mOwners = new HashMap<String, UndoOwner>();
diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java
index 8084b1f..1ff32d4 100644
--- a/core/java/android/content/UndoOperation.java
+++ b/core/java/android/content/UndoOperation.java
@@ -23,6 +23,8 @@
  * A single undoable operation.  You must subclass this to implement the state
  * and behavior for your operation.  Instances of this class are placed and
  * managed in an {@link UndoManager}.
+ *
+ * @hide
  */
 public abstract class UndoOperation<DATA> implements Parcelable {
     UndoOwner mOwner;
diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java
index a279de6..d0cdc95 100644
--- a/core/java/android/content/UndoOwner.java
+++ b/core/java/android/content/UndoOwner.java
@@ -18,6 +18,8 @@
 
 /**
  * Representation of an owner of {@link UndoOperation} objects in an {@link UndoManager}.
+ *
+ * @hide
  */
 public class UndoOwner {
     final String mTag;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 3f17dc4..3dc8717 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -52,7 +52,7 @@
      * Bit in {@link #flags}: If set,
      * {@link android.app.Service#onProvideAssistData(android.os.Bundle)} will
      * be called on the service when it is running in the foreground. Set from
-     * the android.R.attr#provideAssistData attribute.
+     * the {@link android.R.attr#provideAssistData} attribute.
      */
     public static final int FLAG_PROVIDE_ASSIST_DATA = 0x0004;
 
diff --git a/core/java/android/hardware/FlushCompleteListener.java b/core/java/android/hardware/FlushCompleteListener.java
new file mode 100644
index 0000000..cb5b9e3
--- /dev/null
+++ b/core/java/android/hardware/FlushCompleteListener.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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.hardware;
+
+/**
+ * Used for receiving a notification when a flush() has been successfully completed.
+ * @hide
+ */
+public interface FlushCompleteListener {
+    /**
+     * Called after flush() is completed. This flush() could have been initiated by this application
+     * or some other application. All the events in the batch at the point when the flush was called
+     * have been delivered to the applications registered for those sensor events.
+     * <p>
+     *
+     * @param sensor The {@link android.hardware.Sensor Sensor} on which flush was called.
+     *
+     * @see android.hardware.SensorManager#flush(Sensor)
+     */
+    public void onFlushCompleted(Sensor sensor);
+}
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 9bffdbe..bbede57 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -319,6 +319,8 @@
     private float   mResolution;
     private float   mPower;
     private int     mMinDelay;
+    private int     mFifoReservedEventCount;
+    private int     mFifoMaxEventCount;
 
     Sensor() {
     }
@@ -381,6 +383,26 @@
         return mMinDelay;
     }
 
+    /**
+     * @return Number of events reserved for this sensor in the batch mode FIFO. This gives a
+     * guarantee on the minimum number of events that can be batched
+     * @hide
+     */
+    public int getFifoReservedEventCount() {
+        return mFifoReservedEventCount;
+    }
+
+    /**
+     * @return Maximum number of events of this sensor that could be batched. If this value is zero
+     * it indicates that batch mode is not supported for this sensor. If other applications
+     * registered to batched sensors, the actual number of events that can be batched might be
+     * smaller because the hardware FiFo will be partially used to batch the other sensors.
+     * @hide
+     */
+    public int getFifoMaxEventCount() {
+        return mFifoMaxEventCount;
+    }
+
     /** @hide */
     public int getHandle() {
         return mHandle;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 30118f9..b6ca62a 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -608,8 +608,72 @@
     }
 
     /**
-     * Registers a {@link android.hardware.SensorEventListener
-     * SensorEventListener} for the given sensor.
+     * Enables batch mode for a sensor with the given rate and maxBatchReportLatency. If the
+     * underlying hardware does not support batch mode, this defaults to
+     * {@link #registerListener(SensorEventListener, Sensor, int)} and other parameters are are
+     * ignored. In non-batch mode, all sensor events must be reported as soon as they are detected.
+     * While in batch mode, sensor events do not need to be reported as soon as they are detected.
+     * They can be temporarily stored in batches and reported in batches, as long as no event is
+     * delayed by more than "maxBatchReportLatency" microseconds. That is, all events since the
+     * previous batch are recorded and returned all at once. This allows to reduce the amount of
+     * interrupts sent to the SoC, and allows the SoC to switch to a lower power state (Idle) while
+     * the sensor is capturing and batching data.
+     * <p>
+     * Registering to a sensor in batch mode will not prevent the SoC from going to suspend mode. In
+     * this case, the sensor will continue to gather events and store it in a hardware FIFO. If the
+     * FIFO gets full before the AP wakes up again, some events will be lost, as the older events
+     * get overwritten by new events in the hardware FIFO. This can be avoided by holding a wake
+     * lock. If the application holds a wake lock, the SoC will not go to suspend mode, so no events
+     * will be lost, as the events will be reported before the FIFO gets full.
+     * </p>
+     * <p>
+     * Batching is always best effort. If a different application requests updates in continuous
+     * mode, this application will also get events in continuous mode. Batch mode updates can be
+     * unregistered by calling {@link #unregisterListener(SensorEventListener)}.
+     * </p>
+     * <p class="note">
+     * </p>
+     * Note: Don't use this method with a one shot trigger sensor such as
+     * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
+     * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
+     *
+     * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
+     *            that will receive the sensor events.
+     * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
+     * @param rate The desired delay between two consecutive events in microseconds. This is only a
+     *            hint to the system. Events may be received faster or slower than the specified
+     *            rate. Usually events are received faster. Can be one of
+     *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
+     *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
+     *            microseconds.
+     * @param maxBatchReportLatency An event in the batch can be delayed by at most
+     *            maxBatchReportLatency microseconds. More events can be batched if this value is
+     *            large. If this is set to zero, batch mode is disabled and events are delivered in
+     *            continuous mode as soon as they are available which is equivalent to calling
+     *            {@link #registerListener(SensorEventListener, Sensor, int)}.
+     * @param reservedFlags Always set to Zero.
+     * @param flushCompleteListener A {@link android.hardware.FlushCompleteListener
+     *            FlushCompleteListener} object which is called when any application calls flush()
+     *            on this sensor and all the events in the batch at the time of calling flush() are
+     *            successfully delivered to the listeners.
+     * @return true if batch mode is successfully enabled for this sensor, false otherwise.
+     * @see #registerListener(SensorEventListener, Sensor, int)
+     * @see #unregisterListener(SensorEventListener)
+     * @see #flush(Sensor)
+     * @throws IllegalArgumentException when sensor or listener is null or a trigger sensor.
+     * @hide
+     */
+    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
+            int maxBatchReportLatencyUs, int reservedFlags,
+            FlushCompleteListener flushCompleteListener) {
+        int delay = getDelay(rateUs);
+        return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs,
+                                        reservedFlags, flushCompleteListener);
+    }
+
+    /**
+     * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
+     * sensor. Events are delivered in continuous mode as soon as they are available.
      *
      * <p class="note"></p>
      * Note: Don't use this method with a one shot trigger sensor such as
@@ -655,31 +719,55 @@
             return false;
         }
 
-        int delay = -1;
-        switch (rate) {
-            case SENSOR_DELAY_FASTEST:
-                delay = 0;
-                break;
-            case SENSOR_DELAY_GAME:
-                delay = 20000;
-                break;
-            case SENSOR_DELAY_UI:
-                delay = 66667;
-                break;
-            case SENSOR_DELAY_NORMAL:
-                delay = 200000;
-                break;
-            default:
-                delay = rate;
-                break;
-        }
+        int delay = getDelay(rate);
+        return registerListenerImpl(listener, sensor, delay, handler, 0, 0, null);
+    }
 
-        return registerListenerImpl(listener, sensor, delay, handler);
+    /**
+     * Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
+     * @param handler
+     *        The {@link android.os.Handler Handler} the
+     *        {@link android.hardware.SensorEvent sensor events} will be
+     *        delivered to.
+     *
+     * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+     * @hide
+     */
+    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
+            int maxBatchReportLatencyUs, int reservedFlags, Handler handler,
+            FlushCompleteListener flushCompleteListener) {
+        int delayUs = getDelay(rateUs);
+        return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs,
+                                        reservedFlags, flushCompleteListener);
     }
 
     /** @hide */
     protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
-            int delay, Handler handler);
+            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
+            FlushCompleteListener flushCompleteListener);
+
+
+    /**
+     * Flushes the batch FIFO of the given sensor. If there are events in the FIFO of this sensor,
+     * they are returned as if the batch timeout has expired. Events are returned in the
+     * usual way through the SensorEventListener. This call doesn't effect the batch timeout for
+     * this sensor. This call is asynchronous and returns immediately. FlushCompleteListener is
+     * called after all the events in the batch at the time of calling this method have been
+     * delivered successfully.
+     * @param sensor
+     *        The {@link android.hardware.Sensor Sensor} to flush.
+     * @return true if the flush is initiated successfully. false if the sensor isn't active
+     *         i.e no application is registered for updates from this sensor.
+     * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+     * @throws IllegalArgumentException when sensor is null or a trigger sensor.
+     * @hide
+     */
+    public boolean flush(Sensor sensor) {
+        return flushImpl(sensor);
+    }
+
+    /** @hide */
+    protected abstract boolean flushImpl(Sensor sensor);
 
     /**
      * <p>
@@ -1079,15 +1167,15 @@
      * <p>
      * All three angles above are in <b>radians</b> and <b>positive</b> in the
      * <b>counter-clockwise</b> direction.
-     * 
+     *
      * @param R
      *        rotation matrix see {@link #getRotationMatrix}.
-     * 
+     *
      * @param values
      *        an array of 3 floats to hold the result.
-     * 
+     *
      * @return The array values passed as argument.
-     * 
+     *
      * @see #getRotationMatrix(float[], float[], float[], float[])
      * @see GeomagneticField
      */
@@ -1407,4 +1495,26 @@
             return mLegacySensorManager;
         }
     }
+
+    private static int getDelay(int rate) {
+        int delay = -1;
+        switch (rate) {
+            case SENSOR_DELAY_FASTEST:
+                delay = 0;
+                break;
+            case SENSOR_DELAY_GAME:
+                delay = 20000;
+                break;
+            case SENSOR_DELAY_UI:
+                delay = 66667;
+                break;
+            case SENSOR_DELAY_NORMAL:
+                delay = 200000;
+                break;
+            default:
+                delay = rate;
+                break;
+        }
+        return delay;
+    }
 }
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 852cf4a..9747f0d 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -93,30 +93,35 @@
     /** @hide */
     @Override
     protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
-            int delay, Handler handler)
-    {
+            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
+            FlushCompleteListener flushCompleteListener) {
+        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+        if (reservedFlags != 0) throw new IllegalArgumentException("reservedFlags should be zero");
+        if (delayUs < 0) throw new IllegalArgumentException("rateUs should be positive");
+        if (maxBatchReportLatencyUs < 0)
+            throw new IllegalArgumentException("maxBatchReportLatencyUs should be positive");
+        // Trigger Sensors should use the requestTriggerSensor call.
+        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
+            throw new IllegalArgumentException("Trigger Sensors cannot use registerListener");
+
         // Invariants to preserve:
         // - one Looper per SensorEventListener
         // - one Looper per SensorEventQueue
         // We map SensorEventListener to a SensorEventQueue, which holds the looper
-        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
-
-        // Trigger Sensors should use the requestTriggerSensor call.
-        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false;
-
         synchronized (mSensorListeners) {
             SensorEventQueue queue = mSensorListeners.get(listener);
             if (queue == null) {
                 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
-                queue = new SensorEventQueue(listener, looper, this);
-                if (!queue.addSensor(sensor, delay)) {
+                queue = new SensorEventQueue(listener, looper, this, flushCompleteListener);
+                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
                     queue.dispose();
                     return false;
                 }
                 mSensorListeners.put(listener, queue);
                 return true;
             } else {
-                return queue.addSensor(sensor, delay);
+                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);
             }
         }
     }
@@ -157,14 +162,14 @@
             TriggerEventQueue queue = mTriggerListeners.get(listener);
             if (queue == null) {
                 queue = new TriggerEventQueue(listener, mMainLooper, this);
-                if (!queue.addSensor(sensor, 0)) {
+                if (!queue.addSensor(sensor, 0, 0, 0)) {
                     queue.dispose();
                     return false;
                 }
                 mTriggerListeners.put(listener, queue);
                 return true;
             } else {
-                return queue.addSensor(sensor, 0);
+                return queue.addSensor(sensor, 0, 0, 0);
             }
         }
     }
@@ -195,6 +200,18 @@
         }
     }
 
+    protected boolean flushImpl(Sensor sensor) {
+        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+        if(Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
+            throw new IllegalArgumentException("Trigger Sensors cannot call flush");
+
+        FlushEventQueue queue = new FlushEventQueue(mMainLooper, this);
+        if (queue.flushSensor(sensor) != 0) {
+            return false;
+        }
+        return true;
+    }
+
     /*
      * BaseEventQueue is the communication channel with the sensor service,
      * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
@@ -202,11 +219,12 @@
      */
     private static abstract class BaseEventQueue {
         private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
-
                 float[] scratch);
-        private static native int nativeEnableSensor(int eventQ, int handle, int us);
+        private static native int nativeEnableSensor(int eventQ, int handle, int rateUs,
+                int maxBatchReportLatencyUs, int reservedFlags);
         private static native int nativeDisableSensor(int eventQ, int handle);
         private static native void nativeDestroySensorEventQueue(int eventQ);
+        private static native int nativeFlushSensor(int eventQ, int handle);
         private int nSensorEventQueue;
         private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
         protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
@@ -225,7 +243,8 @@
             dispose(false);
         }
 
-        public boolean addSensor(Sensor sensor, int delay) {
+        public boolean addSensor(
+                Sensor sensor, int delayUs, int maxBatchReportLatencyUs, int reservedFlags) {
             // Check if already present.
             int handle = sensor.getHandle();
             if (mActiveSensors.get(handle)) return false;
@@ -233,9 +252,13 @@
             // Get ready to receive events before calling enable.
             mActiveSensors.put(handle, true);
             addSensorEvent(sensor);
-            if (enableSensor(sensor, delay) != 0) {
-                removeSensor(sensor, false);
-                return false;
+            if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) {
+                // Try continuous mode if batching fails.
+                if (maxBatchReportLatencyUs == 0 ||
+                    maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) {
+                  removeSensor(sensor, false);
+                  return false;
+                }
             }
             return true;
         }
@@ -268,6 +291,12 @@
             return false;
         }
 
+        public int flushSensor(Sensor sensor) {
+            if (nSensorEventQueue == 0) throw new NullPointerException();
+            if (sensor == null) throw new NullPointerException();
+            return nativeFlushSensor(nSensorEventQueue, sensor.getHandle());
+        }
+
         public boolean hasSensors() {
             // no more sensors are set
             return mActiveSensors.indexOfValue(true) >= 0;
@@ -295,11 +324,14 @@
             }
         }
 
-        private int enableSensor(Sensor sensor, int us) {
+        private int enableSensor(
+                Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) {
             if (nSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
-            return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), us);
+            return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
+                    maxBatchReportLatencyUs, reservedFlags);
         }
+
         private int disableSensor(Sensor sensor) {
             if (nSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
@@ -307,6 +339,7 @@
         }
         protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
                 long timestamp);
+        protected abstract void dispatchFlushCompleteEvent(int handle);
 
         protected abstract void addSensorEvent(Sensor sensor);
         protected abstract void removeSensorEvent(Sensor sensor);
@@ -314,12 +347,14 @@
 
     static final class SensorEventQueue extends BaseEventQueue {
         private final SensorEventListener mListener;
+        private final FlushCompleteListener mFlushCompleteListener;
         private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
 
         public SensorEventQueue(SensorEventListener listener, Looper looper,
-                SystemSensorManager manager) {
+                SystemSensorManager manager, FlushCompleteListener flushCompleteListener) {
             super(looper, manager);
             mListener = listener;
+            mFlushCompleteListener = flushCompleteListener;
         }
 
         public void addSensorEvent(Sensor sensor) {
@@ -370,6 +405,15 @@
             }
             mListener.onSensorChanged(t);
         }
+
+        @SuppressWarnings("unused")
+        protected void dispatchFlushCompleteEvent(int handle) {
+            final Sensor sensor = sHandleToSensor.get(handle);
+            if (mFlushCompleteListener != null) {
+                mFlushCompleteListener.onFlushCompleted(sensor);
+            }
+            return;
+        }
     }
 
     static final class TriggerEventQueue extends BaseEventQueue {
@@ -415,5 +459,35 @@
 
             mListener.onTrigger(t);
         }
+
+        @SuppressWarnings("unused")
+        protected void dispatchFlushCompleteEvent(int handle) {
+        }
+    }
+
+    static final class FlushEventQueue extends BaseEventQueue {
+        public FlushEventQueue(Looper looper, SystemSensorManager manager) {
+            super(looper, manager);
+        }
+
+        @SuppressWarnings("unused")
+        @Override
+        protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
+                long timestamp) {
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        protected void addSensorEvent(Sensor sensor) {
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        protected void removeSensorEvent(Sensor sensor) {
+        }
+
+        @SuppressWarnings("unused")
+        protected void dispatchFlushCompleteEvent(int handle) {
+        }
     }
 }
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 8b5bf4a..3f9b9e9 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -303,13 +303,14 @@
      * </p>
      * <p>
      * Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight.
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
      * </p><p>
      * The coordinate system is based on the active pixel array,
-     * with (0,0) being the top-left of the active pixel array, and
-     * (android.sensor.info.activeArraySize.width,
-     * android.sensor.info.activeArraySize.height) being the
-     * bottom-right point of the active pixel array. The weight
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.
      * </p><p>
      * If all regions have 0 weight, then no specific metering area
@@ -378,13 +379,14 @@
      * </p>
      * <p>
      * Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight.
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
      * </p><p>
      * The coordinate system is based on the active pixel array,
-     * with (0,0) being the top-left of the active pixel array, and
-     * (android.sensor.info.activeArraySize.width,
-     * android.sensor.info.activeArraySize.height) being the
-     * bottom-right point of the active pixel array. The weight
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.
      * </p><p>
      * If all regions have 0 weight, then no specific focus area
@@ -462,12 +464,15 @@
      * <p>
      * Only used in AUTO mode.
      * </p><p>
-     * Each area is a rectangle plus weight: xmin, ymin, xmax,
-     * ymax, weight. The coordinate system is based on the active
-     * pixel array, with (0,0) being the top-left of the active
-     * pixel array, and (android.sensor.info.activeArraySize.width,
-     * android.sensor.info.activeArraySize.height) being the
-     * bottom-right point of the active pixel array. The weight
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.
      * </p><p>
      * If all regions have 0 weight, then no specific metering area
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ef6aaa0..bd151a2 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -198,13 +198,14 @@
      * </p>
      * <p>
      * Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight.
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
      * </p><p>
      * The coordinate system is based on the active pixel array,
-     * with (0,0) being the top-left of the active pixel array, and
-     * (android.sensor.info.activeArraySize.width,
-     * android.sensor.info.activeArraySize.height) being the
-     * bottom-right point of the active pixel array. The weight
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.
      * </p><p>
      * If all regions have 0 weight, then no specific metering area
@@ -258,13 +259,14 @@
      * </p>
      * <p>
      * Each area is a rectangle plus weight: xmin, ymin,
-     * xmax, ymax, weight.
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
      * </p><p>
      * The coordinate system is based on the active pixel array,
-     * with (0,0) being the top-left of the active pixel array, and
-     * (android.sensor.info.activeArraySize.width,
-     * android.sensor.info.activeArraySize.height) being the
-     * bottom-right point of the active pixel array. The weight
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.
      * </p><p>
      * If all regions have 0 weight, then no specific focus area
@@ -342,12 +344,15 @@
      * <p>
      * Only used in AUTO mode.
      * </p><p>
-     * Each area is a rectangle plus weight: xmin, ymin, xmax,
-     * ymax, weight. The coordinate system is based on the active
-     * pixel array, with (0,0) being the top-left of the active
-     * pixel array, and (android.sensor.info.activeArraySize.width,
-     * android.sensor.info.activeArraySize.height) being the
-     * bottom-right point of the active pixel array. The weight
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
      * should be nonnegative.
      * </p><p>
      * If all regions have 0 weight, then no specific metering area
diff --git a/core/java/android/hardware/camera2/Rational.java b/core/java/android/hardware/camera2/Rational.java
index 0260e02..77b8c26 100644
--- a/core/java/android/hardware/camera2/Rational.java
+++ b/core/java/android/hardware/camera2/Rational.java
@@ -26,22 +26,17 @@
     /**
      * <p>Create a Rational with a given numerator and denominator.</p>
      *
-     * <p>
-     * The signs of the numerator and the denominator may be flipped such that the denominator
-     * is always 0.
-     * </p>
+     * <p>The signs of the numerator and the denominator may be flipped such that the denominator
+     * is always positive.</p>
+     *
+     * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
+     * as float NaN and INF values. The int getter functions return 0 in this case.</p>
      *
      * @param numerator the numerator of the rational
      * @param denominator the denominator of the rational
-     *
-     * @throws IllegalArgumentException if the denominator is 0
      */
     public Rational(int numerator, int denominator) {
 
-        if (denominator == 0) {
-            throw new IllegalArgumentException("Argument 'denominator' is 0");
-        }
-
         if (denominator < 0) {
             numerator = -numerator;
             denominator = -denominator;
@@ -55,6 +50,9 @@
      * Gets the numerator of the rational.
      */
     public int getNumerator() {
+        if (mDenominator == 0) {
+            return 0;
+        }
         return mNumerator;
     }
 
@@ -65,22 +63,41 @@
         return mDenominator;
     }
 
+    private boolean isNaN() {
+        return mDenominator == 0 && mNumerator == 0;
+    }
+
+    private boolean isInf() {
+        return mDenominator == 0 && mNumerator > 0;
+    }
+
+    private boolean isNegInf() {
+        return mDenominator == 0 && mNumerator < 0;
+    }
+
     /**
      * <p>Compare this Rational to another object and see if they are equal.</p>
      *
      * <p>A Rational object can only be equal to another Rational object (comparing against any other
      * type will return false).</p>
      *
-     * <p>A Rational object is considered equal to another Rational object if and only if their
-     * reduced forms have the same numerator and denominator.</p>
+     * <p>A Rational object is considered equal to another Rational object if and only if one of
+     * the following holds</p>:
+     * <ul><li>Both are NaN</li>
+     *     <li>Both are infinities of the same sign</li>
+     *     <li>Both have the same numerator and denominator in their reduced form</li>
+     * </ul>
      *
      * <p>A reduced form of a Rational is calculated by dividing both the numerator and the
      * denominator by their greatest common divisor.</p>
      *
      * <pre>
-     *      (new Rational(1, 2)).equals(new Rational(1, 2)) == true  // trivially true
-     *      (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
-     *      (new Rational(1, 2)).equals(new Rational(2, 4)) == true  // true after reduction
+     *      (new Rational(1, 2)).equals(new Rational(1, 2)) == true   // trivially true
+     *      (new Rational(2, 3)).equals(new Rational(1, 2)) == false  // trivially false
+     *      (new Rational(1, 2)).equals(new Rational(2, 4)) == true   // true after reduction
+     *      (new Rational(0, 0)).equals(new Rational(0, 0)) == true   // NaN.equals(NaN)
+     *      (new Rational(1, 0)).equals(new Rational(5, 0)) == true   // both are +infinity
+     *      (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
      * </pre>
      *
      * @param obj a reference to another object
@@ -91,13 +108,17 @@
     public boolean equals(Object obj) {
         if (obj == null) {
             return false;
-        }
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof Rational) {
+        } else if (obj instanceof Rational) {
             Rational other = (Rational) obj;
-            if(mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
+            if (mDenominator == 0 || other.mDenominator == 0) {
+                if (isNaN() && other.isNaN()) {
+                    return true;
+                } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
+                    return true;
+                } else {
+                    return false;
+                }
+            } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
                 return true;
             } else {
                 int thisGcd = gcd();
@@ -117,7 +138,25 @@
 
     @Override
     public String toString() {
-        return mNumerator + "/" + mDenominator;
+        if (isNaN()) {
+            return "NaN";
+        } else if (isInf()) {
+            return "Infinity";
+        } else if (isNegInf()) {
+            return "-Infinity";
+        } else {
+            return mNumerator + "/" + mDenominator;
+        }
+    }
+
+    /**
+     * <p>Convert to a floating point representation.</p>
+     *
+     * @return The floating point representation of this rational number.
+     * @hide
+     */
+    public float toFloat() {
+        return (float) mNumerator / (float) mDenominator;
     }
 
     @Override
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 64e4dc9..86a073f 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -301,7 +301,9 @@
         synchronized (mLock) {
 
             try {
-                mRemoteDevice.disconnect();
+                if (mRemoteDevice != null) {
+                    mRemoteDevice.disconnect();
+                }
             } catch (CameraRuntimeException e) {
                 throw e.asChecked();
             } catch (RemoteException e) {
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index fbe7ff4..2c05c58 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -49,7 +49,7 @@
     public static final int EACCES = -13;
     public static final int EBUSY = -16;
     public static final int ENODEV = -19;
-    public static final int ENOTSUP = -129;
+    public static final int EOPNOTSUPP = -95;
 
     private static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
 
@@ -86,7 +86,7 @@
                     case ENODEV:
                         UncheckedThrow.throwAnyException(new CameraRuntimeException(
                                 CAMERA_DISCONNECTED));
-                    case ENOTSUP:
+                    case EOPNOTSUPP:
                         UncheckedThrow.throwAnyException(new CameraRuntimeException(
                                 CAMERA_DEPRECATED_HAL));
                 }
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
similarity index 89%
rename from core/java/android/nfc/INdefPushCallback.aidl
rename to core/java/android/nfc/IAppCallback.aidl
index 16771dc..9599308 100644
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -17,12 +17,14 @@
 package android.nfc;
 
 import android.nfc.BeamShareData;
+import android.nfc.Tag;
 
 /**
  * @hide
  */
-interface INdefPushCallback
+interface IAppCallback
 {
     BeamShareData createBeamShareData();
     void onNdefPushComplete();
+    void onTagDiscovered(in Tag tag);
 }
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 15d0475..8414738 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -21,10 +21,11 @@
 import android.nfc.NdefMessage;
 import android.nfc.Tag;
 import android.nfc.TechListParcel;
-import android.nfc.INdefPushCallback;
+import android.nfc.IAppCallback;
 import android.nfc.INfcAdapterExtras;
 import android.nfc.INfcTag;
 import android.nfc.INfcCardEmulation;
+import android.os.Bundle;
 
 /**
  * @hide
@@ -44,10 +45,10 @@
 
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
-    void setNdefPushCallback(in INdefPushCallback callback);
+    void setAppCallback(in IAppCallback callback);
 
     void dispatch(in Tag tag);
 
-    void setReaderMode (IBinder b, int flags);
+    void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras);
     void setP2pModes(int initatorModes, int targetModes);
 }
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index d0d943c..77c0234 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.app.Application;
 import android.net.Uri;
+import android.nfc.NfcAdapter.ReaderCallback;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -36,7 +37,7 @@
  *
  * @hide
  */
-public final class NfcActivityManager extends INdefPushCallback.Stub
+public final class NfcActivityManager extends IAppCallback.Stub
         implements Application.ActivityLifecycleCallbacks {
     static final String TAG = NfcAdapter.TAG;
     static final Boolean DBG = false;
@@ -113,6 +114,8 @@
         Uri[] uris = null;
         int flags = 0;
         int readerModeFlags = 0;
+        NfcAdapter.ReaderCallback readerCallback = null;
+        Bundle readerModeExtras = null;
         Binder token;
 
         public NfcActivityState(Activity activity) {
@@ -197,17 +200,20 @@
         mDefaultEvent = new NfcEvent(mAdapter);
     }
 
-    public void enableReaderMode(Activity activity, int flags) {
+    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
+            Bundle extras) {
         boolean isResumed;
         Binder token;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = getActivityState(activity);
+            state.readerCallback = callback;
             state.readerModeFlags = flags;
+            state.readerModeExtras = extras;
             token = state.token;
             isResumed = state.resumed;
         }
         if (isResumed) {
-            setReaderMode(token, flags);
+            setReaderMode(token, flags, extras);
         }
     }
 
@@ -216,20 +222,22 @@
         Binder token;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = getActivityState(activity);
+            state.readerCallback = null;
             state.readerModeFlags = 0;
+            state.readerModeExtras = null;
             token = state.token;
             isResumed = state.resumed;
         }
         if (isResumed) {
-            setReaderMode(token, 0);
+            setReaderMode(token, 0, null);
         }
 
     }
 
-    public void setReaderMode(Binder token, int flags) {
+    public void setReaderMode(Binder token, int flags, Bundle extras) {
         if (DBG) Log.d(TAG, "Setting reader mode");
         try {
-            NfcAdapter.sService.setReaderMode(token, flags);
+            NfcAdapter.sService.setReaderMode(token, this, flags, extras);
         } catch (RemoteException e) {
             mAdapter.attemptDeadServiceRecovery(e);
         }
@@ -302,12 +310,12 @@
     }
 
     /**
-     * Request or unrequest NFC service callbacks for NDEF push.
+     * Request or unrequest NFC service callbacks.
      * Makes IPC call - do not hold lock.
      */
     void requestNfcServiceCallback() {
         try {
-            NfcAdapter.sService.setNdefPushCallback(this);
+            NfcAdapter.sService.setAppCallback(this);
         } catch (RemoteException e) {
             mAdapter.attemptDeadServiceRecovery(e);
         }
@@ -375,6 +383,22 @@
         }
     }
 
+    @Override
+    public void onTagDiscovered(Tag tag) throws RemoteException {
+        NfcAdapter.ReaderCallback callback;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = findResumedActivityState();
+            if (state == null) return;
+
+            callback = state.readerCallback;
+        }
+
+        // Make callback without lock
+        if (callback != null) {
+            callback.onTagDiscovered(tag);
+        }
+
+    }
     /** Callback from Activity life-cycle, on main thread */
     @Override
     public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
@@ -387,6 +411,7 @@
     @Override
     public void onActivityResumed(Activity activity) {
         int readerModeFlags = 0;
+        Bundle readerModeExtras = null;
         Binder token;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = findActivityState(activity);
@@ -395,9 +420,10 @@
             state.resumed = true;
             token = state.token;
             readerModeFlags = state.readerModeFlags;
+            readerModeExtras = state.readerModeExtras;
         }
         if (readerModeFlags != 0) {
-            setReaderMode(token, readerModeFlags);
+            setReaderMode(token, readerModeFlags, readerModeExtras);
         }
         requestNfcServiceCallback();
     }
@@ -417,7 +443,7 @@
         }
         if (readerModeFlagsSet) {
             // Restore default p2p modes
-            setReaderMode(token, 0);
+            setReaderMode(token, 0, null);
         }
     }
 
@@ -441,4 +467,5 @@
             }
         }
     }
+
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index fa0c1f6..2a18900 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -33,6 +33,7 @@
 import android.nfc.tech.Ndef;
 import android.nfc.tech.NfcA;
 import android.nfc.tech.NfcF;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -196,42 +197,42 @@
     public static final int STATE_TURNING_OFF = 4;
 
     /**
-     * Flag for use with {@link #enableReaderMode(Activity, int)}.
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
      * Setting this flag enables polling for Nfc-A technology.
      */
     public static final int FLAG_READER_NFC_A = 0x1;
 
     /**
-     * Flag for use with {@link #enableReaderMode(Activity, int)}.
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
      * Setting this flag enables polling for Nfc-B technology.
      */
     public static final int FLAG_READER_NFC_B = 0x2;
 
     /**
-     * Flag for use with {@link #enableReaderMode(Activity, int)}.
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
      * Setting this flag enables polling for Nfc-F technology.
      */
     public static final int FLAG_READER_NFC_F = 0x4;
 
     /**
-     * Flag for use with {@link #enableReaderMode(Activity, int)}.
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
      * Setting this flag enables polling for Nfc-V (ISO15693) technology.
      */
     public static final int FLAG_READER_NFC_V = 0x8;
 
     /**
-     * Flag for use with {@link #enableReaderMode(Activity, int)}.
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
      * Setting this flag enables polling for Kovio technology.
      */
     public static final int FLAG_READER_KOVIO = 0x10;
 
     /**
-     * Flag for use with {@link #enableReaderMode(Activity, int)}.
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
      * <p>
      * Setting this flag allows the caller to prevent the
      * platform from performing an NDEF check on the tags it
@@ -239,6 +240,23 @@
      */
     public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80;
 
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag allows the caller to prevent the
+     * platform from playing sounds when it discovers a tag.
+     */
+    public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100;
+
+    /**
+     * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this integer extra allows the calling application to specify
+     * the delay that the platform will use for performing presence checks
+     * on any discovered tag.
+     */
+    public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
+
     /** @hide */
     public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
 
@@ -291,6 +309,14 @@
     final Context mContext;
 
     /**
+     * A callback to be invoked when the system has found a tag in
+     * reader mode.
+     */
+    public interface ReaderCallback {
+        public void onTagDiscovered(Tag tag);
+    }
+
+    /**
      * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
      * to another device.
      * @see #setOnNdefPushCompleteCallback
@@ -1167,19 +1193,18 @@
      * {@link Ndef} tag technology from being enumerated on the tag, and that
      * NDEF-based tag dispatch will not be functional.
      *
-     * <p>It is recommended to combine this method with
-     * {@link #enableForegroundDispatch(Activity, PendingIntent, IntentFilter[], String[][])
-     * to ensure that tags are delivered to this activity.
-     *
      * <p>For interacting with tags that are emulated on another Android device
      * using Android's host-based card-emulation, the recommended flags are
      * {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}.
      *
      * @param activity the Activity that requests the adapter to be in reader mode
+     * @param callback the callback to be called when a tag is discovered
      * @param flags Flags indicating poll technologies and other optional parameters
+     * @param extras Additional extras for configuring reader mode.
      */
-    public void enableReaderMode(Activity activity, int flags) {
-        mNfcActivityManager.enableReaderMode(activity, flags);
+    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
+            Bundle extras) {
+        mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
     }
 
     /**
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
index 1bb2ea4..174acc0 100644
--- a/core/java/android/nfc/cardemulation/HostApduService.java
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -81,7 +81,7 @@
      * currently active on the logical channel).
      *
      * <p>Note that this next AID may still be resolved to this
-     * service, in which case {@link #processCommandApdu(byte[], int)}
+     * service, in which case {@link #processCommandApdu(byte[], Bundle)}
      * will be called again.
      */
     public static final int DEACTIVATION_DESELECTED = 1;
@@ -149,7 +149,7 @@
 
                 byte[] apdu = dataBundle.getByteArray(KEY_DATA);
                 if (apdu != null) {
-                    byte[] responseApdu = processCommandApdu(apdu, 0);
+                    byte[] responseApdu = processCommandApdu(apdu, null);
                     if (responseApdu != null) {
                         if (mNfcService == null) {
                             Log.e(TAG, "Response not sent; service was deactivated.");
@@ -248,7 +248,7 @@
      * transaction.
      *
      * <p>Note: this method may be called anywhere between
-     *    the first {@link #processCommandApdu(byte[], int)}
+     *    the first {@link #processCommandApdu(byte[], Bundle)}
      *    call and a {@link #onDeactivated(int)} call.
      */
     public final void notifyUnhandled() {
@@ -308,8 +308,11 @@
      * @param flags
      * @return a byte-array containing the response APDU, or null if no
      *         response APDU can be sent at this point.
+     * @hide
      */
-    public abstract byte[] processCommandApdu(byte[] commandApdu, int flags);
+    public byte[] processCommandApdu(byte[] commandApdu, int flags) {
+        return null;
+    }
 
     /**
      * This method will be called in two possible scenarios:
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 38ffb96..dbaa325 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2380,22 +2380,25 @@
     
     @SuppressWarnings("unused")
     public void dumpCheckinLocked(
-            PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly) {
+            PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
+            boolean includeHistory) {
         prepareForDumpLocked();
         
         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
 
-        final HistoryItem rec = new HistoryItem();
-        if (startIteratingHistoryLocked()) {
-            HistoryPrinter hprinter = new HistoryPrinter();
-            while (getNextHistoryLocked(rec)) {
-                pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
-                pw.print(0); pw.print(',');
-                pw.print(HISTORY_DATA); pw.print(',');
-                hprinter.printNextItemCheckin(pw, rec, now);
-                pw.println();
+        if (includeHistory) {
+            final HistoryItem rec = new HistoryItem();
+            if (startIteratingHistoryLocked()) {
+                HistoryPrinter hprinter = new HistoryPrinter();
+                while (getNextHistoryLocked(rec)) {
+                    pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+                    pw.print(0); pw.print(',');
+                    pw.print(HISTORY_DATA); pw.print(',');
+                    hprinter.printNextItemCheckin(pw, rec, now);
+                    pw.println();
+                }
+                finishIteratingHistoryLocked();
             }
-            finishIteratingHistoryLocked();
         }
 
         if (apps != null) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 83426ae..10b9765 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -357,7 +357,18 @@
      * @param restrictionKey the string key representing the restriction
      */
     public boolean hasUserRestriction(String restrictionKey) {
-        return getUserRestrictions().getBoolean(restrictionKey, false);
+        return hasUserRestriction(restrictionKey, Process.myUserHandle());
+    }
+
+    /**
+     * @hide
+     * Returns whether the given user has been disallowed from performing certain actions
+     * or setting certain settings.
+     * @param restrictionKey the string key representing the restriction
+     * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
+     */
+    public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
+        return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
     }
 
     /**
diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java
index bb26a3a..c81ca95 100644
--- a/core/java/android/print/PrintDocumentAdapter.java
+++ b/core/java/android/print/PrintDocumentAdapter.java
@@ -55,7 +55,7 @@
  * The APIs defined in this class are designed to enable doing part or all
  * of the work on an arbitrary thread. For example, if the printed content
  * does not depend on the UI state, i.e. on what is shown on the screen, then
- * you can off load the entire work on a dedicated thread, thus making your
+ * you can offload the entire work on a dedicated thread, thus making your
  * application interactive while the print work is being performed.
  * </p>
  * <p>
@@ -99,6 +99,7 @@
      * the last argument <code>true</code> or <code>false</code> depending on
      * whether the layout changed the content or not, respectively; and {@link
      * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred.
+     * Note that you must call one of the methods of the given callback.
      * </p>
      * <p>
      * <strong>Note:</strong> If the content is large and a layout will be
@@ -125,13 +126,14 @@
 
     /**
      * Called when specific pages of the content should be written in the
-     * from of a PDF file to the given file descriptor. This method is invoked
+     * form of a PDF file to the given file descriptor. This method is invoked
      * on the main thread.
      *<p>
      * After you are done writing, you should close the file descriptor and
-     * invoke {@link WriteResultCallback #onWriteFinished(List)}, if writing
+     * invoke {@link WriteResultCallback #onWriteFinished(PageRange[]), if writing
      * completed successfully; or {@link WriteResultCallback#onWriteFailed(
-     * CharSequence)}, if an error occurred.
+     * CharSequence)}, if an error occurred. Note that you must call one of
+     * the methods of the given callback.
      * </p>
      * <p>
      * <strong>Note:</strong> If the printed content is large, it is a good
diff --git a/core/java/android/print/PrintFileDocumentAdapter.java b/core/java/android/print/PrintFileDocumentAdapter.java
index b905396..c3a23a5 100644
--- a/core/java/android/print/PrintFileDocumentAdapter.java
+++ b/core/java/android/print/PrintFileDocumentAdapter.java
@@ -36,10 +36,11 @@
 import java.io.OutputStream;
 
 /**
- * Adapter for printing files. This class could be useful if you
+ * Adapter for printing PDF files. This class could be useful if you
  * want to print a file and intercept when the system is ready
- * spooling the data, so you can deleted the file if it is a
- * temporary one.
+ * spooling the data, so you can delete the file if it is a
+ * temporary one. To achieve this one must override {@link #onFinish()}
+ * and delete the file yourself.
  */
 public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
 
@@ -57,7 +58,7 @@
      * Constructor.
      *
      * @param context Context for accessing resources.
-     * @param file The file to print.
+     * @param file The PDF file to print.
      * @param documentInfo The information about the printed file.
      */
     public PrintFileDocumentAdapter(Context context, File file,
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
index 8bae9d6..4ff7f0c 100644
--- a/core/java/android/printservice/PrintJob.java
+++ b/core/java/android/printservice/PrintJob.java
@@ -26,8 +26,8 @@
  * service. It provides APIs for observing the print job state and
  * performing operations on the print job.
  * <p>
- * <strong>Note: </strong> All methods of this class must be executed on the main
- * application thread.
+ * <strong>Note: </strong> All methods of this class must be invoked on
+ * the main application thread.
  * </p>
  */
 public final class PrintJob {
diff --git a/core/java/android/printservice/PrinterDiscoverySession.java b/core/java/android/printservice/PrinterDiscoverySession.java
index 5450e02..b0bf3da 100644
--- a/core/java/android/printservice/PrinterDiscoverySession.java
+++ b/core/java/android/printservice/PrinterDiscoverySession.java
@@ -30,7 +30,7 @@
 /**
  * This class encapsulates the interaction between a print service and the
  * system during printer discovery. During printer discovery you are responsible
- * for adding discovered printers, removing already added printers that
+ * for adding discovered printers, removing previously added printers that
  * disappeared, and updating already added printers.
  * <p>
  * During the lifetime of this session you may be asked to start and stop
diff --git a/core/java/android/printservice/package.html b/core/java/android/printservice/package.html
index 6b0327c..7410a49 100644
--- a/core/java/android/printservice/package.html
+++ b/core/java/android/printservice/package.html
@@ -9,8 +9,7 @@
 <p>
 A print service implementation should extend {@link android.printservice.PrintService}
 and implement its abstract methods. Also the print service has to follow the contract for
-managing print {@link android.printservice.PrintJob}s to ensure correct interaction with
-the system and consistent user experience.
+managing print {@link android.printservice.PrintJob}s.
 <p/>
 <p>
 The system is responsible for starting and stopping a print service depending on whether
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 09f4866..07cb2a9 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -28,11 +28,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.UriMatcher;
+import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.graphics.Point;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
@@ -40,6 +42,8 @@
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import libcore.io.IoUtils;
 
 import java.io.FileNotFoundException;
@@ -328,16 +332,24 @@
     @Override
     public final Bundle callFromPackage(
             String callingPackage, String method, String arg, Bundle extras) {
+        final Context context = getContext();
+
         if (!method.startsWith("android:")) {
             // Let non-platform methods pass through
             return super.callFromPackage(callingPackage, method, arg, extras);
         }
 
-        // Require that caller can manage given document
         final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
         final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
-        getContext().enforceCallingOrSelfUriPermission(
-                documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method);
+
+        // Require that caller can manage given document
+        final boolean callerHasManage =
+                context.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DOCUMENTS)
+                == PackageManager.PERMISSION_GRANTED;
+        if (!callerHasManage) {
+            getContext().enforceCallingOrSelfUriPermission(
+                    documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method);
+        }
 
         final Bundle out = new Bundle();
         try {
@@ -345,14 +357,26 @@
                 final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
                 final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
 
-                // TODO: issue Uri grant towards calling package
-                // TODO: enforce that package belongs to caller
                 final String newDocumentId = createDocument(documentId, mimeType, displayName);
                 out.putString(Document.COLUMN_DOCUMENT_ID, newDocumentId);
 
+                // Extend permission grant towards caller if needed
+                if (!callerHasManage) {
+                    final Uri newDocumentUri = DocumentsContract.buildDocumentUri(
+                            mAuthority, newDocumentId);
+                    context.grantUriPermission(callingPackage, newDocumentUri,
+                            Intent.FLAG_GRANT_READ_URI_PERMISSION
+                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                            | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+                }
+
             } else if (METHOD_DELETE_DOCUMENT.equals(method)) {
-                final String docId = extras.getString(Document.COLUMN_DOCUMENT_ID);
-                deleteDocument(docId);
+                deleteDocument(documentId);
+
+                // Document no longer exists, clean up any grants
+                context.revokeUriPermission(documentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                        | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
 
             } else {
                 throw new UnsupportedOperationException("Method not supported " + method);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a17a5378..c3fcd62 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5121,6 +5121,21 @@
                "wifi_display_certification_on";
 
        /**
+        * WPS Configuration method used by Wifi display, this setting only
+        * takes effect when WIFI_DISPLAY_CERTIFICATION_ON is 1 (enabled).
+        *
+        * Possible values are:
+        *
+        * WpsInfo.INVALID: use default WPS method chosen by framework
+        * WpsInfo.PBC    : use Push button
+        * WpsInfo.KEYPAD : use Keypad
+        * WpsInfo.DISPLAY: use Display
+        * @hide
+        */
+       public static final String WIFI_DISPLAY_WPS_CONFIG =
+           "wifi_display_wps_config";
+
+       /**
         * Whether to notify the user of open networks.
         * <p>
         * If not connected and the scan results have an open network, we will
@@ -5282,6 +5297,13 @@
                "data_stall_alarm_aggressive_delay_in_ms";
 
        /**
+        * The number of milliseconds to allow the provisioning apn to remain active
+        * @hide
+        */
+       public static final String PROVISIONING_APN_ALARM_DELAY_IN_MS =
+               "provisioning_apn_alarm_delay_in_ms";
+
+       /**
         * The interval in milliseconds at which to check gprs registration
         * after the first registration mismatch of gprs and voice service,
         * to detect possible data network registration problems.
diff --git a/core/java/android/view/transition/AutoTransition.java b/core/java/android/transition/AutoTransition.java
similarity index 67%
rename from core/java/android/view/transition/AutoTransition.java
rename to core/java/android/transition/AutoTransition.java
index 7ddac7e..6e46021 100644
--- a/core/java/android/view/transition/AutoTransition.java
+++ b/core/java/android/transition/AutoTransition.java
@@ -14,22 +14,28 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 /**
  * Utility class for creating a default transition that automatically fades,
  * moves, and resizes views during a scene change.
+ *
+ * <p>An AutoTransition can be described in a resource file by using the
+ * tag <code>autoTransition</code>, along with the other standard
+ * attributes of {@link android.R.styleable#Transition}.</p>
  */
-public class AutoTransition extends TransitionGroup {
+public class AutoTransition extends TransitionSet {
 
     /**
-     * Constructs an AutoTransition object, which is a TransitionGroup which
+     * Constructs an AutoTransition object, which is a TransitionSet which
      * first fades out disappearing targets, then moves and resizes existing
      * targets, and finally fades in appearing targets.
      *
      */
     public AutoTransition() {
-        setOrdering(SEQUENTIALLY);
-        addTransitions(new Fade(Fade.OUT), new Move(), new Fade(Fade.IN));
+        setOrdering(ORDERING_SEQUENTIAL);
+        addTransition(new Fade(Fade.OUT)).
+                addTransition(new ChangeBounds()).
+                addTransition(new Fade(Fade.IN));
     }
 }
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/transition/ChangeBounds.java
similarity index 90%
rename from core/java/android/view/transition/Move.java
rename to core/java/android/transition/ChangeBounds.java
index fda0cd2..8053bff 100644
--- a/core/java/android/view/transition/Move.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -33,13 +33,17 @@
 /**
  * This transition captures the layout bounds of target views before and after
  * the scene change and animates those changes during the transition.
+ *
+ * <p>A ChangeBounds transition can be described in a resource file by using the
+ * tag <code>changeBounds</code>, along with the other standard
+ * attributes of {@link android.R.styleable#Transition}.</p>
  */
-public class Move extends Transition {
+public class ChangeBounds extends Transition {
 
-    private static final String PROPNAME_BOUNDS = "android:move:bounds";
-    private static final String PROPNAME_PARENT = "android:move:parent";
-    private static final String PROPNAME_WINDOW_X = "android:move:windowX";
-    private static final String PROPNAME_WINDOW_Y = "android:move:windowY";
+    private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";
+    private static final String PROPNAME_PARENT = "android:changeBounds:parent";
+    private static final String PROPNAME_WINDOW_X = "android:changeBounds:windowX";
+    private static final String PROPNAME_WINDOW_Y = "android:changeBounds:windowY";
     private static final String[] sTransitionProperties = {
             PROPNAME_BOUNDS,
             PROPNAME_PARENT,
@@ -50,7 +54,7 @@
     int[] tempLocation = new int[2];
     boolean mResizeClip = false;
     boolean mReparent = false;
-    private static final String LOG_TAG = "Move";
+    private static final String LOG_TAG = "ChangeBounds";
 
     private static RectEvaluator sRectEvaluator = new RectEvaluator();
 
@@ -64,7 +68,7 @@
     }
 
     /**
-     * Setting this flag tells Move to track the before/after parent
+     * Setting this flag tells ChangeBounds to track the before/after parent
      * of every view using this transition. The flag is not enabled by
      * default because it requires the parent instances to be the same
      * in the two scenes or else all parents must use ids to allow
@@ -77,8 +81,7 @@
         mReparent = reparent;
     }
 
-    @Override
-    protected void captureValues(TransitionValues values, boolean start) {
+    private void captureValues(TransitionValues values) {
         View view = values.view;
         values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
                 view.getRight(), view.getBottom()));
@@ -89,7 +92,17 @@
     }
 
     @Override
-    protected Animator play(final ViewGroup sceneRoot, TransitionValues startValues,
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         if (startValues == null || endValues == null) {
             return null;
@@ -105,7 +118,7 @@
         boolean parentsEqual = (startParent == endParent) ||
                 (startParent.getId() == endParent.getId());
         // TODO: Might want reparenting to be separate/subclass transition, or at least
-        // triggered by a property on Move. Otherwise, we're forcing the requirement that
+        // triggered by a property on ChangeBounds. Otherwise, we're forcing the requirement that
         // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
         // of reparenting the views.
         if (!mReparent || parentsEqual) {
diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/transition/Crossfade.java
similarity index 89%
rename from core/java/android/view/transition/Crossfade.java
rename to core/java/android/transition/Crossfade.java
index 18bb57f..69ce872 100644
--- a/core/java/android/view/transition/Crossfade.java
+++ b/core/java/android/transition/Crossfade.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -24,10 +24,8 @@
 import android.animation.ValueAnimator;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
 import android.util.Log;
 import android.view.SurfaceView;
 import android.view.TextureView;
@@ -43,6 +41,8 @@
  *
  * <p>Note: This transition is not compatible with {@link TextureView}
  * or {@link SurfaceView}.</p>
+ *
+ * @hide
  */
 public class Crossfade extends Transition {
     // TODO: Add a hook that lets a Transition call user code to query whether it should run on
@@ -121,12 +121,19 @@
      * @param fadeBehavior The type of fading animation to use when this
      * transition is run.
      */
-    public void setFadeBehavior(int fadeBehavior) {
+    public Crossfade setFadeBehavior(int fadeBehavior) {
         if (fadeBehavior >= FADE_BEHAVIOR_CROSSFADE && fadeBehavior <= FADE_BEHAVIOR_OUT_IN) {
             mFadeBehavior = fadeBehavior;
         }
+        return this;
     }
 
+    /**
+     * Returns the fading behavior of the animation.
+     *
+     * @return This crossfade object.
+     * @see #setFadeBehavior(int)
+     */
     public int getFadeBehavior() {
         return mFadeBehavior;
     }
@@ -139,18 +146,25 @@
      * @param resizeBehavior The type of resizing behavior to use when this
      * transition is run.
      */
-    public void setResizeBehavior(int resizeBehavior) {
+    public Crossfade setResizeBehavior(int resizeBehavior) {
         if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) {
             mResizeBehavior = resizeBehavior;
         }
+        return this;
     }
 
+    /**
+     * Returns the resizing behavior of the animation.
+     *
+     * @return This crossfade object.
+     * @see #setResizeBehavior(int)
+     */
     public int getResizeBehavior() {
         return mResizeBehavior;
     }
 
     @Override
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         if (startValues == null || endValues == null) {
             return null;
@@ -243,18 +257,16 @@
         }
     }
 
-    @Override
-    protected void captureValues(TransitionValues values, boolean start) {
-        View view = values.view;
+    private void captureValues(TransitionValues transitionValues) {
+        View view = transitionValues.view;
         Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
         if (mFadeBehavior != FADE_BEHAVIOR_REVEAL) {
             bounds.offset(view.getLeft(), view.getTop());
         }
-        values.values.put(PROPNAME_BOUNDS, bounds);
+        transitionValues.values.put(PROPNAME_BOUNDS, bounds);
 
         if (Transition.DBG) {
-            Log.d(LOG_TAG, "Captured bounds " + values.values.get(PROPNAME_BOUNDS) + ": start = " +
-                    start);
+            Log.d(LOG_TAG, "Captured bounds " + transitionValues.values.get(PROPNAME_BOUNDS));
         }
         Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
                 Bitmap.Config.ARGB_8888);
@@ -264,12 +276,21 @@
             Canvas c = new Canvas(bitmap);
             view.draw(c);
         }
-        values.values.put(PROPNAME_BITMAP, bitmap);
+        transitionValues.values.put(PROPNAME_BITMAP, bitmap);
         // TODO: I don't have resources, can't call the non-deprecated method?
         BitmapDrawable drawable = new BitmapDrawable(bitmap);
         // TODO: lrtb will be wrong if the view has transXY set
         drawable.setBounds(bounds);
-        values.values.put(PROPNAME_DRAWABLE, drawable);
+        transitionValues.values.put(PROPNAME_DRAWABLE, drawable);
     }
 
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
 }
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/transition/Fade.java
similarity index 86%
rename from core/java/android/view/transition/Fade.java
rename to core/java/android/transition/Fade.java
index 45c21d8..12e0d73 100644
--- a/core/java/android/view/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -14,12 +14,11 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -30,6 +29,12 @@
  * or non-visible. Visibility is determined by both the
  * {@link View#setVisibility(int)} state of the view as well as whether it
  * is parented in the current view hierarchy.
+ *
+ * <p>A Fade transition can be described in a resource file by using the
+ * tag <code>fade</code>, along with the standard
+ * attributes of {@link android.R.styleable#Fade} and
+ * {@link android.R.styleable#Transition}.</p>
+
  */
 public class Fade extends Visibility {
 
@@ -93,21 +98,31 @@
         return anim;
     }
 
-    @Override
-    protected void captureValues(TransitionValues values, boolean start) {
-        super.captureValues(values, start);
-        float alpha = values.view.getAlpha();
-        values.values.put(PROPNAME_ALPHA, alpha);
+    private void captureValues(TransitionValues transitionValues) {
+        float alpha = transitionValues.view.getAlpha();
+        transitionValues.values.put(PROPNAME_ALPHA, alpha);
         int[] loc = new int[2];
-        values.view.getLocationOnScreen(loc);
-        values.values.put(PROPNAME_SCREEN_X, loc[0]);
-        values.values.put(PROPNAME_SCREEN_Y, loc[1]);
+        transitionValues.view.getLocationOnScreen(loc);
+        transitionValues.values.put(PROPNAME_SCREEN_X, loc[0]);
+        transitionValues.values.put(PROPNAME_SCREEN_Y, loc[1]);
     }
 
     @Override
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public void captureStartValues(TransitionValues transitionValues) {
+        super.captureStartValues(transitionValues);
+        captureValues(transitionValues);
+    }
+
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        super.captureEndValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
-        Animator animator = super.play(sceneRoot, startValues, endValues);
+        Animator animator = super.createAnimator(sceneRoot, startValues, endValues);
         if (animator == null && startValues != null && endValues != null) {
             boolean endVisible = isVisible(endValues);
             final View endView = endValues.view;
@@ -122,13 +137,18 @@
     }
 
     @Override
-    protected Animator appear(ViewGroup sceneRoot,
+    public Animator onAppear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
         if ((mFadingMode & IN) != IN || endValues == null) {
             return null;
         }
         final View endView = endValues.view;
+        if (DBG) {
+            View startView = (startValues != null) ? startValues.view : null;
+            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
+                    startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+        }
         // if alpha < 1, just fade it in from the current value
         if (endView.getAlpha() == 1.0f) {
             endView.setAlpha(0);
@@ -137,7 +157,7 @@
     }
 
     @Override
-    protected Animator disappear(ViewGroup sceneRoot,
+    public Animator onDisappear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
         if ((mFadingMode & OUT) != OUT) {
@@ -147,7 +167,7 @@
         View startView = (startValues != null) ? startValues.view : null;
         View endView = (endValues != null) ? endValues.view : null;
         if (DBG) {
-            Log.d(LOG_TAG, "Fade.predisappear: startView, startVis, endView, endVis = " +
+            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
                         startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
         }
         View overlayView = null;
diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/transition/Recolor.java
similarity index 80%
rename from core/java/android/view/transition/Recolor.java
rename to core/java/android/transition/Recolor.java
index e4858c4..70111d1 100644
--- a/core/java/android/view/transition/Recolor.java
+++ b/core/java/android/transition/Recolor.java
@@ -14,20 +14,17 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.ArgbEvaluator;
 import android.animation.ObjectAnimator;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.util.ArrayMap;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
-import java.util.Map;
-
 /**
  * This transition tracks changes during scene changes to the
  * {@link View#setBackground(android.graphics.drawable.Drawable) background}
@@ -36,22 +33,34 @@
  * {@link TextView#setTextColor(android.content.res.ColorStateList)
  * color} of the text for target TextViews. If the color changes between
  * scenes, the color change is animated.
+ *
+ * @hide
  */
 public class Recolor extends Transition {
 
     private static final String PROPNAME_BACKGROUND = "android:recolor:background";
     private static final String PROPNAME_TEXT_COLOR = "android:recolor:textColor";
 
-    @Override
-    protected void captureValues(TransitionValues values, boolean start) {
-        values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
-        if (values.view instanceof TextView) {
-            values.values.put(PROPNAME_TEXT_COLOR, ((TextView)values.view).getCurrentTextColor());
+    private void captureValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_BACKGROUND, transitionValues.view.getBackground());
+        if (transitionValues.view instanceof TextView) {
+            transitionValues.values.put(PROPNAME_TEXT_COLOR,
+                    ((TextView)transitionValues.view).getCurrentTextColor());
         }
     }
 
     @Override
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         if (startValues == null || endValues == null) {
             return null;
diff --git a/core/java/android/view/transition/Rotate.java b/core/java/android/transition/Rotate.java
similarity index 77%
rename from core/java/android/view/transition/Rotate.java
rename to core/java/android/transition/Rotate.java
index d35a6dc7..ad1720ca 100644
--- a/core/java/android/view/transition/Rotate.java
+++ b/core/java/android/transition/Rotate.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
@@ -24,18 +24,25 @@
 /**
  * This transition captures the rotation property of targets before and after
  * the scene change and animates any changes.
+ *
+ * @hide
  */
 public class Rotate extends Transition {
 
     private static final String PROPNAME_ROTATION = "android:rotate:rotation";
 
     @Override
-    protected void captureValues(TransitionValues values, boolean start) {
-        values.values.put(PROPNAME_ROTATION, values.view.getRotation());
+    public void captureStartValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_ROTATION, transitionValues.view.getRotation());
     }
 
     @Override
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public void captureEndValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_ROTATION, transitionValues.view.getRotation());
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         if (startValues == null || endValues == null) {
             return null;
diff --git a/core/java/android/view/transition/Scene.java b/core/java/android/transition/Scene.java
similarity index 67%
rename from core/java/android/view/transition/Scene.java
rename to core/java/android/transition/Scene.java
index cf3eadb..f81eeef 100644
--- a/core/java/android/view/transition/Scene.java
+++ b/core/java/android/transition/Scene.java
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.content.Context;
+import android.util.SparseArray;
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
 
 /**
@@ -34,6 +36,37 @@
     private ViewGroup mSceneRoot;
     private ViewGroup mLayout; // alternative to layoutId
     Runnable mEnterAction, mExitAction;
+    private static ThreadLocal<SparseArray<Scene>> sScenes = new ThreadLocal<SparseArray<Scene>>();
+
+    /**
+     * Returns a Scene described by the resource file associated with the given
+     * <code>layoutId</code> parameter. If such a Scene has already been created,
+     * that same Scene will be returned. This caching of layoutId-based scenes enables
+     * sharing of common scenes between those created in code and those referenced
+     * by {@link TransitionManager} XML resource files.
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     * and transitions will take place.
+     * @param layoutId The id of a standard layout resource file.
+     * @param context The context used in the process of inflating
+     * the layout resource.
+     * @return
+     */
+    public static Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
+        SparseArray<Scene> scenes = sScenes.get();
+        if (scenes == null) {
+            scenes = new SparseArray<Scene>();
+            sScenes.set(scenes);
+        }
+        Scene scene = scenes.get(layoutId);
+        if (scene != null) {
+            return scene;
+        } else {
+            scene = new Scene(sceneRoot, layoutId, context);
+            scenes.put(layoutId, scene);
+            return scene;
+        }
+    }
 
     /**
      * Constructs a Scene with no information about how values will change
@@ -54,6 +87,9 @@
      * children from the sceneRoot container and will inflate and add
      * the hierarchy specified by the layoutId resource file.
      *
+     * <p>This method is hidden because layoutId-based scenes should be
+     * created by the caching factory method {@link Scene#getCurrentScene(View)}.</p>
+     *
      * @param sceneRoot The root of the hierarchy in which scene changes
      * and transitions will take place.
      * @param layoutId The id of a resource file that defines the view
@@ -61,7 +97,7 @@
      * @param context The context used in the process of inflating
      * the layout resource.
      */
-    public Scene(ViewGroup sceneRoot, int layoutId, Context context) {
+    private Scene(ViewGroup sceneRoot, int layoutId, Context context) {
         mContext = context;
         mSceneRoot = sceneRoot;
         mLayoutId = layoutId;
@@ -74,7 +110,7 @@
      *
      * @param sceneRoot The root of the hierarchy in which scene changes
      * and transitions will take place.
-     * @param layout The view hiearrchy of this scene, added as a child
+     * @param layout The view hierarchy of this scene, added as a child
      * of sceneRoot when this scene is entered.
      */
     public Scene(ViewGroup sceneRoot, ViewGroup layout) {
@@ -94,19 +130,14 @@
     }
 
     /**
-     * Exits this scene, if it is the {@link ViewGroup#getCurrentScene()
-     * currentScene} on the scene's {@link #getSceneRoot() scene root}.
-     * Exiting a scene involves removing the layout added if the scene
-     * has either a layoutId or layout view group (set at construction
-     * time) and running the {@link #setExitAction(Runnable) exit action}
+     * Exits this scene, if it is the current scene
+     * on the scene's {@link #getSceneRoot() scene root}. The current scene is
+     * set when {@link #enter() entering} a scene.
+     * Exiting a scene runs the {@link #setExitAction(Runnable) exit action}
      * if there is one.
      */
     public void exit() {
-        if (mSceneRoot.getCurrentScene() == this) {
-            if (mLayoutId >= 0 || mLayout != null) {
-                // Undo layout change caused by entering this scene
-                getSceneRoot().removeAllViews();
-            }
+        if (getCurrentScene(mSceneRoot) == this) {
             if (mExitAction != null) {
                 mExitAction.run();
             }
@@ -127,8 +158,7 @@
 
         // Apply layout change, if any
         if (mLayoutId >= 0 || mLayout != null) {
-            // redundant with exit() action of previous scene, but must
-            // empty out that parent container before adding to it
+            // empty out parent container before adding to it
             getSceneRoot().removeAllViews();
 
             if (mLayoutId >= 0) {
@@ -143,7 +173,30 @@
             mEnterAction.run();
         }
 
-        mSceneRoot.setCurrentScene(this );
+        setCurrentScene(mSceneRoot, this);
+    }
+
+    /**
+     * Set the scene that the given view is in. The current scene is set only
+     * on the root view of a scene, not for every view in that hierarchy. This
+     * information is used by Scene to determine whether there is a previous
+     * scene which should be exited before the new scene is entered.
+     *
+     * @param view The view on which the current scene is being set
+     */
+    static void setCurrentScene(View view, Scene scene) {
+        view.setTagInternal(com.android.internal.R.id.current_scene, scene);
+    }
+
+    /**
+     * Gets the current {@link Scene} set on the given view. A scene is set on a view
+     * only if that view is the scene root.
+     *
+     * @return The current Scene set on this view. A value of null indicates that
+     * no Scene is currently set.
+     */
+    static Scene getCurrentScene(View view) {
+        return (Scene) view.getTag(com.android.internal.R.id.current_scene);
     }
 
     /**
diff --git a/core/java/android/view/transition/Slide.java b/core/java/android/transition/Slide.java
similarity index 93%
rename from core/java/android/view/transition/Slide.java
rename to core/java/android/transition/Slide.java
index b2f5db5..b38973c 100644
--- a/core/java/android/view/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
@@ -28,6 +28,8 @@
  * This transition captures the visibility of target objects before and
  * after a scene change and animates any changes by sliding the target
  * objects into or out of place.
+ *
+ * @hide
  */
 public class Slide extends Visibility {
 
@@ -37,7 +39,7 @@
     private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
 
     @Override
-    protected Animator appear(ViewGroup sceneRoot,
+    public Animator onAppear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
         View endView = (endValues != null) ? endValues.view : null;
@@ -49,7 +51,7 @@
     }
 
     @Override
-    protected Animator disappear(ViewGroup sceneRoot,
+    public Animator onDisappear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
         View startView = (startValues != null) ? startValues.view : null;
diff --git a/core/java/android/view/transition/TextChange.java b/core/java/android/transition/TextChange.java
similarity index 85%
rename from core/java/android/view/transition/TextChange.java
rename to core/java/android/transition/TextChange.java
index 7973c97..1b26942 100644
--- a/core/java/android/view/transition/TextChange.java
+++ b/core/java/android/transition/TextChange.java
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
 import android.graphics.Color;
-import android.util.ArrayMap;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
@@ -33,6 +32,8 @@
  * starting text stays until the transition ends, at which point it changes
  * to the end text.  This is useful in situations where you want to resize a
  * text view to its new size before displaying the text that goes there.
+ *
+ * @hide
  */
 public class TextChange extends Transition {
     private static final String PROPNAME_TEXT = "android:textchange:text";
@@ -84,15 +85,18 @@
 
     /**
      * Sets the type of changing animation that will be run, one of
-     * {@link #CHANGE_BEHAVIOR_KEEP} and {@link #CHANGE_BEHAVIOR_OUT_IN}.
+     * {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT},
+     * {@link #CHANGE_BEHAVIOR_IN}, and {@link #CHANGE_BEHAVIOR_OUT_IN}.
      *
      * @param changeBehavior The type of fading animation to use when this
      * transition is run.
+     * @return this textChange object.
      */
-    public void setChangeBehavior(int changeBehavior) {
+    public TextChange setChangeBehavior(int changeBehavior) {
         if (changeBehavior >= CHANGE_BEHAVIOR_KEEP && changeBehavior <= CHANGE_BEHAVIOR_OUT_IN) {
             mChangeBehavior = changeBehavior;
         }
+        return this;
     }
 
     @Override
@@ -100,19 +104,38 @@
         return sTransitionProperties;
     }
 
-    @Override
-    protected void captureValues(TransitionValues values, boolean start) {
-        if (values.view instanceof TextView) {
-            TextView textview = (TextView) values.view;
-            values.values.put(PROPNAME_TEXT, textview.getText());
+    /**
+     * Returns the type of changing animation that will be run.
+     *
+     * @return either {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT},
+     * {@link #CHANGE_BEHAVIOR_IN}, or {@link #CHANGE_BEHAVIOR_OUT_IN}.
+     */
+    public int getChangeBehavior() {
+        return mChangeBehavior;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        if (transitionValues.view instanceof TextView) {
+            TextView textview = (TextView) transitionValues.view;
+            transitionValues.values.put(PROPNAME_TEXT, textview.getText());
             if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) {
-                values.values.put(PROPNAME_TEXT_COLOR, textview.getCurrentTextColor());
+                transitionValues.values.put(PROPNAME_TEXT_COLOR, textview.getCurrentTextColor());
             }
         }
     }
 
     @Override
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
             return null;
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/transition/Transition.java
similarity index 77%
rename from core/java/android/view/transition/Transition.java
rename to core/java/android/transition/Transition.java
index a66fa52..59df183 100644
--- a/core/java/android/view/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -31,11 +31,12 @@
 import android.widget.ListView;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * A Transition holds information about animations that will be run on its
  * targets during a scene change. Subclasses of this abstract class may
- * choreograph several child transitions ({@link TransitionGroup} or they may
+ * choreograph several child transitions ({@link TransitionSet} or they may
  * perform custom animations themselves. Any Transition has two main jobs:
  * (1) capture property values, and (2) play animations based on changes to
  * captured property values. A custom transition knows what property values
@@ -50,9 +51,42 @@
  * a non-UI thread, so changes to the view due to transitions (such as moving
  * and resizing the view) may be out of sync with the display inside those bounds.
  * TextureView is more compatible with transitions in general, but some
- * specific transitions (such as {@link Crossfade}) may not be compatible
+ * specific transitions (such as {@link Fade}) may not be compatible
  * with TextureView because they rely on {@link ViewOverlay} functionality,
  * which does not currently work with TextureView.</p>
+ *
+ * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code>
+ * directory. Transition resources consist of a tag name for one of the Transition
+ * subclasses along with attributes to define some of the attributes of that transition.
+ * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds}
+ *
+ * <p>Note that attributes for the transition are not required, just as they are
+ * optional when declared in code; Transitions created from XML resources will use
+ * the same defaults as their code-created equivalents. Here is a slightly more
+ * elaborate example which declares a {@link TransitionSet} transition with
+ * {@link ChangeBounds} and {@link Fade} child transitions:</p>
+ *
+ * {@sample
+ * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet}
+ *
+ * <p>In this example, the transitionOrdering attribute is used on the TransitionSet
+ * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior
+ * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade}
+ * transition uses a fadingMode of {@link Fade#OUT} instead of the default
+ * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which
+ * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each
+ * of which lists a specific <code>targetId</code> which this transition acts upon.
+ * Use of targets is optional, but can be used to either limit the time spent checking
+ * attributes on unchanging views, or limiting the types of animations run on specific views.
+ * In this case, we know that only the <code>grayscaleContainer</code> will be
+ * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p>
+ *
+ * Further information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, and {@link android.R.styleable#Fade}.
+ *
  */
 public abstract class Transition implements Cloneable {
 
@@ -64,17 +98,17 @@
     long mStartDelay = -1;
     long mDuration = -1;
     TimeInterpolator mInterpolator = null;
-    int[] mTargetIds;
-    View[] mTargets;
+    ArrayList<Integer> mTargetIds = new ArrayList<Integer>();
+    ArrayList<View> mTargets = new ArrayList<View>();
     private TransitionValuesMaps mStartValues = new TransitionValuesMaps();
     private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
-    TransitionGroup mParent = null;
+    TransitionSet mParent = null;
 
     // Per-animator information used for later canceling when future transitions overlap
     private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators =
             new ThreadLocal<ArrayMap<Animator, AnimationInfo>>();
 
-    // Scene Root is set at play() time in the cloned Transition
+    // Scene Root is set at createAnimator() time in the cloned Transition
     ViewGroup mSceneRoot = null;
 
     // Track all animators in use in case the transition gets canceled and needs to
@@ -91,14 +125,15 @@
     // The set of listeners to be sent transition lifecycle events.
     ArrayList<TransitionListener> mListeners = null;
 
-    // The set of animators collected from calls to play(), to be run in runAnimations()
+    // The set of animators collected from calls to createAnimator(),
+    // to be run in runAnimators()
     ArrayList<Animator> mAnimators = new ArrayList<Animator>();
 
     /**
      * Constructs a Transition object with no target objects. A transition with
      * no targets defaults to running on all target objects in the scene hierarchy
-     * (if the transition is not contained in a TransitionGroup), or all target
-     * objects passed down from its parent (if it is in a TransitionGroup).
+     * (if the transition is not contained in a TransitionSet), or all target
+     * objects passed down from its parent (if it is in a TransitionSet).
      */
     public Transition() {}
 
@@ -110,6 +145,7 @@
      *
      * @param duration The length of the animation, in milliseconds.
      * @return This transition object.
+     * @attr ref android.R.styleable#Transition_duration
      */
     public Transition setDuration(long duration) {
         mDuration = duration;
@@ -121,8 +157,8 @@
      * the returned value will be negative, indicating that resulting animators will
      * retain their own durations.
      *
-     * @return The duration set on this transition, if one has been set, otherwise
-     * returns a negative number.
+     * @return The duration set on this transition, in milliseconds, if one has been
+     * set, otherwise returns a negative number.
      */
     public long getDuration() {
         return mDuration;
@@ -135,9 +171,12 @@
      * Transition is set, that delay will override the Animator delay.
      *
      * @param startDelay The length of the delay, in milliseconds.
+     * @return This transition object.
+     * @attr ref android.R.styleable#Transition_startDelay
      */
-    public void setStartDelay(long startDelay) {
+    public Transition setStartDelay(long startDelay) {
         mStartDelay = startDelay;
+        return this;
     }
 
     /**
@@ -145,8 +184,8 @@
      * the returned value will be negative, indicating that resulting animators will
      * retain their own startDelays.
      *
-     * @return The startDealy set on this transition, if one has been set, otherwise
-     * returns a negative number.
+     * @return The startDelay set on this transition, in milliseconds, if one has
+     * been set, otherwise returns a negative number.
      */
     public long getStartDelay() {
         return mStartDelay;
@@ -159,9 +198,12 @@
      * Transition is set, that interpolator will override the Animator interpolator.
      *
      * @param interpolator The time interpolator used by the transition
+     * @return This transition object.
+     * @attr ref android.R.styleable#Transition_interpolator
      */
-    public void setInterpolator(TimeInterpolator interpolator) {
+    public Transition setInterpolator(TimeInterpolator interpolator) {
         mInterpolator = interpolator;
+        return this;
     }
 
     /**
@@ -178,7 +220,7 @@
 
     /**
      * Returns the set of property names used stored in the {@link TransitionValues}
-     * object passed into {@link #captureValues(TransitionValues, boolean)} that
+     * object passed into {@link #captureStartValues(TransitionValues)} that
      * this transition cares about for the purposes of canceling overlapping animations.
      * When any transition is started on a given scene root, all transitions
      * currently running on that same scene root are checked to see whether the
@@ -202,11 +244,17 @@
     }
 
     /**
-     * This method is called by the transition's parent (all the way up to the
+     * This method creates an animation that will be run for this transition
+     * given the information in the startValues and endValues structures captured
+     * earlier for the start and end scenes. Subclasses of Transition should override
+     * this method. The method should only be called by the transition system; it is
+     * not intended to be called from external classes.
+     *
+     * <p>This method is called by the transition's parent (all the way up to the
      * topmost Transition in the hierarchy) with the sceneRoot and start/end
      * values that the transition may need to set up initial target values
      * and construct an appropriate animation. For example, if an overall
-     * Transition is a {@link TransitionGroup} consisting of several
+     * Transition is a {@link TransitionSet} consisting of several
      * child transitions in sequence, then some of the child transitions may
      * want to set initial values on target views prior to the overall
      * Transition commencing, to put them in an appropriate state for the
@@ -216,14 +264,13 @@
      * actually starting the animation. This is necessary because the scene
      * change that triggers the Transition will automatically set the end-scene
      * on all target views, so a Transition that wants to animate from a
-     * different value should set that value prior to returning from this method.
+     * different value should set that value prior to returning from this method.</p>
      *
      * <p>Additionally, a Transition can perform logic to determine whether
      * the transition needs to run on the given target and start/end values.
      * For example, a transition that resizes objects on the screen may wish
      * to avoid running for views which are not present in either the start
-     * or end scenes. A return value of <code>null</code> indicates that
-     * no animation should run. The default implementation returns null.</p>
+     * or end scenes.</p>
      *
      * <p>If there is an animator created and returned from this method, the
      * transition mechanism will apply any applicable duration, startDelay,
@@ -234,31 +281,34 @@
      * <p>The method is called for every applicable target object, which is
      * stored in the {@link TransitionValues#view} field.</p>
      *
-     * @param sceneRoot
-     * @param startValues
-     * @param endValues
-     * @return A non-null Animator to be started at the appropriate time in the
-     * overall transition for this scene change, null otherwise.
+     *
+     * @param sceneRoot The root of the transition hierarchy.
+     * @param startValues The values for a specific target in the start scene.
+     * @param endValues The values for the target in the end scene.
+     * @return A Animator to be started at the appropriate time in the
+     * overall transition for this scene change. A null value means no animation
+     * should be run.
      */
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         return null;
     }
 
     /**
-     * This version of play() is called with the entire set of start/end
+     * This method, essentially a wrapper around all calls to createAnimator for all
+     * possible target views, is called with the entire set of start/end
      * values. The implementation in Transition iterates through these lists
-     * and calls {@link #play(ViewGroup, TransitionValues, TransitionValues)}
+     * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
      * with each set of start/end values on this transition. The
-     * TransitionGroup subclass overrides this method and delegates it to
+     * TransitionSet subclass overrides this method and delegates it to
      * each of its children in succession.
      *
      * @hide
      */
-    protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
             TransitionValuesMaps endValues) {
         if (DBG) {
-            Log.d(LOG_TAG, "play() for " + this);
+            Log.d(LOG_TAG, "createAnimators() for " + this);
         }
         ArrayMap<View, TransitionValues> endCopy =
                 new ArrayMap<View, TransitionValues>(endValues.viewValues);
@@ -392,7 +442,7 @@
                         }
                     }
                     // TODO: what to do about targetIds and itemIds?
-                    Animator animator = play(sceneRoot, start, end);
+                    Animator animator = createAnimator(sceneRoot, start, end);
                     if (animator != null) {
                         // Save animation info for future cancellation purposes
                         View view = null;
@@ -450,19 +500,19 @@
      * views are ignored and only the ids are used).
      */
     boolean isValidTarget(View target, long targetId) {
-        if (mTargetIds == null && mTargets == null) {
+        if (mTargetIds.size() == 0 && mTargets.size() == 0) {
             return true;
         }
-        if (mTargetIds != null) {
-            for (int i = 0; i < mTargetIds.length; ++i) {
-                if (mTargetIds[i] == targetId) {
+        if (mTargetIds.size() > 0) {
+            for (int i = 0; i < mTargetIds.size(); ++i) {
+                if (mTargetIds.get(i) == targetId) {
                     return true;
                 }
             }
         }
-        if (target != null && mTargets != null) {
-            for (int i = 0; i < mTargets.length; ++i) {
-                if (mTargets[i] == target) {
+        if (target != null && mTargets.size() > 0) {
+            for (int i = 0; i < mTargets.size(); ++i) {
+                if (mTargets.get(i) == target) {
                     return true;
                 }
             }
@@ -485,13 +535,13 @@
      *
      * @hide
      */
-    protected void runAnimations() {
+    protected void runAnimators() {
         if (DBG) {
-            Log.d(LOG_TAG, "runAnimations() on " + this);
+            Log.d(LOG_TAG, "runAnimators() on " + this);
         }
         start();
         ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
-        // Now start every Animator that was previously created for this transition in play()
+        // Now start every Animator that was previously created for this transition
         for (Animator anim : mAnimators) {
             if (DBG) {
                 Log.d(LOG_TAG, "  anim: " + anim);
@@ -525,17 +575,20 @@
     }
 
     /**
-     * Captures the current scene of values for the properties that this
-     * transition monitors. These values can be either the start or end
-     * values used in a subsequent call to
-     * {@link #play(ViewGroup, TransitionValues, TransitionValues)}, as indicated by
-     * <code>start</code>. The main concern for an implementation is what the
+     * Captures the values in the start scene for the properties that this
+     * transition monitors. These values are then passed as the startValues
+     * structure in a later call to
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+     * The main concern for an implementation is what the
      * properties are that the transition cares about and what the values are
      * for all of those properties. The start and end values will be compared
      * later during the
-     * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)}
+     * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}
      * method to determine what, if any, animations, should be run.
      *
+     * <p>Subclasses must implement this method. The method should only be called by the
+     * transition system; it is not intended to be called from external classes.</p>
+     *
      * @param transitionValues The holder for any values that the Transition
      * wishes to store. Values are stored in the <code>values</code> field
      * of this TransitionValues object and are keyed from
@@ -544,29 +597,80 @@
      * <code>transitionValues.values.put("appname:transitionname:rotation",
      * view.getRotation())</code>. The target view will already be stored in
      * the transitionValues structure when this method is called.
+     *
+     * @see #captureEndValues(TransitionValues)
+     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
      */
-    protected abstract void captureValues(TransitionValues transitionValues, boolean start);
+    public abstract void captureStartValues(TransitionValues transitionValues);
 
     /**
-     * Sets the ids of target views that this Transition is interested in
+     * Captures the values in the end scene for the properties that this
+     * transition monitors. These values are then passed as the endValues
+     * structure in a later call to
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+     * The main concern for an implementation is what the
+     * properties are that the transition cares about and what the values are
+     * for all of those properties. The start and end values will be compared
+     * later during the
+     * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}
+     * method to determine what, if any, animations, should be run.
+     *
+     * <p>Subclasses must implement this method. The method should only be called by the
+     * transition system; it is not intended to be called from external classes.</p>
+     *
+     * @param transitionValues The holder for any values that the Transition
+     * wishes to store. Values are stored in the <code>values</code> field
+     * of this TransitionValues object and are keyed from
+     * a String value. For example, to store a view's rotation value,
+     * a transition might call
+     * <code>transitionValues.values.put("appname:transitionname:rotation",
+     * view.getRotation())</code>. The target view will already be stored in
+     * the transitionValues structure when this method is called.
+     *
+     * @see #captureStartValues(TransitionValues)
+     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     */
+    public abstract void captureEndValues(TransitionValues transitionValues);
+
+    /**
+     * Adds the id of a target view that this Transition is interested in
      * animating. By default, there are no targetIds, and a Transition will
      * listen for changes on every view in the hierarchy below the sceneRoot
-     * of the Scene being transitioned into. Setting targetIDs constrains
+     * of the Scene being transitioned into. Setting targetIds constrains
      * the Transition to only listen for, and act on, views with these IDs.
      * Views with different IDs, or no IDs whatsoever, will be ignored.
      *
+     * <p>Note that using ids to specify targets implies that ids should be unique
+     * within the view hierarchy underneat the scene root.</p>
+     *
      * @see View#getId()
-     * @param targetIds A list of IDs which specify the set of Views on which
-     * the Transition will act.
-     * @return Transition The Transition on which the targetIds have been set.
+     * @param targetId The id of a target view, must be a positive number.
+     * @return The Transition to which the targetId is added.
      * Returning the same object makes it easier to chain calls during
      * construction, such as
-     * <code>transitionGroup.addTransitions(new Fade()).setTargetIds(someId);</code>
+     * <code>transitionSet.addTransitions(new Fade()).addTargetId(someId);</code>
      */
-    public Transition setTargetIds(int... targetIds) {
-        int numTargets = targetIds.length;
-        mTargetIds = new int[numTargets];
-        System.arraycopy(targetIds, 0, mTargetIds, 0, numTargets);
+    public Transition addTargetId(int targetId) {
+        if (targetId > 0) {
+            mTargetIds.add(targetId);
+        }
+        return this;
+    }
+
+    /**
+     * Removes the given targetId from the list of ids that this Transition
+     * is interested in animating.
+     *
+     * @param targetId The id of a target view, must be a positive number.
+     * @return The Transition from which the targetId is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code>
+     */
+    public Transition removeTargetId(int targetId) {
+        if (targetId > 0) {
+            mTargetIds.remove(targetId);
+        }
         return this;
     }
 
@@ -578,28 +682,43 @@
      * the Transition to only listen for, and act on, these views.
      * All other views will be ignored.
      *
-     * <p>The target list is like the {@link #setTargetIds(int...) targetId}
+     * <p>The target list is like the {@link #addTargetId(int) targetId}
      * list except this list specifies the actual View instances, not the ids
      * of the views. This is an important distinction when scene changes involve
      * view hierarchies which have been inflated separately; different views may
      * share the same id but not actually be the same instance. If the transition
-     * should treat those views as the same, then seTargetIds() should be used
-     * instead of setTargets(). If, on the other hand, scene changes involve
+     * should treat those views as the same, then {@link #addTargetId(int)} should be used
+     * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
      * changes all within the same view hierarchy, among views which do not
-     * necessary have ids set on them, then the target list may be more
+     * necessarily have ids set on them, then the target list of views may be more
      * convenient.</p>
      *
-     * @see #setTargetIds(int...)
-     * @param targets A list of Views on which the Transition will act.
-     * @return Transition The Transition on which the targets have been set.
+     * @see #addTargetId(int)
+     * @param target A View on which the Transition will act, must be non-null.
+     * @return The Transition to which the target is added.
      * Returning the same object makes it easier to chain calls during
      * construction, such as
-     * <code>transitionGroup.addTransitions(new Fade()).setTargets(someView);</code>
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code>
      */
-    public Transition setTargets(View... targets) {
-        int numTargets = targets.length;
-        mTargets = new View[numTargets];
-        System.arraycopy(targets, 0, mTargets, 0, numTargets);
+    public Transition addTarget(View target) {
+        mTargets.add(target);
+        return this;
+    }
+
+    /**
+     * Removes the given target from the list of targets that this Transition
+     * is interested in animating.
+     *
+     * @param target The target view, must be non-null.
+     * @return Transition The Transition from which the target is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code>
+     */
+    public Transition removeTarget(View target) {
+        if (target != null) {
+            mTargets.remove(target);
+        }
         return this;
     }
 
@@ -612,7 +731,7 @@
      *
      * @return the list of target IDs
      */
-    public int[] getTargetIds() {
+    public List<Integer> getTargetIds() {
         return mTargetIds;
     }
 
@@ -625,7 +744,7 @@
      *
      * @return the list of target views
      */
-    public View[] getTargets() {
+    public List<View> getTargets() {
         return mTargets;
     }
 
@@ -646,16 +765,19 @@
             mEndValues.idValues.clear();
             mEndValues.itemIdValues.clear();
         }
-        if (mTargetIds != null && mTargetIds.length > 0 ||
-                mTargets != null && mTargets.length > 0) {
-            if (mTargetIds != null) {
-                for (int i = 0; i < mTargetIds.length; ++i) {
-                    int id = mTargetIds[i];
+        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
+            if (mTargetIds.size() > 0) {
+                for (int i = 0; i < mTargetIds.size(); ++i) {
+                    int id = mTargetIds.get(i);
                     View view = sceneRoot.findViewById(id);
                     if (view != null) {
                         TransitionValues values = new TransitionValues();
                         values.view = view;
-                        captureValues(values, start);
+                        if (start) {
+                            captureStartValues(values);
+                        } else {
+                            captureEndValues(values);
+                        }
                         if (start) {
                             mStartValues.viewValues.put(view, values);
                             if (id >= 0) {
@@ -670,13 +792,17 @@
                     }
                 }
             }
-            if (mTargets != null) {
-                for (int i = 0; i < mTargets.length; ++i) {
-                    View view = mTargets[i];
+            if (mTargets.size() > 0) {
+                for (int i = 0; i < mTargets.size(); ++i) {
+                    View view = mTargets.get(i);
                     if (view != null) {
                         TransitionValues values = new TransitionValues();
                         values.view = view;
-                        captureValues(values, start);
+                        if (start) {
+                            captureStartValues(values);
+                        } else {
+                            captureEndValues(values);
+                        }
                         if (start) {
                             mStartValues.viewValues.put(view, values);
                         } else {
@@ -723,7 +849,7 @@
         }
         TransitionValues values = new TransitionValues();
         values.view = view;
-        captureValues(values, start);
+        captureStartValues(values);
         if (start) {
             if (!isListViewItem) {
                 mStartValues.viewValues.put(view, values);
@@ -757,7 +883,7 @@
      * necessary, for example, to query the before/after state of related views
      * for a given transition.
      */
-    protected TransitionValues getTransitionValues(View view, boolean start) {
+    public TransitionValues getTransitionValues(View view, boolean start) {
         if (mParent != null) {
             return mParent.getTransitionValues(view, start);
         }
@@ -834,7 +960,7 @@
 
     /**
      * Called by TransitionManager to play the transition. This calls
-     * play() to set things up and create all of the animations and then
+     * createAnimators() to set things up and create all of the animations and then
      * runAnimations() to actually start the animations.
      */
     void playTransition(ViewGroup sceneRoot) {
@@ -889,11 +1015,8 @@
             }
         }
 
-        // setup() must be called on entire transition hierarchy and set of views
-        // before calling play() on anything; every transition needs a chance to set up
-        // target views appropriately before transitions begin running
-        play(sceneRoot, mStartValues, mEndValues);
-        runAnimations();
+        createAnimators(sceneRoot, mStartValues, mEndValues);
+        runAnimators();
     }
 
     /**
@@ -933,7 +1056,7 @@
 
     /**
      * This method is called automatically by the transition and
-     * TransitionGroup classes prior to a Transition subclass starting;
+     * TransitionSet classes prior to a Transition subclass starting;
      * subclasses should not need to call it directly.
      *
      * @hide
@@ -954,9 +1077,9 @@
 
     /**
      * This method is called automatically by the Transition and
-     * TransitionGroup classes when a transition finishes, either because
+     * TransitionSet classes when a transition finishes, either because
      * a transition did nothing (returned a null Animator from
-     * {@link Transition#play(ViewGroup, TransitionValues,
+     * {@link Transition#createAnimator(ViewGroup, TransitionValues,
      * TransitionValues)}) or because the transition returned a valid
      * Animator and end() was called in the onAnimationEnd()
      * callback of the AnimatorListener.
@@ -993,11 +1116,10 @@
 
     /**
      * This method cancels a transition that is currently running.
-     * Implementation TBD.
+     *
+     * @hide
      */
     protected void cancel() {
-        // TODO: how does this work with instances?
-        // TODO: this doesn't actually do *anything* yet
         int numAnimators = mCurrentAnimators.size();
         for (int i = numAnimators - 1; i >= 0; i--) {
             Animator animator = mCurrentAnimators.get(i);
@@ -1019,12 +1141,14 @@
      *
      * @param listener the listener to be added to the current set of listeners
      * for this animation.
+     * @return This transition object.
      */
-    public void addListener(TransitionListener listener) {
+    public Transition addListener(TransitionListener listener) {
         if (mListeners == null) {
             mListeners = new ArrayList<TransitionListener>();
         }
         mListeners.add(listener);
+        return this;
     }
 
     /**
@@ -1032,29 +1156,22 @@
      *
      * @param listener the listener to be removed from the current set of
      * listeners for this transition.
+     * @return This transition object.
      */
-    public void removeListener(TransitionListener listener) {
+    public Transition removeListener(TransitionListener listener) {
         if (mListeners == null) {
-            return;
+            return this;
         }
         mListeners.remove(listener);
         if (mListeners.size() == 0) {
             mListeners = null;
         }
+        return this;
     }
 
-    /**
-     * Gets the set of {@link TransitionListener} objects that are currently
-     * listening for events on this <code>Transition</code> object.
-     *
-     * @return ArrayList<TransitionListener> The set of listeners.
-     */
-    public ArrayList<TransitionListener> getListeners() {
-        return mListeners;
-    }
-
-    void setSceneRoot(ViewGroup sceneRoot) {
+    Transition setSceneRoot(ViewGroup sceneRoot) {
         mSceneRoot = sceneRoot;
+        return this;
     }
 
     @Override
@@ -1076,9 +1193,9 @@
     /**
      * Returns the name of this Transition. This name is used internally to distinguish
      * between different transitions to determine when interrupting transitions overlap.
-     * For example, a Move running on the same target view as another Move should determine
-     * whether the old transition is animating to different end values and should be
-     * canceled in favor of the new transition.
+     * For example, a ChangeBounds running on the same target view as another ChangeBounds
+     * should determine whether the old transition is animating to different end values
+     * and should be canceled in favor of the new transition.
      *
      * <p>By default, a Transition's name is simply the value of {@link Class#getName()},
      * but subclasses are free to override and return something different.</p>
@@ -1101,22 +1218,22 @@
         if (mInterpolator != null) {
             result += "interp(" + mInterpolator + ") ";
         }
-        if (mTargetIds != null || mTargets != null) {
+        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
             result += "tgts(";
-            if (mTargetIds != null) {
-                for (int i = 0; i < mTargetIds.length; ++i) {
+            if (mTargetIds.size() > 0) {
+                for (int i = 0; i < mTargetIds.size(); ++i) {
                     if (i > 0) {
                         result += ", ";
                     }
-                    result += mTargetIds[i];
+                    result += mTargetIds.get(i);
                 }
             }
-            if (mTargets != null) {
-                for (int i = 0; i < mTargets.length; ++i) {
+            if (mTargets.size() > 0) {
+                for (int i = 0; i < mTargets.size(); ++i) {
                     if (i > 0) {
                         result += ", ";
                     }
-                    result += mTargets[i];
+                    result += mTargets.get(i);
                 }
             }
             result += ")";
@@ -1149,11 +1266,11 @@
 
         /**
          * Notification about the cancellation of the transition.
-         * Note that cancel() may be called by a parent {@link TransitionGroup} on
+         * Note that cancel may be called by a parent {@link TransitionSet} on
          * a child transition which has not yet started. This allows the child
          * transition to restore state on target objects which was set at
-         * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)
-         * play()} time.
+         * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)
+         * createAnimator()} time.
          *
          * @param transition The transition which was canceled.
          */
@@ -1161,11 +1278,11 @@
 
         /**
          * Notification when a transition is paused.
-         * Note that play() may be called by a parent {@link TransitionGroup} on
+         * Note that createAnimator() may be called by a parent {@link TransitionSet} on
          * a child transition which has not yet started. This allows the child
          * transition to restore state on target objects which was set at
-         * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)
-         * play()} time.
+         * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)
+         * createAnimator()} time.
          *
          * @param transition The transition which was paused.
          */
@@ -1173,7 +1290,7 @@
 
         /**
          * Notification when a transition is resumed.
-         * Note that resume() may be called by a parent {@link TransitionGroup} on
+         * Note that resume() may be called by a parent {@link TransitionSet} on
          * a child transition which has not yet started. This allows the child
          * transition to restore state which may have changed in an earlier call
          * to {@link #onTransitionPause(Transition)}.
diff --git a/core/java/android/view/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
similarity index 71%
rename from core/java/android/view/transition/TransitionInflater.java
rename to core/java/android/transition/TransitionInflater.java
index be658af..ebedeeb 100644
--- a/core/java/android/view/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -35,6 +35,11 @@
 
 /**
  * This class inflates scenes and transitions from resource files.
+ *
+ * Information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
+ * and {@link android.R.styleable#TransitionManager}.
  */
 public class TransitionInflater {
 
@@ -121,46 +126,12 @@
         }
     }
 
-    /**
-     * Loads a {@link Scene} object from a resource
-     *
-     * @param resource The resource id of the scene to load
-     * @return The loaded Scene object
-     * @throws android.content.res.Resources.NotFoundException when the scene
-     * cannot be loaded
-     */
-    public Scene inflateScene(int resource, ViewGroup parent) {
-        Scene scene = mScenes.get(resource);
-        if (scene != null) {
-            return scene;
-        }
-        XmlResourceParser parser =  mContext.getResources().getXml(resource);
-        try {
-            scene = createSceneFromXml(parser, Xml.asAttributeSet(parser), parent);
-            mScenes.put(resource, scene);
-            return scene;
-        } catch (XmlPullParserException e) {
-            InflateException ex = new InflateException(e.getMessage());
-            ex.initCause(e);
-            throw ex;
-        } catch (IOException e) {
-            InflateException ex = new InflateException(
-                    parser.getPositionDescription()
-                            + ": " + e.getMessage());
-            ex.initCause(e);
-            throw ex;
-        } finally {
-            parser.close();
-        }
-    }
-
-
     //
     // Transition loading
     //
 
     private Transition createTransitionFromXml(XmlPullParser parser,
-            AttributeSet attrs, TransitionGroup transitionGroup)
+            AttributeSet attrs, TransitionSet transitionSet)
             throws XmlPullParserException, IOException {
 
         Transition transition = null;
@@ -180,10 +151,14 @@
 
             String  name = parser.getName();
             if ("fade".equals(name)) {
-                transition = new Fade();
+                TypedArray a = mContext.obtainStyledAttributes(attrs,
+                        com.android.internal.R.styleable.Fade);
+                int fadingMode = a.getInt(com.android.internal.R.styleable.Fade_fadingMode,
+                        Fade.IN | Fade.OUT);
+                transition = new Fade(fadingMode);
                 newTransition = true;
-            } else if ("move".equals(name)) {
-                transition = new Move();
+            } else if ("changeBounds".equals(name)) {
+                transition = new ChangeBounds();
                 newTransition = true;
             } else if ("slide".equals(name)) {
                 transition = new Slide();
@@ -194,24 +169,31 @@
             } else if ("recolor".equals(name)) {
                 transition = new Recolor();
                 newTransition = true;
-            } else if ("transitionGroup".equals(name)) {
-                transition = new TransitionGroup();
-                createTransitionFromXml(parser, attrs, ((TransitionGroup) transition));
+            } else if ("set".equals(name)) {
+                transition = new TransitionSet();
+                TypedArray a = mContext.obtainStyledAttributes(attrs,
+                        com.android.internal.R.styleable.TransitionSet);
+                int ordering = a.getInt(
+                        com.android.internal.R.styleable.TransitionSet_transitionOrdering,
+                        TransitionSet.ORDERING_TOGETHER);
+                ((TransitionSet) transition).setOrdering(ordering);
+                createTransitionFromXml(parser, attrs, ((TransitionSet) transition));
+                a.recycle();
                 newTransition = true;
             } else if ("targets".equals(name)) {
                 if (parser.getDepth() - 1 > depth && transition != null) {
                     // We're inside the child tag - add targets to the child
-                    getTargetIDs(parser, attrs, transition);
-                } else if (parser.getDepth() - 1 == depth && transitionGroup != null) {
-                    // add targets to the group
-                    getTargetIDs(parser, attrs, transitionGroup);
+                    getTargetIds(parser, attrs, transition);
+                } else if (parser.getDepth() - 1 == depth && transitionSet != null) {
+                    // add targets to the set
+                    getTargetIds(parser, attrs, transitionSet);
                 }
             }
             if (transition != null || "targets".equals(name)) {
                 if (newTransition) {
                     loadTransition(transition, attrs);
-                    if (transitionGroup != null) {
-                        transitionGroup.addTransitions(transition);
+                    if (transitionSet != null) {
+                        transitionSet.addTransition(transition);
                     }
                 }
             } else {
@@ -222,7 +204,7 @@
         return transition;
     }
 
-    private void getTargetIDs(XmlPullParser parser,
+    private void getTargetIds(XmlPullParser parser,
             AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException {
 
         // Make sure we are on a start tag.
@@ -240,8 +222,9 @@
             String  name = parser.getName();
             if (name.equals("target")) {
                 TypedArray a = mContext.obtainStyledAttributes(attrs,
-                        com.android.internal.R.styleable.Transition);
-                int id = a.getResourceId(com.android.internal.R.styleable.Transition_targetID, -1);
+                        com.android.internal.R.styleable.TransitionTarget);
+                int id = a.getResourceId(
+                        com.android.internal.R.styleable.TransitionTarget_targetId, -1);
                 if (id >= 0) {
                     targetIds.add(id);
                 }
@@ -251,11 +234,9 @@
         }
         int numTargets = targetIds.size();
         if (numTargets > 0) {
-            int[] targetsArray = new int[numTargets];
-            for (int i = 0; i < targetIds.size(); ++i) {
-                targetsArray[i] = targetIds.get(i);
+            for (int i = 0; i < numTargets; ++i) {
+                transition.addTargetId(targetIds.get(i));
             }
-            transition.setTargetIds(targetsArray);
         }
     }
 
@@ -268,9 +249,9 @@
         if (duration >= 0) {
             transition.setDuration(duration);
         }
-        long startOffset = a.getInt(com.android.internal.R.styleable.Transition_startOffset, -1);
-        if (startOffset > 0) {
-            transition.setStartDelay(startOffset);
+        long startDelay = a.getInt(com.android.internal.R.styleable.Transition_startDelay, -1);
+        if (startDelay > 0) {
+            transition.setStartDelay(startDelay);
         }
         final int resID =
                 a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
@@ -313,20 +294,19 @@
     }
 
     private void loadTransition(AttributeSet attrs, ViewGroup sceneRoot,
-            TransitionManager transitionManager)
-            throws Resources.NotFoundException {
+            TransitionManager transitionManager) throws Resources.NotFoundException {
 
         TypedArray a = mContext.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.TransitionManager);
-        int transitionId = attrs.getAttributeResourceValue(
+        int transitionId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_transition, -1);
         Scene fromScene = null, toScene = null;
-        int fromId = attrs.getAttributeResourceValue(
+        int fromId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_fromScene, -1);
-        if (fromId >= 0) fromScene = inflateScene(fromId, sceneRoot);
-        int toId = attrs.getAttributeResourceValue(
+        if (fromId >= 0) fromScene = Scene.getSceneForLayout(sceneRoot, fromId, mContext);
+        int toId = a.getResourceId(
                 com.android.internal.R.styleable.TransitionManager_toScene, -1);
-        if (toId >= 0) toScene = inflateScene(toId, sceneRoot);
+        if (toId >= 0) toScene = Scene.getSceneForLayout(sceneRoot, toId, mContext);
         if (transitionId >= 0) {
             Transition transition = inflateTransition(transitionId);
             if (transition != null) {
@@ -344,50 +324,4 @@
         }
         a.recycle();
     }
-
-    //
-    // Scene loading
-    //
-
-    private Scene createSceneFromXml(XmlPullParser parser, AttributeSet attrs, ViewGroup parent)
-            throws XmlPullParserException, IOException {
-        Scene scene = null;
-
-        // Make sure we are on a start tag.
-        int type;
-        int depth = parser.getDepth();
-
-        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
-                && type != XmlPullParser.END_DOCUMENT) {
-
-            if (type != XmlPullParser.START_TAG) {
-                continue;
-            }
-
-            String  name = parser.getName();
-            if (name.equals("scene")) {
-                scene = loadScene(attrs, parent);
-            } else {
-                throw new RuntimeException("Unknown scene name: " + parser.getName());
-            }
-        }
-
-        return scene;
-    }
-
-    private Scene loadScene(AttributeSet attrs, ViewGroup parent)
-            throws Resources.NotFoundException {
-
-        Scene scene;
-        TypedArray a = mContext.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Scene);
-        int layoutId = a.getResourceId(com.android.internal.R.styleable.Scene_layout, -1);
-        if (layoutId >= 0) {
-            scene = new Scene(parent, layoutId, mContext);
-        } else {
-            scene = new Scene(parent);
-        }
-        a.recycle();
-        return scene;
-    }
 }
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
similarity index 79%
rename from core/java/android/view/transition/TransitionManager.java
rename to core/java/android/transition/TransitionManager.java
index bde891d..9904413 100644
--- a/core/java/android/view/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
+import android.content.Context;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 
@@ -34,14 +34,36 @@
  * situations. Specifying other transitions for particular scene changes is
  * only necessary if the application wants different transition behavior
  * in these situations.
+ *
+ * <p>TransitionManagers can be declared in XML resource files inside the
+ * <code>res/transition</code> directory. TransitionManager resources consist of
+ * the <code>transitionManager</code>tag name, containing one or more
+ * <code>transition</code> tags, each of which describe the relationship of
+ * that transition to the from/to scene information in that tag.
+ * For example, here is a resource file that declares several scene
+ * transitions:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/transitions_mgr.xml TransitionManager}
+ *
+ * <p>For each of the <code>fromScene</code> and <code>toScene</code> attributes,
+ * there is a reference to a standard XML layout file. This is equivalent to
+ * creating a scene from a layout in code by calling
+ * {@link Scene#getSceneForLayout(ViewGroup, int, Context)}. For the
+ * <code>transition</code> attribute, there is a reference to a resource
+ * file in the <code>res/transition</code> directory which describes that
+ * transition.</p>
+ *
+ * Information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
+ * and {@link android.R.styleable#TransitionManager}.
  */
 public class TransitionManager {
     // TODO: how to handle enter/exit?
 
     private static String LOG_TAG = "TransitionManager";
 
-    private static final Transition sDefaultTransition = new AutoTransition();
-    private Transition mDefaultTransition = new AutoTransition();
+    private static Transition sDefaultTransition = new AutoTransition();
 
     ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
     ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
@@ -59,7 +81,7 @@
      * @param transition The default transition to be used for scene changes.
      */
     public void setDefaultTransition(Transition transition) {
-        mDefaultTransition = transition;
+        sDefaultTransition = transition;
     }
 
     /**
@@ -69,8 +91,8 @@
      * @return The current default transition.
      * @see #setDefaultTransition(Transition)
      */
-    public Transition getDefaultTransition() {
-        return mDefaultTransition;
+    public static Transition getDefaultTransition() {
+        return sDefaultTransition;
     }
 
     /**
@@ -80,7 +102,7 @@
      * transition to run.
      * @param transition The transition that will play when the given scene is
      * entered. A value of null will result in the default behavior of
-     * using {@link AutoTransition}.
+     * using the {@link #getDefaultTransition() default transition} instead.
      */
     public void setTransition(Scene scene, Transition transition) {
         mSceneTransitions.put(scene, transition);
@@ -96,7 +118,7 @@
      * be run
      * @param transition The transition that will play when the given scene is
      * entered. A value of null will result in the default behavior of
-     * using {@link AutoTransition}.
+     * using the {@link #getDefaultTransition() default transition} instead.
      */
     public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
         ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
@@ -114,15 +136,15 @@
      *
      * @param scene The scene being entered
      * @return The Transition to be used for the given scene change. If no
-     * Transition was specified for this scene change, {@link AutoTransition}
-     * will be used instead.
+     * Transition was specified for this scene change, the {@link #getDefaultTransition()
+     * default transition} will be used instead.
      */
     private Transition getTransition(Scene scene) {
         Transition transition = null;
         ViewGroup sceneRoot = scene.getSceneRoot();
         if (sceneRoot != null) {
             // TODO: cached in Scene instead? long-term, cache in View itself
-            Scene currScene = sceneRoot.getCurrentScene();
+            Scene currScene = Scene.getCurrentScene(sceneRoot);
             if (currScene != null) {
                 ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
                 if (sceneTransitionMap != null) {
@@ -134,7 +156,7 @@
             }
         }
         transition = mSceneTransitions.get(scene);
-        return (transition != null) ? transition : new AutoTransition();
+        return (transition != null) ? transition : sDefaultTransition;
     }
 
     /**
@@ -234,7 +256,7 @@
         }
 
         // Notify previous scene that it is being exited
-        Scene previousScene = sceneRoot.getCurrentScene();
+        Scene previousScene = Scene.getCurrentScene(sceneRoot);
         if (previousScene != null) {
             previousScene.exit();
         }
@@ -256,7 +278,7 @@
     }
 
     /**
-     * Static utility method to simply change to the given scene using
+     * Convenience method to simply change to the given scene using
      * the default transition for TransitionManager.
      *
      * @param scene The Scene to change to
@@ -266,15 +288,14 @@
     }
 
     /**
-     * Static utility method to simply change to the given scene using
+     * Convenience method to simply change to the given scene using
      * the given transition.
      *
      * <p>Passing in <code>null</code> for the transition parameter will
      * result in the scene changing without any transition running, and is
      * equivalent to calling {@link Scene#exit()} on the scene root's
-     * {@link ViewGroup#getCurrentScene() current scene}, followed by
-     * {@link Scene#enter()} on the scene specified by the <code>scene</code>
-     * parameter.</p>
+     * current scene, followed by {@link Scene#enter()} on the scene
+     * specified by the <code>scene</code> parameter.</p>
      *
      * @param scene The Scene to change to
      * @param transition The transition to use for this scene change. A
@@ -285,55 +306,20 @@
     }
 
     /**
-     * Static utility method to simply change to a scene defined by the
-     * code in the given runnable, which will be executed after
-     * the current values have been captured for the transition.
-     * This is equivalent to creating a Scene and calling {@link
-     * Scene#setEnterAction(Runnable)} with the runnable, then calling
-     * {@link #go(Scene, Transition)}. The transition used will be the
-     * default provided by TransitionManager.
-     *
-     * @param sceneRoot The root of the View hierarchy used when this scene
-     * runs a transition automatically.
-     * @param action The runnable whose {@link Runnable#run() run()} method will
-     * be called.
-     */
-    public static void go(ViewGroup sceneRoot, Runnable action) {
-        Scene scene = new Scene(sceneRoot);
-        scene.setEnterAction(action);
-        changeScene(scene, sDefaultTransition);
-    }
-
-    /**
-     * Static utility method to simply change to a scene defined by the
-     * code in the given runnable, which will be executed after
-     * the current values have been captured for the transition.
-     * This is equivalent to creating a Scene and calling {@link
-     * Scene#setEnterAction(Runnable)} with the runnable, then calling
-     * {@link #go(Scene, Transition)}. The given transition will be
-     * used to animate the changes.
-     *
-     * <p>Passing in <code>null</code> for the transition parameter will
-     * result in the scene changing without any transition running, and is
-     * equivalent to calling {@link Scene#exit()} on the scene root's
-     * {@link ViewGroup#getCurrentScene() current scene}, followed by
-     * {@link Scene#enter()} on a new scene specified by the
-     * <code>action</code> parameter.</p>
+     * Convenience method to animate, using the default transition,
+     * to a new scene defined by all changes within the given scene root between
+     * calling this method and the next rendering frame.
+     * Equivalent to calling {@link #beginDelayedTransition(ViewGroup, Transition)}
+     * with a value of <code>null</code> for the <code>transition</code> parameter.
      *
      * @param sceneRoot The root of the View hierarchy to run the transition on.
-     * @param action The runnable whose {@link Runnable#run() run()} method will
-     * be called.
-     * @param transition The transition to use for this change. A
-     * value of null causes the change to happen with no transition.
      */
-    public static void go(ViewGroup sceneRoot, Runnable action, Transition transition) {
-        Scene scene = new Scene(sceneRoot);
-        scene.setEnterAction(action);
-        changeScene(scene, transition);
+    public static void beginDelayedTransition(final ViewGroup sceneRoot) {
+        beginDelayedTransition(sceneRoot, null);
     }
 
     /**
-     * Static utility method to animate to a new scene defined by all changes within
+     * Convenience method to animate to a new scene defined by all changes within
      * the given scene root between calling this method and the next rendering frame.
      * Calling this method causes TransitionManager to capture current values in the
      * scene root and then post a request to run a transition on the next frame.
@@ -367,7 +353,7 @@
             }
             final Transition finalTransition = transition.clone();
             sceneChangeSetup(sceneRoot, transition);
-            sceneRoot.setCurrentScene(null);
+            Scene.setCurrentScene(sceneRoot, null);
             sceneChangeRunTransition(sceneRoot, finalTransition);
         }
     }
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
new file mode 100644
index 0000000..1972c2a
--- /dev/null
+++ b/core/java/android/transition/TransitionSet.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.transition;
+
+import android.animation.TimeInterpolator;
+import android.util.AndroidRuntimeException;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+/**
+ * A TransitionSet is a parent of child transitions (including other
+ * TransitionSets). Using TransitionSets enables more complex
+ * choreography of transitions, where some sets play {@link #ORDERING_TOGETHER} and
+ * others play {@link #ORDERING_SEQUENTIAL}. For example, {@link AutoTransition}
+ * uses a TransitionSet to sequentially play a Fade(Fade.OUT), followed by
+ * a {@link ChangeBounds}, followed by a Fade(Fade.OUT) transition.
+ */
+public class TransitionSet extends Transition {
+
+    ArrayList<Transition> mTransitions = new ArrayList<Transition>();
+    private boolean mPlayTogether = true;
+    int mCurrentListeners;
+    boolean mStarted = false;
+
+    /**
+     * A flag used to indicate that the child transitions of this set
+     * should all start at the same time.
+     */
+    public static final int ORDERING_TOGETHER = 0;
+    /**
+     * A flag used to indicate that the child transitions of this set should
+     * play in sequence; when one child transition ends, the next child
+     * transition begins. Note that a transition does not end until all
+     * instances of it (which are playing on all applicable targets of the
+     * transition) end.
+     */
+    public static final int ORDERING_SEQUENTIAL = 1;
+
+    /**
+     * Constructs an empty transition set. Add child transitions to the
+     * set by calling {@link #addTransition(Transition)} )}. By default,
+     * child transitions will play {@link #ORDERING_TOGETHER together}.
+     */
+    public TransitionSet() {
+    }
+
+    /**
+     * Sets the play order of this set's child transitions.
+     *
+     * @param ordering {@link #ORDERING_TOGETHER} to play this set's child
+     * transitions together, {@link #ORDERING_SEQUENTIAL} to play the child
+     * transitions in sequence.
+     * @return This transitionSet object.
+     */
+    public TransitionSet setOrdering(int ordering) {
+        switch (ordering) {
+            case ORDERING_SEQUENTIAL:
+                mPlayTogether = false;
+                break;
+            case ORDERING_TOGETHER:
+                mPlayTogether = true;
+                break;
+            default:
+                throw new AndroidRuntimeException("Invalid parameter for TransitionSet " +
+                        "ordering: " + ordering);
+        }
+        return this;
+    }
+
+    /**
+     * Returns the ordering of this TransitionSet. By default, the value is
+     * {@link #ORDERING_TOGETHER}.
+     *
+     * @return {@link #ORDERING_TOGETHER} if child transitions will play at the same
+     * time, {@link #ORDERING_SEQUENTIAL} if they will play in sequence.
+     *
+     * @see #setOrdering(int)
+     */
+    public int getOrdering() {
+        return mPlayTogether ? ORDERING_TOGETHER : ORDERING_SEQUENTIAL;
+    }
+
+    /**
+     * Adds child transition to this set. The order in which this child transition
+     * is added relative to other child transitions that are added, in addition to
+     * the {@link #getOrdering() ordering} property, determines the
+     * order in which the transitions are started.
+     *
+     * <p>If this transitionSet has a {@link #getDuration() duration} set on it, the
+     * child transition will inherit that duration. Transitions are assumed to have
+     * a maximum of one transitionSet parent.</p>
+     *
+     * @param transition A non-null child transition to be added to this set.
+     * @return This transitionSet object.
+     */
+    public TransitionSet addTransition(Transition transition) {
+        if (transition != null) {
+            mTransitions.add(transition);
+            transition.mParent = this;
+            if (mDuration >= 0) {
+                transition.setDuration(mDuration);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Setting a non-negative duration on a TransitionSet causes all of the child
+     * transitions (current and future) to inherit this duration.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     * @return This transitionSet object.
+     */
+    @Override
+    public TransitionSet setDuration(long duration) {
+        super.setDuration(duration);
+        if (mDuration >= 0) {
+            int numTransitions = mTransitions.size();
+            for (int i = 0; i < numTransitions; ++i) {
+                mTransitions.get(i).setDuration(duration);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public TransitionSet setStartDelay(long startDelay) {
+        return (TransitionSet) super.setStartDelay(startDelay);
+    }
+
+    @Override
+    public TransitionSet setInterpolator(TimeInterpolator interpolator) {
+        return (TransitionSet) super.setInterpolator(interpolator);
+    }
+
+    @Override
+    public TransitionSet addTarget(View target) {
+        return (TransitionSet) super.addTarget(target);
+    }
+
+    @Override
+    public TransitionSet addTargetId(int targetId) {
+        return (TransitionSet) super.addTargetId(targetId);
+    }
+
+    @Override
+    public TransitionSet addListener(TransitionListener listener) {
+        return (TransitionSet) super.addListener(listener);
+    }
+
+    @Override
+    public TransitionSet removeTargetId(int targetId) {
+        return (TransitionSet) super.removeTargetId(targetId);
+    }
+
+    @Override
+    public TransitionSet removeTarget(View target) {
+        return (TransitionSet) super.removeTarget(target);
+    }
+
+    @Override
+    public TransitionSet removeListener(TransitionListener listener) {
+        return (TransitionSet) super.removeListener(listener);
+    }
+
+    /**
+     * Removes the specified child transition from this set.
+     *
+     * @param transition The transition to be removed.
+     * @return This transitionSet object.
+     */
+    public TransitionSet removeTransition(Transition transition) {
+        mTransitions.remove(transition);
+        transition.mParent = null;
+        return this;
+    }
+
+    /**
+     * Sets up listeners for each of the child transitions. This is used to
+     * determine when this transition set is finished (all child transitions
+     * must finish first).
+     */
+    private void setupStartEndListeners() {
+        TransitionSetListener listener = new TransitionSetListener(this);
+        for (Transition childTransition : mTransitions) {
+            childTransition.addListener(listener);
+        }
+        mCurrentListeners = mTransitions.size();
+    }
+
+    /**
+     * This listener is used to detect when all child transitions are done, at
+     * which point this transition set is also done.
+     */
+    static class TransitionSetListener extends TransitionListenerAdapter {
+        TransitionSet mTransitionSet;
+        TransitionSetListener(TransitionSet transitionSet) {
+            mTransitionSet = transitionSet;
+        }
+        @Override
+        public void onTransitionStart(Transition transition) {
+            if (!mTransitionSet.mStarted) {
+                mTransitionSet.start();
+                mTransitionSet.mStarted = true;
+            }
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+            --mTransitionSet.mCurrentListeners;
+            if (mTransitionSet.mCurrentListeners == 0) {
+                // All child trans
+                mTransitionSet.mStarted = false;
+                mTransitionSet.end();
+            }
+            transition.removeListener(this);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+            TransitionValuesMaps endValues) {
+        for (Transition childTransition : mTransitions) {
+            childTransition.createAnimators(sceneRoot, startValues, endValues);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    protected void runAnimators() {
+        setupStartEndListeners();
+        if (!mPlayTogether) {
+            // Setup sequence with listeners
+            // TODO: Need to add listeners in such a way that we can remove them later if canceled
+            for (int i = 1; i < mTransitions.size(); ++i) {
+                Transition previousTransition = mTransitions.get(i - 1);
+                final Transition nextTransition = mTransitions.get(i);
+                previousTransition.addListener(new TransitionListenerAdapter() {
+                    @Override
+                    public void onTransitionEnd(Transition transition) {
+                        nextTransition.runAnimators();
+                        transition.removeListener(this);
+                    }
+                });
+            }
+            Transition firstTransition = mTransitions.get(0);
+            if (firstTransition != null) {
+                firstTransition.runAnimators();
+            }
+        } else {
+            for (Transition childTransition : mTransitions) {
+                childTransition.runAnimators();
+            }
+        }
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        int targetId = transitionValues.view.getId();
+        for (Transition childTransition : mTransitions) {
+            if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+                childTransition.captureStartValues(transitionValues);
+            }
+        }
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        int targetId = transitionValues.view.getId();
+        for (Transition childTransition : mTransitions) {
+            if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+                childTransition.captureEndValues(transitionValues);
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void pause() {
+        super.pause();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).pause();
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void resume() {
+        super.resume();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).resume();
+        }
+    }
+
+    /** @hide */
+    @Override
+    protected void cancel() {
+        super.cancel();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).cancel();
+        }
+    }
+
+    @Override
+    TransitionSet setSceneRoot(ViewGroup sceneRoot) {
+        super.setSceneRoot(sceneRoot);
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).setSceneRoot(sceneRoot);
+        }
+        return (TransitionSet) this;
+    }
+
+    @Override
+    String toString(String indent) {
+        String result = super.toString(indent);
+        for (int i = 0; i < mTransitions.size(); ++i) {
+            result += "\n" + mTransitions.get(i).toString(indent + "  ");
+        }
+        return result;
+    }
+
+    @Override
+    public TransitionSet clone() {
+        TransitionSet clone = (TransitionSet) super.clone();
+        clone.mTransitions = new ArrayList<Transition>();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            clone.mTransitions.add((Transition) mTransitions.get(i).clone());
+        }
+        return clone;
+    }
+
+}
diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/transition/TransitionValues.java
similarity index 93%
rename from core/java/android/view/transition/TransitionValues.java
rename to core/java/android/transition/TransitionValues.java
index 6e5d3d3..8989f89 100644
--- a/core/java/android/view/transition/TransitionValues.java
+++ b/core/java/android/transition/TransitionValues.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.util.ArrayMap;
 import android.view.View;
@@ -33,11 +33,11 @@
  * "Fader" as "android:fader:alpha".
  *
  * <p>These values are cached during the
- * {@link Transition#captureValues(TransitionValues, boolean)}
+ * {@link Transition#captureStartValues(TransitionValues)}
  * capture} phases of a scene change, once when the start values are captured
  * and again when the end values are captured. These start/end values are then
  * passed into the transitions via the
- * for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}
+ * for {@link Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
  * method.</p>
  */
 public class TransitionValues {
diff --git a/core/java/android/view/transition/TransitionValuesMaps.java b/core/java/android/transition/TransitionValuesMaps.java
similarity index 96%
rename from core/java/android/view/transition/TransitionValuesMaps.java
rename to core/java/android/transition/TransitionValuesMaps.java
index 4cfce4d..131596b 100644
--- a/core/java/android/view/transition/TransitionValuesMaps.java
+++ b/core/java/android/transition/TransitionValuesMaps.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.util.ArrayMap;
 import android.util.LongSparseArray;
diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/transition/Visibility.java
similarity index 79%
rename from core/java/android/view/transition/Visibility.java
rename to core/java/android/transition/Visibility.java
index 348dcfb..75d3e7c 100644
--- a/core/java/android/view/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -14,13 +14,11 @@
  * limitations under the License.
  */
 
-package android.view.transition;
+package android.transition;
 
 import android.animation.Animator;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewOverlay;
-import android.view.ViewParent;
 
 /**
  * This transition tracks changes to the visibility of target views in the
@@ -30,13 +28,13 @@
  * utility for subclasses such as {@link Fade}, which use this visibility
  * information to determine the specific animations to run when visibility
  * changes occur. Subclasses should implement one or both of the methods
- * {@link #appear(ViewGroup, TransitionValues, int, TransitionValues, int), and
- * {@link #disappear(ViewGroup, TransitionValues, int, TransitionValues, int)}.
+ * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
  *
  * <p>Note that a view's visibility change is determined by both whether the view
  * itself is changing and whether its parent hierarchy's visibility is changing.
  * That is, a view that appears in the end scene will only trigger a call to
- * {@link #appear(android.view.ViewGroup, TransitionValues, int, TransitionValues, int)
+ * {@link #onAppear(android.view.ViewGroup, TransitionValues, int, TransitionValues, int)
  * appear()} if its parent hierarchy was stable between the start and end scenes.
  * This is done to avoid causing a visibility transition on every node in a hierarchy
  * when only the top-most node is the one that should be transitioned in/out.
@@ -75,11 +73,20 @@
         return sTransitionProperties;
     }
 
+    private void captureValues(TransitionValues transitionValues) {
+        int visibility = transitionValues.view.getVisibility();
+        transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
+        transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
+    }
+
     @Override
-    protected void captureValues(TransitionValues values, boolean start) {
-        int visibility = values.view.getVisibility();
-        values.values.put(PROPNAME_VISIBILITY, visibility);
-        values.values.put(PROPNAME_PARENT, values.view.getParent());
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
     }
 
     /**
@@ -87,7 +94,7 @@
      * object. This is determined by testing the same properties in the values
      * object that are used to determine whether the object is appearing or
      * disappearing in the {@link
-     * #play(android.view.ViewGroup, TransitionValues, TransitionValues)}
+     * Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
      * method. This method can be called by, for example, subclasses that want
      * to know whether the object is visible in the same way that Visibility
      * determines it for the actual animation.
@@ -207,14 +214,14 @@
     }
 
     @Override
-    protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
             TransitionValues endValues) {
         VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
         if (visInfo.visibilityChange) {
             // Only transition views that are either targets of this transition
             // or whose parent hierarchies remain stable between scenes
             boolean isTarget = false;
-            if (mTargets != null || mTargetIds != null) {
+            if (mTargets.size() > 0 || mTargetIds.size() > 0) {
                 View startView = startValues != null ? startValues.view : null;
                 View endView = endValues != null ? endValues.view : null;
                 int startId = startView != null ? startView.getId() : -1;
@@ -225,10 +232,10 @@
                     !isHierarchyVisibilityChanging(sceneRoot,
                             visInfo.startParent, visInfo.endParent))) {
                 if (visInfo.fadeIn) {
-                    return appear(sceneRoot, startValues, visInfo.startVisibility,
+                    return onAppear(sceneRoot, startValues, visInfo.startVisibility,
                             endValues, visInfo.endVisibility);
                 } else {
-                    return disappear(sceneRoot, startValues, visInfo.startVisibility,
+                    return onDisappear(sceneRoot, startValues, visInfo.startVisibility,
                             endValues, visInfo.endVisibility
                     );
                 }
@@ -239,17 +246,20 @@
 
     /**
      * The default implementation of this method does nothing. Subclasses
-     * should override if they need to set up anything prior to the
-     * transition starting.
+     * should override if they need to create an Animator when targets appear.
+     * The method should only be called by the Visibility class; it is
+     * not intended to be called from external classes.
      *
-     * @param sceneRoot
-     * @param startValues
-     * @param startVisibility
-     * @param endValues
-     * @param endVisibility
-     * @return
+     * @param sceneRoot The root of the transition hierarchy
+     * @param startValues The target values in the start scene
+     * @param startVisibility The target visibility in the start scene
+     * @param endValues The target values in the end scene
+     * @param endVisibility The target visibility in the end scene
+     * @return An Animator to be started at the appropriate time in the
+     * overall transition for this scene change. A null value means no animation
+     * should be run.
      */
-    protected Animator appear(ViewGroup sceneRoot,
+    public Animator onAppear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
         return null;
@@ -257,17 +267,21 @@
 
     /**
      * The default implementation of this method does nothing. Subclasses
-     * should override if they need to set up anything prior to the
-     * transition starting.
+     * should override if they need to create an Animator when targets disappear.
+     * The method should only be called by the Visibility class; it is
+     * not intended to be called from external classes.
      *
-     * @param sceneRoot
-     * @param startValues
-     * @param startVisibility
-     * @param endValues
-     * @param endVisibility
-     * @return
+     *
+     * @param sceneRoot The root of the transition hierarchy
+     * @param startValues The target values in the start scene
+     * @param startVisibility The target visibility in the start scene
+     * @param endValues The target values in the end scene
+     * @param endVisibility The target visibility in the end scene
+     * @return An Animator to be started at the appropriate time in the
+     * overall transition for this scene change. A null value means no animation
+     * should be run.
      */
-    protected Animator disappear(ViewGroup sceneRoot,
+    public Animator onDisappear(ViewGroup sceneRoot,
             TransitionValues startValues, int startVisibility,
             TransitionValues endValues, int endVisibility) {
         return null;
diff --git a/core/java/android/view/transition/package.html b/core/java/android/transition/package.html
similarity index 73%
rename from core/java/android/view/transition/package.html
rename to core/java/android/transition/package.html
index 37dc0ec..f357d34 100644
--- a/core/java/android/view/transition/package.html
+++ b/core/java/android/transition/package.html
@@ -3,15 +3,15 @@
 <p>The classes in this package enable "scenes & transitions" functionality for
 view hiearchies.</p>
 
-<p>A <b>Scene</b> is an encapsulation of the state of a view hiearchy,
+<p>A <b>Scene</b> is an encapsulation of the state of a view hierarchy,
 including the views in that hierarchy and the various values (layout-related
-and otherwise) that those views have. A scene be defined by a layout hierarchy
-directly or some code which sets up the scene dynamically as it is entered.</p>
+and otherwise) that those views have. A scene can be defined by a layout hierarchy
+directly or by code which sets up the scene dynamically as it is entered.</p>
 
 <p>A <b>Transition</b> is a mechanism to automatically animate changes that occur
 when a new scene is entered. Some transition capabilities are automatic. That
 is, entering a scene may cause animations to run which fade out views that
-go away, move and resize existing views that change, and fade in views that
+go away, changeBounds and resize existing views that change, and fade in views that
 become visible. There are additional transitions that can animate other
 attributes, such as color changes, and which can optionally be specified
 to take place during particular scene changes. Finally, developers can
@@ -19,7 +19,8 @@
 changes and which run custom animations when those properties change values.</p>
 
 <p><b>TransitionManager</b> is used to specify custom transitions for particular
-scene changes, and to cause scene changes with transitions to take place.</p>
+scene changes, and to cause scene changes with specific transitions to
+take place.</p>
 
 </body>
 </html>
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 28c1058..6bbfe0f 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -323,7 +323,7 @@
 
     /**
      * Creates a GestureDetector with the supplied listener.
-     * You may only use this constructor from a UI thread (this is the usual situation).
+     * You may only use this constructor from a {@link android.os.Looper} thread.
      * @see android.os.Handler#Handler()
      *
      * @param context the application's context
@@ -337,14 +337,14 @@
     }
 
     /**
-     * Creates a GestureDetector with the supplied listener.
-     * You may only use this constructor from a UI thread (this is the usual situation).
+     * Creates a GestureDetector with the supplied listener that runs deferred events on the
+     * thread associated with the supplied {@link android.os.Handler}.
      * @see android.os.Handler#Handler()
      *
      * @param context the application's context
      * @param listener the listener invoked for all the callbacks, this must
      * not be null.
-     * @param handler the handler to use     
+     * @param handler the handler to use for running deferred listener events.
      *
      * @throws NullPointerException if {@code listener} is null.
      */
@@ -362,14 +362,15 @@
     }
     
     /**
-     * Creates a GestureDetector with the supplied listener.
-     * You may only use this constructor from a UI thread (this is the usual situation).
+     * Creates a GestureDetector with the supplied listener that runs deferred events on the
+     * thread associated with the supplied {@link android.os.Handler}.
      * @see android.os.Handler#Handler()
      *
      * @param context the application's context
      * @param listener the listener invoked for all the callbacks, this must
      * not be null.
-     * @param handler the handler to use
+     * @param handler the handler to use for running deferred listener events.
+     * @param unused currently not used.
      *
      * @throws NullPointerException if {@code listener} is null.
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 5b279ec..f2b3e89 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -74,7 +74,6 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
-import android.view.transition.Scene;
 import android.widget.ScrollBarDrawable;
 
 import static android.os.Build.VERSION_CODES.*;
@@ -1575,8 +1574,6 @@
      */
     protected Object mTag;
 
-    private Scene mCurrentScene = null;
-
     // for mPrivateFlags:
     /** {@hide} */
     static final int PFLAG_WANTS_FOCUS                 = 0x00000001;
@@ -8836,9 +8833,11 @@
     /**
      * Change the view's z order in the tree, so it's on top of other sibling
      * views. This ordering change may affect layout, if the parent container
-     * uses an order-dependent layout scheme (e.g., LinearLayout). This
+     * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+     * to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} this
      * method should be followed by calls to {@link #requestLayout()} and
-     * {@link View#invalidate()} on the parent.
+     * {@link View#invalidate()} on the view's parent to force the parent to redraw
+     * with the new child ordering.
      *
      * @see ViewGroup#bringChildToFront(View)
      */
@@ -12187,7 +12186,6 @@
         cleanupDraw();
 
         mCurrentAnimation = null;
-        mCurrentScene = null;
     }
 
     private void cleanupDraw() {
@@ -13256,14 +13254,8 @@
                     // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
                     switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
                         case DRAWING_CACHE_QUALITY_AUTO:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
                         case DRAWING_CACHE_QUALITY_LOW:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
                         case DRAWING_CACHE_QUALITY_HIGH:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
                         default:
                             quality = Bitmap.Config.ARGB_8888;
                             break;
@@ -18106,31 +18098,6 @@
     }
 
     /**
-     * Set the current Scene that this view is in. The current scene is set only
-     * on the root view of a scene, not for every view in that hierarchy. This
-     * information is used by Scene to determine whether there is a previous
-     * scene which should be exited before the new scene is entered.
-     *
-     * @param scene The new scene being set on the view
-     *
-     * @hide
-     */
-    public void setCurrentScene(Scene scene) {
-        mCurrentScene = scene;
-    }
-
-    /**
-     * Gets the current {@link Scene} set on this view. A scene is set on a view
-     * only if that view is the scene root.
-     *
-     * @return The current Scene set on this view. A value of null indicates that
-     * no Scene is current set.
-     */
-    public Scene getCurrentScene() {
-        return mCurrentScene;
-    }
-
-    /**
      * Interface definition for a callback to be invoked when a hardware key event is
      * dispatched to this view. The callback will be invoked before the key event is
      * given to the view. This is only useful for hardware keyboards; a software input
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 03a9c37..2d75b06 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1123,6 +1123,8 @@
             removeFromArray(index);
             addInArray(child, mChildrenCount);
             child.mParent = this;
+            requestLayout();
+            invalidate();
         }
     }
 
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 26596d9..656d756 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -148,9 +148,11 @@
     /**
      * Change the z order of the child so it's on top of all other children.
      * This ordering change may affect layout, if this container
-     * uses an order-dependent layout scheme (e.g., LinearLayout). This
+     * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+     * to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} this
      * method should be followed by calls to {@link #requestLayout()} and
-     * {@link View#invalidate()} on this parent.
+     * {@link View#invalidate()} on this parent to force the parent to redraw
+     * with the new child ordering.
      * 
      * @param child The child to bring to the top of the z order
      */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 354e815..0f9a2ac 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1449,7 +1449,7 @@
                             }
 
                             DisplayList displayList = mView.mDisplayList;
-                            if (displayList != null) {
+                            if (displayList != null && displayList.isValid()) {
                                 layerCanvas.drawDisplayList(displayList, null,
                                         DisplayList.FLAG_CLIP_CHILDREN);
                             } else {
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
deleted file mode 100644
index b3bacde..0000000
--- a/core/java/android/view/transition/TransitionGroup.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.transition;
-
-import android.util.AndroidRuntimeException;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-
-/**
- * A TransitionGroup is a parent of child transitions (including other
- * TransitionGroups). Using TransitionGroups enables more complex
- * choreography of transitions, where some groups play {@link #TOGETHER} and
- * others play {@link #SEQUENTIALLY}. For example, {@link AutoTransition}
- * uses a TransitionGroup to sequentially play a Fade(Fade.OUT), followed by
- * a {@link Move}, followed by a Fade(Fade.OUT) transition.
- */
-public class TransitionGroup extends Transition {
-
-    ArrayList<Transition> mTransitions = new ArrayList<Transition>();
-    private boolean mPlayTogether = true;
-    int mCurrentListeners;
-    boolean mStarted = false;
-
-    /**
-     * A flag used to indicate that the child transitions of this group
-     * should all start at the same time.
-     */
-    public static final int TOGETHER = 0;
-    /**
-     * A flag used to indicate that the child transitions of this group should
-     * play in sequence; when one child transition ends, the next child
-     * transition begins. Note that a transition does not end until all
-     * instances of it (which are playing on all applicable targets of the
-     * transition) end.
-     */
-    public static final int SEQUENTIALLY = 1;
-
-    /**
-     * Constructs an empty transition group. Add child transitions to the
-     * group by calling to {@link #addTransitions(Transition...)} )}. By default,
-     * child transitions will play {@link #TOGETHER}.
-     */
-    public TransitionGroup() {
-    }
-
-    /**
-     * Constructs an empty transition group with the specified ordering.
-     *
-     * @param ordering {@link #TOGETHER} to start this group's child
-     * transitions together, {@link #SEQUENTIALLY} to play the child
-     * transitions in sequence.
-     * @see #setOrdering(int)
-     */
-    public TransitionGroup(int ordering) {
-        setOrdering(ordering);
-    }
-
-    /**
-     * Sets the play order of this group's child transitions.
-     *
-     * @param ordering {@link #TOGETHER} to start this group's child
-     * transitions together, {@link #SEQUENTIALLY} to play the child
-     * transitions in sequence.
-     */
-    public void setOrdering(int ordering) {
-        switch (ordering) {
-            case SEQUENTIALLY:
-                mPlayTogether = false;
-                break;
-            case TOGETHER:
-                mPlayTogether = true;
-                break;
-            default:
-                throw new AndroidRuntimeException("Invalid parameter for TransitionGroup " +
-                        "ordering: " + ordering);
-        }
-    }
-
-    /**
-     * Adds child transitions to this group. The order of the child transitions
-     * passed in determines the order in which they are started.
-     *
-     * @param transitions A list of child transition to be added to this group.
-     */
-    public void addTransitions(Transition... transitions) {
-        if (transitions != null) {
-            int numTransitions = transitions.length;
-            for (int i = 0; i < numTransitions; ++i) {
-                mTransitions.add(transitions[i]);
-                transitions[i].mParent = this;
-                if (mDuration >= 0) {
-                    transitions[i].setDuration(mDuration);
-                }
-            }
-        }
-    }
-
-    /**
-     * Setting a non-negative duration on a TransitionGroup causes all of the child
-     * transitions (current and future) to inherit this duration.
-     *
-     * @param duration The length of the animation, in milliseconds.
-     * @return This transitionGroup object.
-     */
-    @Override
-    public Transition setDuration(long duration) {
-        super.setDuration(duration);
-        if (mDuration >= 0) {
-            int numTransitions = mTransitions.size();
-            for (int i = 0; i < numTransitions; ++i) {
-                mTransitions.get(i).setDuration(duration);
-            }
-        }
-        return this;
-    }
-
-    /**
-     * Removes the specified child transition from this group.
-     *
-     * @param transition The transition to be removed.
-     */
-    public void removeTransition(Transition transition) {
-        mTransitions.remove(transition);
-        transition.mParent = null;
-    }
-
-    /**
-     * Sets up listeners for each of the child transitions. This is used to
-     * determine when this transition group is finished (all child transitions
-     * must finish first).
-     */
-    private void setupStartEndListeners() {
-        TransitionGroupListener listener = new TransitionGroupListener(this);
-        for (Transition childTransition : mTransitions) {
-            childTransition.addListener(listener);
-        }
-        mCurrentListeners = mTransitions.size();
-    }
-
-    /**
-     * This listener is used to detect when all child transitions are done, at
-     * which point this transition group is also done.
-     */
-    static class TransitionGroupListener extends TransitionListenerAdapter {
-        TransitionGroup mTransitionGroup;
-        TransitionGroupListener(TransitionGroup transitionGroup) {
-            mTransitionGroup = transitionGroup;
-        }
-        @Override
-        public void onTransitionStart(Transition transition) {
-            if (!mTransitionGroup.mStarted) {
-                mTransitionGroup.start();
-                mTransitionGroup.mStarted = true;
-            }
-        }
-
-        @Override
-        public void onTransitionEnd(Transition transition) {
-            --mTransitionGroup.mCurrentListeners;
-            if (mTransitionGroup.mCurrentListeners == 0) {
-                // All child trans
-                mTransitionGroup.mStarted = false;
-                mTransitionGroup.end();
-            }
-            transition.removeListener(this);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
-            TransitionValuesMaps endValues) {
-        for (Transition childTransition : mTransitions) {
-            childTransition.play(sceneRoot, startValues, endValues);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    protected void runAnimations() {
-        setupStartEndListeners();
-        if (!mPlayTogether) {
-            // Setup sequence with listeners
-            // TODO: Need to add listeners in such a way that we can remove them later if canceled
-            for (int i = 1; i < mTransitions.size(); ++i) {
-                Transition previousTransition = mTransitions.get(i - 1);
-                final Transition nextTransition = mTransitions.get(i);
-                previousTransition.addListener(new TransitionListenerAdapter() {
-                    @Override
-                    public void onTransitionEnd(Transition transition) {
-                        nextTransition.runAnimations();
-                        transition.removeListener(this);
-                    }
-                });
-            }
-            Transition firstTransition = mTransitions.get(0);
-            if (firstTransition != null) {
-                firstTransition.runAnimations();
-            }
-        } else {
-            for (Transition childTransition : mTransitions) {
-                childTransition.runAnimations();
-            }
-        }
-    }
-
-    @Override
-    protected void captureValues(TransitionValues transitionValues, boolean start) {
-        int targetId = transitionValues.view.getId();
-        for (Transition childTransition : mTransitions) {
-            if (childTransition.isValidTarget(transitionValues.view, targetId)) {
-                childTransition.captureValues(transitionValues, start);
-            }
-        }
-    }
-
-    /** @hide */
-    @Override
-    public void pause() {
-        super.pause();
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).pause();
-        }
-    }
-
-    /** @hide */
-    @Override
-    public void resume() {
-        super.resume();
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).resume();
-        }
-    }
-
-    @Override
-    protected void cancel() {
-        super.cancel();
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).cancel();
-        }
-    }
-
-    @Override
-    void setSceneRoot(ViewGroup sceneRoot) {
-        super.setSceneRoot(sceneRoot);
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).setSceneRoot(sceneRoot);
-        }
-    }
-
-    @Override
-    String toString(String indent) {
-        String result = super.toString(indent);
-        for (int i = 0; i < mTransitions.size(); ++i) {
-            result += "\n" + mTransitions.get(i).toString(indent + "  ");
-        }
-        return result;
-    }
-
-    @Override
-    public TransitionGroup clone() {
-        TransitionGroup clone = (TransitionGroup) super.clone();
-        clone.mTransitions = new ArrayList<Transition>();
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; ++i) {
-            clone.mTransitions.add((Transition) mTransitions.get(i).clone());
-        }
-        return clone;
-    }
-
-}
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index fea6be6..7707392 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -50,7 +50,9 @@
  */
 class CallbackProxy extends Handler {
     // Logging tag
-    private static final String LOGTAG = "CallbackProxy";
+    static final String LOGTAG = "WebViewCallback";
+    // Enables API callback tracing
+    private static final boolean TRACE = DebugFlags.TRACE_CALLBACK;
     // Instance of WebViewClient that is the client callback.
     private volatile WebViewClient mWebViewClient;
     // Instance of WebChromeClient for handling all chrome functions.
@@ -258,6 +260,7 @@
         }
         boolean override = false;
         if (mWebViewClient != null) {
+            if (TRACE) Log.d(LOGTAG, "shouldOverrideUrlLoading=" + overrideUrl);
             override = mWebViewClient.shouldOverrideUrlLoading(mWebView.getWebView(),
                     overrideUrl);
         } else {
@@ -307,6 +310,7 @@
                 String startedUrl = msg.getData().getString("url");
                 mWebView.onPageStarted(startedUrl);
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onPageStarted=" + startedUrl);
                     mWebViewClient.onPageStarted(mWebView.getWebView(), startedUrl,
                             (Bitmap) msg.obj);
                 }
@@ -316,18 +320,21 @@
                 String finishedUrl = (String) msg.obj;
                 mWebView.onPageFinished(finishedUrl);
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onPageFinished=" + finishedUrl);
                     mWebViewClient.onPageFinished(mWebView.getWebView(), finishedUrl);
                 }
                 break;
 
             case RECEIVED_ICON:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedIcon");
                     mWebChromeClient.onReceivedIcon(mWebView.getWebView(), (Bitmap) msg.obj);
                 }
                 break;
 
             case RECEIVED_TOUCH_ICON_URL:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedTouchIconUrl");
                     mWebChromeClient.onReceivedTouchIconUrl(mWebView.getWebView(),
                             (String) msg.obj, msg.arg1 == 1);
                 }
@@ -335,6 +342,7 @@
 
             case RECEIVED_TITLE:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedTitle");
                     mWebChromeClient.onReceivedTitle(mWebView.getWebView(),
                             (String) msg.obj);
                 }
@@ -345,6 +353,7 @@
                     int reasonCode = msg.arg1;
                     final String description  = msg.getData().getString("description");
                     final String failUrl  = msg.getData().getString("failingUrl");
+                    if (TRACE) Log.d(LOGTAG, "onReceivedError=" + failUrl);
                     mWebViewClient.onReceivedError(mWebView.getWebView(), reasonCode,
                             description, failUrl);
                 }
@@ -356,6 +365,7 @@
                 Message dontResend =
                         (Message) msg.getData().getParcelable("dontResend");
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onFormResubmission");
                     mWebViewClient.onFormResubmission(mWebView.getWebView(), dontResend,
                             resend);
                 } else {
@@ -379,6 +389,7 @@
                     HttpAuthHandler handler = (HttpAuthHandler) msg.obj;
                     String host = msg.getData().getString("host");
                     String realm = msg.getData().getString("realm");
+                    if (TRACE) Log.d(LOGTAG, "onReceivedHttpAuthRequest");
                     mWebViewClient.onReceivedHttpAuthRequest(mWebView.getWebView(), handler,
                             host, realm);
                 }
@@ -388,6 +399,7 @@
                 if (mWebViewClient != null) {
                     HashMap<String, Object> map =
                         (HashMap<String, Object>) msg.obj;
+                    if (TRACE) Log.d(LOGTAG, "onReceivedSslError");
                     mWebViewClient.onReceivedSslError(mWebView.getWebView(),
                             (SslErrorHandler) map.get("handler"),
                             (SslError) map.get("error"));
@@ -396,6 +408,7 @@
 
             case PROCEEDED_AFTER_SSL_ERROR:
                 if (mWebViewClient != null && mWebViewClient instanceof WebViewClientClassicExt) {
+                    if (TRACE) Log.d(LOGTAG, "onProceededAfterSslError");
                     ((WebViewClientClassicExt) mWebViewClient).onProceededAfterSslError(
                             mWebView.getWebView(),
                             (SslError) msg.obj);
@@ -404,6 +417,7 @@
 
             case CLIENT_CERT_REQUEST:
                 if (mWebViewClient != null  && mWebViewClient instanceof WebViewClientClassicExt) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedClientCertRequest");
                     HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;
                     ((WebViewClientClassicExt) mWebViewClient).onReceivedClientCertRequest(
                             mWebView.getWebView(),
@@ -418,6 +432,7 @@
                 // changed.
                 synchronized (this) {
                     if (mWebChromeClient != null) {
+                        if (TRACE) Log.d(LOGTAG, "onProgressChanged=" + mLatestProgress);
                         mWebChromeClient.onProgressChanged(mWebView.getWebView(),
                                 mLatestProgress);
                     }
@@ -427,14 +442,18 @@
 
             case UPDATE_VISITED:
                 if (mWebViewClient != null) {
+                    String url = (String) msg.obj;
+                    if (TRACE) Log.d(LOGTAG, "doUpdateVisitedHistory=" + url);
                     mWebViewClient.doUpdateVisitedHistory(mWebView.getWebView(),
-                            (String) msg.obj, msg.arg1 != 0);
+                            url, msg.arg1 != 0);
                 }
                 break;
 
             case LOAD_RESOURCE:
                 if (mWebViewClient != null) {
-                    mWebViewClient.onLoadResource(mWebView.getWebView(), (String) msg.obj);
+                    String url = (String) msg.obj;
+                    if (TRACE) Log.d(LOGTAG, "onLoadResource=" + url);
+                    mWebViewClient.onLoadResource(mWebView.getWebView(), url);
                 }
                 break;
 
@@ -448,6 +467,7 @@
                     String referer = msg.getData().getString("referer");
                     Long contentLength = msg.getData().getLong("contentLength");
 
+                    if (TRACE) Log.d(LOGTAG, "onDownloadStart");
                     if (mDownloadListener instanceof BrowserDownloadListener) {
                         ((BrowserDownloadListener) mDownloadListener).onDownloadStart(url,
                              userAgent, contentDisposition, mimetype, referer, contentLength);
@@ -460,6 +480,7 @@
 
             case CREATE_WINDOW:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onCreateWindow");
                     if (!mWebChromeClient.onCreateWindow(mWebView.getWebView(),
                                 msg.arg1 == 1, msg.arg2 == 1,
                                 (Message) msg.obj)) {
@@ -473,12 +494,14 @@
 
             case REQUEST_FOCUS:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onRequestFocus");
                     mWebChromeClient.onRequestFocus(mWebView.getWebView());
                 }
                 break;
 
             case CLOSE_WINDOW:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onCloseWindow");
                     mWebChromeClient.onCloseWindow(((WebViewClassic) msg.obj).getWebView());
                 }
                 break;
@@ -500,6 +523,7 @@
 
             case ASYNC_KEYEVENTS:
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onUnhandledKeyEvent");
                     mWebViewClient.onUnhandledKeyEvent(mWebView.getWebView(),
                             (KeyEvent) msg.obj);
                 }
@@ -521,6 +545,7 @@
                     WebStorage.QuotaUpdater quotaUpdater =
                         (WebStorage.QuotaUpdater) map.get("quotaUpdater");
 
+                    if (TRACE) Log.d(LOGTAG, "onExceededDatabaseQuota");
                     mWebChromeClient.onExceededDatabaseQuota(url,
                             databaseIdentifier, quota, estimatedDatabaseSize,
                             totalQuota, quotaUpdater);
@@ -538,6 +563,7 @@
                     WebStorage.QuotaUpdater quotaUpdater =
                         (WebStorage.QuotaUpdater) map.get("quotaUpdater");
 
+                    if (TRACE) Log.d(LOGTAG, "onReachedMaxAppCacheSize");
                     mWebChromeClient.onReachedMaxAppCacheSize(requiredStorage,
                             quota, quotaUpdater);
                 }
@@ -551,6 +577,7 @@
                     GeolocationPermissions.Callback callback =
                             (GeolocationPermissions.Callback)
                             map.get("callback");
+                    if (TRACE) Log.d(LOGTAG, "onGeolocationPermissionsShowPrompt");
                     mWebChromeClient.onGeolocationPermissionsShowPrompt(origin,
                             callback);
                 }
@@ -558,6 +585,7 @@
 
             case GEOLOCATION_PERMISSIONS_HIDE_PROMPT:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onGeolocationPermissionsHidePrompt");
                     mWebChromeClient.onGeolocationPermissionsHidePrompt();
                 }
                 break;
@@ -566,6 +594,7 @@
                 if (mWebChromeClient != null) {
                     final JsResultReceiver receiver = (JsResultReceiver) msg.obj;
                     JsDialogHelper helper = new JsDialogHelper(receiver.mJsResult, msg);
+                    if (TRACE) Log.d(LOGTAG, "onJsAlert");
                     if (!helper.invokeCallback(mWebChromeClient, mWebView.getWebView())) {
                         helper.showDialog(mContext);
                     }
@@ -577,6 +606,7 @@
                 if(mWebChromeClient != null) {
                     final JsResultReceiver receiver = (JsResultReceiver) msg.obj;
                     final JsResult res = receiver.mJsResult;
+                    if (TRACE) Log.d(LOGTAG, "onJsTimeout");
                     if (mWebChromeClient.onJsTimeout()) {
                         res.confirm();
                     } else {
@@ -598,6 +628,7 @@
 
             case SCALE_CHANGED:
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onScaleChanged");
                     mWebViewClient.onScaleChanged(mWebView.getWebView(), msg.getData()
                             .getFloat("old"), msg.getData().getFloat("new"));
                 }
@@ -624,6 +655,7 @@
                 ConsoleMessage.MessageLevel messageLevel =
                         ConsoleMessage.MessageLevel.values()[msgLevel];
 
+                if (TRACE) Log.d(LOGTAG, "onConsoleMessage");
                 if (!mWebChromeClient.onConsoleMessage(new ConsoleMessage(message, sourceID,
                         lineNumber, messageLevel))) {
                     // If false was returned the user did not provide their own console function so
@@ -654,12 +686,14 @@
 
             case GET_VISITED_HISTORY:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "getVisitedHistory");
                     mWebChromeClient.getVisitedHistory((ValueCallback<String[]>)msg.obj);
                 }
                 break;
 
             case OPEN_FILE_CHOOSER:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "openFileChooser");
                     UploadFileMessageData data = (UploadFileMessageData)msg.obj;
                     mWebChromeClient.openFileChooser(data.getUploadFile(), data.getAcceptType(),
                             data.getCapture());
@@ -668,6 +702,7 @@
 
             case ADD_HISTORY_ITEM:
                 if (mWebBackForwardListClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onNewHistoryItem");
                     mWebBackForwardListClient.onNewHistoryItem(
                             (WebHistoryItem) msg.obj);
                 }
@@ -693,6 +728,7 @@
                     String realm = msg.getData().getString("realm");
                     String account = msg.getData().getString("account");
                     String args = msg.getData().getString("args");
+                    if (TRACE) Log.d(LOGTAG, "onReceivedLoginRequest");
                     mWebViewClient.onReceivedLoginRequest(mWebView.getWebView(), realm,
                             account, args);
                 }
@@ -910,6 +946,7 @@
             return null;
         }
         // Note: This method does _not_ send a message.
+        if (TRACE) Log.d(LOGTAG, "shouldInterceptRequest=" + url);
         WebResourceResponse r =
                 mWebViewClient.shouldInterceptRequest(mWebView.getWebView(), url);
         if (r == null) {
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 349113e..524f610 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -24,25 +24,33 @@
  * The name of each flags maps directly to the name of the class in which that
  * flag is used.
  *
+ * @hide Only used by WebView implementations.
  */
-class DebugFlags {
+public class DebugFlags {
 
+    public static final boolean COOKIE_SYNC_MANAGER = false;
+    public static final boolean TRACE_API = false;
+    public static final boolean TRACE_CALLBACK = false;
+    public static final boolean TRACE_JAVASCRIPT_BRIDGE = false;
+    public static final boolean URL_UTIL = false;
+    public static final boolean WEB_SYNC_MANAGER = false;
+
+    // TODO: Delete these when WebViewClassic is moved
     public static final boolean BROWSER_FRAME = false;
     public static final boolean CACHE_MANAGER = false;
     public static final boolean CALLBACK_PROXY = false;
     public static final boolean COOKIE_MANAGER = false;
-    public static final boolean COOKIE_SYNC_MANAGER = false;
     public static final boolean FRAME_LOADER = false;
     public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
     public static final boolean LOAD_LISTENER = false;
+    public static final boolean MEASURE_PAGE_SWAP_FPS = false;
     public static final boolean NETWORK = false;
     public static final boolean SSL_ERROR_HANDLER = false;
     public static final boolean STREAM_LOADER = false;
-    public static final boolean URL_UTIL = false;
     public static final boolean WEB_BACK_FORWARD_LIST = false;
     public static final boolean WEB_SETTINGS = false;
-    public static final boolean WEB_SYNC_MANAGER = false;
     public static final boolean WEB_VIEW = false;
     public static final boolean WEB_VIEW_CORE = false;
-    public static final boolean MEASURE_PAGE_SWAP_FPS = false;
+
+
 }
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index b52218d..6fb32c8 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.media.MediaPlayer;
 import android.media.Metadata;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
@@ -293,12 +294,16 @@
         mLayout.setVisibility(View.VISIBLE);
         WebChromeClient client = webView.getWebChromeClient();
         if (client != null) {
+            if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onShowCustomView");
             client.onShowCustomView(mLayout, mCallback);
             // Plugins like Flash will draw over the video so hide
             // them while we're playing.
             if (webView.getViewManager() != null)
                 webView.getViewManager().hideAll();
 
+            if (DebugFlags.TRACE_CALLBACK) {
+                Log.d(CallbackProxy.LOGTAG, "getVideoLoadingProgressView");
+            }
             mProgressView = client.getVideoLoadingProgressView();
             if (mProgressView != null) {
                 mLayout.addView(mProgressView, layoutParams);
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index a3d62ae..e8538f6 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -180,6 +180,7 @@
             if (!mHTML5VideoView.fullScreenExited() && mHTML5VideoView.isFullScreenMode()) {
                 WebChromeClient client = webView.getWebChromeClient();
                 if (client != null) {
+                    if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onHideCustomView");
                     client.onHideCustomView();
                 }
             }
@@ -405,6 +406,7 @@
             case ERROR: {
                 WebChromeClient client = mWebView.getWebChromeClient();
                 if (client != null) {
+                    if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onHideCustomView");
                     client.onHideCustomView();
                 }
                 break;
@@ -412,6 +414,9 @@
             case LOAD_DEFAULT_POSTER: {
                 WebChromeClient client = mWebView.getWebChromeClient();
                 if (client != null) {
+                    if (DebugFlags.TRACE_CALLBACK) {
+                        Log.d(CallbackProxy.LOGTAG, "getDefaultVideoPoster");
+                    }
                     doSetPoster(client.getDefaultVideoPoster());
                 }
                 break;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index eded438..f0e8c4f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -244,7 +244,7 @@
         implements ViewTreeObserver.OnGlobalFocusChangeListener,
         ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
 
-    private static final String LOGTAG = "webview_proxy";
+    private static final String LOGTAG = "WebView";
 
     // Throwing an exception for incorrect thread usage if the
     // build target is JB MR2 or newer. Defaults to false, and is
@@ -496,6 +496,7 @@
         sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
                 Build.VERSION_CODES.JELLY_BEAN_MR2;
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "WebView<init>");
 
         ensureProviderCreated();
         mProvider.init(javaScriptInterfaces, privateBrowsing);
@@ -510,6 +511,7 @@
      */
     public void setHorizontalScrollbarOverlay(boolean overlay) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHorizontalScrollbarOverlay=" + overlay);
         mProvider.setHorizontalScrollbarOverlay(overlay);
     }
 
@@ -520,6 +522,7 @@
      */
     public void setVerticalScrollbarOverlay(boolean overlay) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setVerticalScrollbarOverlay=" + overlay);
         mProvider.setVerticalScrollbarOverlay(overlay);
     }
 
@@ -574,6 +577,7 @@
     @Deprecated
     public void setCertificate(SslCertificate certificate) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setCertificate=" + certificate);
         mProvider.setCertificate(certificate);
     }
 
@@ -597,6 +601,7 @@
     @Deprecated
     public void savePassword(String host, String username, String password) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePassword=" + host);
         mProvider.savePassword(host, username, password);
     }
 
@@ -616,6 +621,7 @@
     public void setHttpAuthUsernamePassword(String host, String realm,
             String username, String password) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHttpAuthUsernamePassword=" + host);
         mProvider.setHttpAuthUsernamePassword(host, realm, username, password);
     }
 
@@ -645,6 +651,7 @@
      */
     public void destroy() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "destroy");
         mProvider.destroy();
     }
 
@@ -683,6 +690,7 @@
      */
     public void setNetworkAvailable(boolean networkUp) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setNetworkAvailable=" + networkUp);
         mProvider.setNetworkAvailable(networkUp);
     }
 
@@ -699,6 +707,7 @@
      */
     public WebBackForwardList saveState(Bundle outState) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveState");
         return mProvider.saveState(outState);
     }
 
@@ -715,6 +724,7 @@
     @Deprecated
     public boolean savePicture(Bundle b, final File dest) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePicture=" + dest.getName());
         return mProvider.savePicture(b, dest);
     }
 
@@ -732,6 +742,7 @@
     @Deprecated
     public boolean restorePicture(Bundle b, File src) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restorePicture=" + src.getName());
         return mProvider.restorePicture(b, src);
     }
 
@@ -749,6 +760,7 @@
      */
     public WebBackForwardList restoreState(Bundle inState) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restoreState");
         return mProvider.restoreState(inState);
     }
 
@@ -765,6 +777,7 @@
      */
     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl(extra headers)=" + url);
         mProvider.loadUrl(url, additionalHttpHeaders);
     }
 
@@ -775,6 +788,7 @@
      */
     public void loadUrl(String url) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl=" + url);
         mProvider.loadUrl(url);
     }
 
@@ -789,6 +803,7 @@
      */
     public void postUrl(String url, byte[] postData) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "postUrl=" + url);
         mProvider.postUrl(url, postData);
     }
 
@@ -823,6 +838,7 @@
      */
     public void loadData(String data, String mimeType, String encoding) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadData");
         mProvider.loadData(data, mimeType, encoding);
     }
 
@@ -855,6 +871,7 @@
     public void loadDataWithBaseURL(String baseUrl, String data,
             String mimeType, String encoding, String historyUrl) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
         mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
     }
 
@@ -871,6 +888,7 @@
      */
     public void evaluateJavascript(String script, ValueCallback<String> resultCallback) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "evaluateJavascript=" + script);
         mProvider.evaluateJavaScript(script, resultCallback);
     }
 
@@ -881,6 +899,7 @@
      */
     public void saveWebArchive(String filename) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive=" + filename);
         mProvider.saveWebArchive(filename);
     }
 
@@ -898,6 +917,7 @@
      */
     public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive(auto)=" + basename);
         mProvider.saveWebArchive(basename, autoname, callback);
     }
 
@@ -906,6 +926,7 @@
      */
     public void stopLoading() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "stopLoading");
         mProvider.stopLoading();
     }
 
@@ -914,6 +935,7 @@
      */
     public void reload() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "reload");
         mProvider.reload();
     }
 
@@ -932,6 +954,7 @@
      */
     public void goBack() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBack");
         mProvider.goBack();
     }
 
@@ -950,6 +973,7 @@
      */
     public void goForward() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goForward");
         mProvider.goForward();
     }
 
@@ -975,6 +999,7 @@
      */
     public void goBackOrForward(int steps) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBackOrForwad=" + steps);
         mProvider.goBackOrForward(steps);
     }
 
@@ -994,6 +1019,7 @@
      */
     public boolean pageUp(boolean top) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageUp");
         return mProvider.pageUp(top);
     }
 
@@ -1005,6 +1031,7 @@
      */
     public boolean pageDown(boolean bottom) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageDown");
         return mProvider.pageDown(bottom);
     }
 
@@ -1017,6 +1044,7 @@
     @Deprecated
     public void clearView() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearView");
         mProvider.clearView();
     }
 
@@ -1036,6 +1064,7 @@
      */
     public Picture capturePicture() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "capturePicture");
         return mProvider.capturePicture();
     }
 
@@ -1073,6 +1102,7 @@
             ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
             throws java.io.IOException {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "exportToPdf");
         mProvider.exportToPdf(fd, attributes, resultCallback, cancellationSignal);
     }
 
@@ -1104,6 +1134,7 @@
      */
     public void setInitialScale(int scaleInPercent) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setInitialScale=" + scaleInPercent);
         mProvider.setInitialScale(scaleInPercent);
     }
 
@@ -1114,6 +1145,7 @@
      */
     public void invokeZoomPicker() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "invokeZoomPicker");
         mProvider.invokeZoomPicker();
     }
 
@@ -1137,6 +1169,7 @@
      */
     public HitTestResult getHitTestResult() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "getHitTestResult");
         return mProvider.getHitTestResult();
     }
 
@@ -1155,6 +1188,7 @@
      */
     public void requestFocusNodeHref(Message hrefMsg) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestFocusNodeHref");
         mProvider.requestFocusNodeHref(hrefMsg);
     }
 
@@ -1167,6 +1201,7 @@
      */
     public void requestImageRef(Message msg) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestImageRef");
         mProvider.requestImageRef(msg);
     }
 
@@ -1271,6 +1306,7 @@
      */
     public void pauseTimers() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pauseTimers");
         mProvider.pauseTimers();
     }
 
@@ -1280,6 +1316,7 @@
      */
     public void resumeTimers() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "resumeTimers");
         mProvider.resumeTimers();
     }
 
@@ -1292,6 +1329,7 @@
      */
     public void onPause() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onPause");
         mProvider.onPause();
     }
 
@@ -1300,6 +1338,7 @@
      */
     public void onResume() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onResume");
         mProvider.onResume();
     }
 
@@ -1319,6 +1358,7 @@
      */
     public void freeMemory() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "freeMemory");
         mProvider.freeMemory();
     }
 
@@ -1330,6 +1370,7 @@
      */
     public void clearCache(boolean includeDiskFiles) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearCache");
         mProvider.clearCache(includeDiskFiles);
     }
 
@@ -1341,6 +1382,7 @@
      */
     public void clearFormData() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearFormData");
         mProvider.clearFormData();
     }
 
@@ -1349,6 +1391,7 @@
      */
     public void clearHistory() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearHistory");
         mProvider.clearHistory();
     }
 
@@ -1358,6 +1401,7 @@
      */
     public void clearSslPreferences() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearSslPreferences");
         mProvider.clearSslPreferences();
     }
 
@@ -1399,6 +1443,7 @@
      */
     public void findNext(boolean forward) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findNext");
         mProvider.findNext(forward);
     }
 
@@ -1414,6 +1459,7 @@
     @Deprecated
     public int findAll(String find) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAll");
         StrictMode.noteSlowCall("findAll blocks UI: prefer findAllAsync");
         return mProvider.findAll(find);
     }
@@ -1428,6 +1474,7 @@
      */
     public void findAllAsync(String find) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAllAsync");
         mProvider.findAllAsync(find);
     }
 
@@ -1448,6 +1495,7 @@
     @Deprecated
     public boolean showFindDialog(String text, boolean showIme) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "showFindDialog");
         return mProvider.showFindDialog(text, showIme);
     }
 
@@ -1483,6 +1531,7 @@
      */
     public void clearMatches() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearMatches");
         mProvider.clearMatches();
     }
 
@@ -1543,6 +1592,7 @@
     @Deprecated
     public void setPictureListener(PictureListener listener) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setPictureListener=" + listener);
         mProvider.setPictureListener(listener);
     }
 
@@ -1592,6 +1642,7 @@
      */
     public void addJavascriptInterface(Object object, String name) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "addJavascriptInterface=" + name);
         mProvider.addJavascriptInterface(object, name);
     }
 
@@ -1604,6 +1655,7 @@
      */
     public void removeJavascriptInterface(String name) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "removeJavascriptInterface=" + name);
         mProvider.removeJavascriptInterface(name);
     }
 
@@ -1693,6 +1745,7 @@
 
     public void flingScroll(int vx, int vy) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "flingScroll");
         mProvider.flingScroll(vx, vy);
     }
 
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index b1a7878..3f22d53 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -7951,6 +7951,7 @@
             // triggered in setNewPicture
             Picture picture = mContext.getApplicationInfo().targetSdkVersion <
                     Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
+            if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onNewPicture");
             mPictureListener.onNewPicture(getWebView(), picture);
         }
     }
@@ -8038,6 +8039,7 @@
                 // triggered in pageSwapCallback
                 Picture picture = mContext.getApplicationInfo().targetSdkVersion <
                         Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
+                if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onNewPicture");
                 mPictureListener.onNewPicture(getWebView(), picture);
             }
         }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index be47bf0..c308024 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4924,11 +4924,37 @@
      * Scrolls the list items within the view by a specified number of pixels.
      *
      * @param y the amount of pixels to scroll by vertically
-     * @return true if the list is able to scroll, or false if the list is
-     *         already at the beginning/end and unable to scroll any more.
+     * @see #canScrollList(int)
      */
-    public boolean scrollListBy(int y) {
-        return !trackMotionScroll(-y, -y);
+    public void scrollListBy(int y) {
+        trackMotionScroll(-y, -y);
+    }
+
+    /**
+     * Check if the items in the list can be scrolled in a certain direction.
+     *
+     * @param direction Negative to check scrolling up, positive to check
+     *            scrolling down.
+     * @return true if the list can be scrolled in the specified direction,
+     *         false otherwise.
+     * @see #scrollListBy(int)
+     */
+    public boolean canScrollList(int direction) {
+        final int childCount = getChildCount();
+        if (childCount == 0) {
+            return false;
+        }
+
+        final int firstPosition = mFirstPosition;
+        final Rect listPadding = mListPadding;
+        if (direction > 0) {
+            final int lastBottom = getChildAt(childCount - 1).getBottom();
+            final int lastPosition = firstPosition + childCount;
+            return lastPosition < mItemCount || lastBottom > getHeight() - listPadding.bottom;
+        } else {
+            final int firstTop = getChildAt(0).getTop();
+            return firstPosition > 0 || firstTop < listPadding.top;
+        }
     }
 
     /**
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 778c8db..dff1531 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -29,12 +29,14 @@
 import android.util.AttributeSet;
 import android.view.ActionProvider;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ActivityChooserModel.ActivityChooserModelClient;
+import android.widget.ListPopupWindow.ForwardingListener;
 
 /**
  * This class is a view for choosing an activity for handling a given {@link Intent}.
@@ -228,17 +230,37 @@
         mDefaultActivityButton.setOnLongClickListener(mCallbacks);
         mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
 
-        mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.expand_activities_button);
-        mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
-        mExpandActivityOverflowButton.setAccessibilityDelegate(new AccessibilityDelegate() {
+        final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
+        expandButton.setOnClickListener(mCallbacks);
+        expandButton.setAccessibilityDelegate(new AccessibilityDelegate() {
             @Override
             public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
                 super.onInitializeAccessibilityNodeInfo(host, info);
                 info.setCanOpenPopup(true);
             }
         });
+        expandButton.setOnTouchListener(new ForwardingListener(expandButton) {
+            @Override
+            public ListPopupWindow getPopup() {
+                return getListPopupWindow();
+            }
+
+            @Override
+            protected boolean onForwardingStarted() {
+                showPopup();
+                return true;
+            }
+
+            @Override
+            protected boolean onForwardingStopped() {
+                dismissPopup();
+                return true;
+            }
+        });
+        mExpandActivityOverflowButton = expandButton;
+
         mExpandActivityOverflowButtonImage =
-            (ImageView) mExpandActivityOverflowButton.findViewById(R.id.image);
+            (ImageView) expandButton.findViewById(R.id.image);
         mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
 
         mAdapter = new ActivityChooserViewAdapter();
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index f2da765..b7e1fdd 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -974,10 +974,12 @@
      * currently touched list item.
      * <p>
      * Example usage:
-     * <pre>ListPopupWindow myPopup = new ListPopupWindow(context);
+     * <pre>
+     * ListPopupWindow myPopup = new ListPopupWindow(context);
      * myPopup.setAnchor(myAnchor);
      * OnTouchListener dragListener = myPopup.createDragToOpenListener(myAnchor);
-     * myAnchor.setOnTouchListener(dragListener);</pre>
+     * myAnchor.setOnTouchListener(dragListener);
+     * </pre>
      *
      * @param src the view on which the resulting listener will be set
      * @return a touch listener that controls drag-to-open behavior
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index e5344c6..603db70 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -82,8 +82,10 @@
      * currently touched list item.
      * <p>
      * Example usage:
-     * <pre>PopupMenu myPopup = new PopupMenu(context, myAnchor);
-     * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());</pre>
+     * <pre>
+     * PopupMenu myPopup = new PopupMenu(context, myAnchor);
+     * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());
+     * </pre>
      *
      * @return a touch listener that controls drag-to-open behavior
      */
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index f73e2c4..b9b6b08 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -462,6 +462,7 @@
 
         views = mSortedVerticalChildren;
         count = views.length;
+        final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
 
         for (int i = 0; i < count; i++) {
             View child = views[i];
@@ -476,14 +477,26 @@
 
                 if (isWrapContentWidth) {
                     if (isLayoutRtl()) {
-                        width = Math.max(width, myWidth - params.mLeft);
+                        if (targetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE) {
+                            width = Math.max(width, myWidth - params.mLeft);
+                        } else {
+                            width = Math.max(width, myWidth - params.mLeft - params.leftMargin);
+                        }
                     } else {
-                        width = Math.max(width, params.mRight);
+                        if (targetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE) {
+                            width = Math.max(width, params.mRight);
+                        } else {
+                            width = Math.max(width, params.mRight + params.rightMargin);
+                        }
                     }
                 }
 
                 if (isWrapContentHeight) {
-                    height = Math.max(height, params.mBottom);
+                    if (targetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE) {
+                        height = Math.max(height, params.mBottom);
+                    } else {
+                        height = Math.max(height, params.mBottom + params.bottomMargin);
+                    }
                 }
 
                 if (child != ignore || verticalGravity) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a2d48a8..3c9cc98 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1519,6 +1519,8 @@
      * with this TextView.  By default there is no associated UndoManager, so null
      * is returned.  One can be associated with the TextView through
      * {@link #setUndoManager(android.content.UndoManager, String)}
+     *
+     * @hide
      */
     public final UndoManager getUndoManager() {
         return mEditor == null ? null : mEditor.mUndoManager;
@@ -1535,6 +1537,8 @@
      * @param tag String tag identifying this particular TextView owner in the
      * UndoManager.  This is used to keep the correct association with the
      * {@link android.content.UndoOwner} of any operations inside of the UndoManager.
+     *
+     * @hide
      */
     public final void setUndoManager(UndoManager undoManager, String tag) {
         if (undoManager != null) {
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index ebf9fe0..f449797 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -21,15 +21,20 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.media.AudioManager;
+import android.media.MediaFormat;
 import android.media.MediaPlayer;
-import android.media.Metadata;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaPlayer.OnInfoListener;
+import android.media.Metadata;
+import android.media.SubtitleController;
+import android.media.WebVttRenderer;
 import android.net.Uri;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pair;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
@@ -40,7 +45,10 @@
 import android.widget.MediaController.MediaPlayerControl;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Map;
+import java.util.Vector;
 
 /**
  * Displays a video file.  The VideoView class
@@ -49,7 +57,8 @@
  * it can be used in any layout manager, and provides various display options
  * such as scaling and tinting.
  */
-public class VideoView extends SurfaceView implements MediaPlayerControl {
+public class VideoView extends SurfaceView
+        implements MediaPlayerControl, SubtitleController.Anchor {
     private String TAG = "VideoView";
     // settable by the client
     private Uri         mUri;
@@ -91,6 +100,15 @@
     private boolean     mCanSeekBack;
     private boolean     mCanSeekForward;
 
+    /** List of views overlaid on top of the video. */
+    private ArrayList<View> mOverlays;
+
+    /**
+     * Listener for overlay layout changes. Invalidates the video view to ensure
+     * that captions are redrawn whenever their layout changes.
+     */
+    private OnLayoutChangeListener mOverlayLayoutListener;
+
     public VideoView(Context context) {
         super(context);
         initVideoView();
@@ -194,6 +212,7 @@
         setFocusable(true);
         setFocusableInTouchMode(true);
         requestFocus();
+        mPendingSubtitleTracks = new Vector<Pair<InputStream, MediaFormat>>();
         mCurrentState = STATE_IDLE;
         mTargetState  = STATE_IDLE;
     }
@@ -218,6 +237,43 @@
         invalidate();
     }
 
+    /**
+     * Adds an external subtitle source file (from the provided input stream.)
+     *
+     * Note that a single external subtitle source may contain multiple or no
+     * supported tracks in it. If the source contained at least one track in
+     * it, one will receive an {@link MediaPlayer#MEDIA_INFO_METADATA_UPDATE}
+     * info message. Otherwise, if reading the source takes excessive time,
+     * one will receive a {@link MediaPlayer#MEDIA_INFO_SUBTITLE_TIMED_OUT}
+     * message. If the source contained no supported track (including an empty
+     * source file or null input stream), one will receive a {@link
+     * MediaPlayer#MEDIA_INFO_UNSUPPORTED_SUBTITLE} message. One can find the
+     * total number of available tracks using {@link MediaPlayer#getTrackInfo()}
+     * to see what additional tracks become available after this method call.
+     *
+     * @param is     input stream containing the subtitle data.  It will be
+     *               closed by the media framework.
+     * @param format the format of the subtitle track(s).  Must contain at least
+     *               the mime type ({@link MediaFormat#KEY_MIME}) and the
+     *               language ({@link MediaFormat#KEY_LANGUAGE}) of the file.
+     *               If the file itself contains the language information,
+     *               specify "und" for the language.
+     */
+    public void addSubtitleSource(InputStream is, MediaFormat format) {
+        if (mMediaPlayer == null) {
+            mPendingSubtitleTracks.add(Pair.create(is, format));
+        } else {
+            try {
+                mMediaPlayer.addSubtitleSource(is, format);
+            } catch (IllegalStateException e) {
+                mInfoListener.onInfo(
+                        mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+            }
+        }
+    }
+
+    private Vector<Pair<InputStream, MediaFormat>> mPendingSubtitleTracks;
+
     public void stopPlayback() {
         if (mMediaPlayer != null) {
             mMediaPlayer.stop();
@@ -244,6 +300,15 @@
         release(false);
         try {
             mMediaPlayer = new MediaPlayer();
+            // TODO: create SubtitleController in MediaPlayer, but we need
+            // a context for the subtitle renderers
+            SubtitleController controller = new SubtitleController(
+                    getContext(),
+                    mMediaPlayer.getMediaTimeProvider(),
+                    mMediaPlayer);
+            controller.registerRenderer(new WebVttRenderer(getContext(), null));
+            mMediaPlayer.setSubtitleAnchor(controller, this);
+
             if (mAudioSession != 0) {
                 mMediaPlayer.setAudioSessionId(mAudioSession);
             } else {
@@ -253,7 +318,7 @@
             mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
             mMediaPlayer.setOnCompletionListener(mCompletionListener);
             mMediaPlayer.setOnErrorListener(mErrorListener);
-            mMediaPlayer.setOnInfoListener(mOnInfoListener);
+            mMediaPlayer.setOnInfoListener(mInfoListener);
             mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
             mCurrentBufferPercentage = 0;
             mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
@@ -261,6 +326,16 @@
             mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
             mMediaPlayer.setScreenOnWhilePlaying(true);
             mMediaPlayer.prepareAsync();
+
+            for (Pair<InputStream, MediaFormat> pending: mPendingSubtitleTracks) {
+                try {
+                    mMediaPlayer.addSubtitleSource(pending.first, pending.second);
+                } catch (IllegalStateException e) {
+                    mInfoListener.onInfo(
+                            mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+                }
+            }
+
             // we don't set the target state here either, but preserve the
             // target state that was there before.
             mCurrentState = STATE_PREPARING;
@@ -277,6 +352,8 @@
             mTargetState = STATE_ERROR;
             mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
             return;
+        } finally {
+            mPendingSubtitleTracks.clear();
         }
     }
 
@@ -386,6 +463,16 @@
         }
     };
 
+    private MediaPlayer.OnInfoListener mInfoListener =
+        new MediaPlayer.OnInfoListener() {
+        public  boolean onInfo(MediaPlayer mp, int arg1, int arg2) {
+            if (mOnInfoListener != null) {
+                mOnInfoListener.onInfo(mp, arg1, arg2);
+            }
+            return true;
+        }
+    };
+
     private MediaPlayer.OnErrorListener mErrorListener =
         new MediaPlayer.OnErrorListener() {
         public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
@@ -530,6 +617,7 @@
             mMediaPlayer.reset();
             mMediaPlayer.release();
             mMediaPlayer = null;
+            mPendingSubtitleTracks.clear();
             mCurrentState = STATE_IDLE;
             if (cleartargetstate) {
                 mTargetState  = STATE_IDLE;
@@ -702,4 +790,119 @@
         }
         return mAudioSession;
     }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        // Layout overlay views, if necessary.
+        if (changed && mOverlays != null && !mOverlays.isEmpty()) {
+            measureAndLayoutOverlays();
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        final int count = mOverlays.size();
+        for (int i = 0; i < count; i++) {
+            final View overlay = mOverlays.get(i);
+            overlay.draw(canvas);
+        }
+    }
+
+    /**
+     * Adds a view to be overlaid on top of this video view. During layout, the
+     * view will be forced to match the bounds, less padding, of the video view.
+     * <p>
+     * Overlays are drawn in the order they are added. The last added overlay
+     * will be drawn on top.
+     *
+     * @param overlay the view to overlay
+     * @see #removeOverlay(View)
+     */
+    private void addOverlay(View overlay) {
+        if (mOverlays == null) {
+            mOverlays = new ArrayList<View>(1);
+        }
+
+        if (mOverlayLayoutListener == null) {
+            mOverlayLayoutListener = new OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                    invalidate();
+                }
+            };
+        }
+
+        if (mOverlays.isEmpty()) {
+            setWillNotDraw(false);
+        }
+
+        mOverlays.add(overlay);
+        overlay.addOnLayoutChangeListener(mOverlayLayoutListener);
+        measureAndLayoutOverlays();
+    }
+
+    /**
+     * Removes a view previously added using {@link #addOverlay}.
+     *
+     * @param overlay the view to remove
+     * @see #addOverlay(View)
+     */
+    private void removeOverlay(View overlay) {
+        if (mOverlays == null) {
+            return;
+        }
+
+        overlay.removeOnLayoutChangeListener(mOverlayLayoutListener);
+        mOverlays.remove(overlay);
+
+        if (mOverlays.isEmpty()) {
+            setWillNotDraw(true);
+        }
+
+        invalidate();
+    }
+
+    /**
+     * Forces a measurement and layout pass for all overlaid views.
+     *
+     * @see #addOverlay(View)
+     */
+    private void measureAndLayoutOverlays() {
+        final int left = getPaddingLeft();
+        final int top = getPaddingTop();
+        final int right = getWidth() - left - getPaddingRight();
+        final int bottom = getHeight() - top - getPaddingBottom();
+        final int widthSpec = MeasureSpec.makeMeasureSpec(right - left, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(bottom - top, MeasureSpec.EXACTLY);
+
+        final int count = mOverlays.size();
+        for (int i = 0; i < count; i++) {
+            final View overlay = mOverlays.get(i);
+            overlay.measure(widthSpec, heightSpec);
+            overlay.layout(left, top, right, bottom);
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void setSubtitleView(View view) {
+        if (mSubtitleView == view) {
+            return;
+        }
+
+        if (mSubtitleView != null) {
+            removeOverlay(mSubtitleView);
+        }
+        mSubtitleView = view;
+        if (mSubtitleView != null) {
+            addOverlay(mSubtitleView);
+        }
+    }
+
+    private View mSubtitleView;
 }
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index ac9bf166..16b119a 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1583,7 +1583,7 @@
                 final int NSRVS = pkgState.mServices.size();
                 if (NPROCS > 0 || NSRVS > 0) {
                     if (!printedHeader) {
-                        pw.println("Per-Package Process Stats:");
+                        pw.println("Per-Package Stats:");
                         printedHeader = true;
                     }
                     pw.print("  * "); pw.print(pkgName); pw.print(" / ");
@@ -1651,7 +1651,8 @@
                         continue;
                     }
                     if (!printedHeader) {
-                        pw.println("Process Stats:");
+                        pw.println();
+                        pw.println("Per-Process Stats:");
                         printedHeader = true;
                     }
                     pw.print("  * "); pw.print(procName); pw.print(" / ");
@@ -2536,7 +2537,8 @@
             if (mActive <= 0) {
                 throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
             }
-            int state = started ? memFactor : STATE_NOTHING;
+            final boolean wasStarted = mStartedState != STATE_NOTHING;
+            final int state = started ? memFactor : STATE_NOTHING;
             if (mStartedState != state) {
                 if (mStartedState != STATE_NOTHING) {
                     addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
@@ -2546,8 +2548,8 @@
                 }
                 mStartedState = state;
                 mStartedStartTime = now;
-                if (mProc != null) {
-                    mProc = mProc.pullFixedProc(mPackage);
+                mProc = mProc.pullFixedProc(mPackage);
+                if (wasStarted != started) {
                     if (started) {
                         mProc.incStartedServices(memFactor, now);
                     } else {
@@ -2561,7 +2563,7 @@
             if (mActive <= 0) {
                 throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
             }
-            int state = bound ? memFactor : STATE_NOTHING;
+            final int state = bound ? memFactor : STATE_NOTHING;
             if (mBoundState != state) {
                 if (mBoundState != STATE_NOTHING) {
                     addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
@@ -2578,7 +2580,7 @@
             if (mActive <= 0) {
                 throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
             }
-            int state = executing ? memFactor : STATE_NOTHING;
+            final int state = executing ? memFactor : STATE_NOTHING;
             if (mExecState != state) {
                 if (mExecState != STATE_NOTHING) {
                     addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ab81a37..8819237 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -287,102 +287,104 @@
     }
 
     protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
-        // Build a reasonable intent filter, based on what matched.
-        IntentFilter filter = new IntentFilter();
+        if (mAlwaysUseOption) {
+            // Build a reasonable intent filter, based on what matched.
+            IntentFilter filter = new IntentFilter();
 
-        if (intent.getAction() != null) {
-            filter.addAction(intent.getAction());
-        }
-        Set<String> categories = intent.getCategories();
-        if (categories != null) {
-            for (String cat : categories) {
-                filter.addCategory(cat);
+            if (intent.getAction() != null) {
+                filter.addAction(intent.getAction());
             }
-        }
-        filter.addCategory(Intent.CATEGORY_DEFAULT);
-
-        int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
-        Uri data = intent.getData();
-        if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
-            String mimeType = intent.resolveType(this);
-            if (mimeType != null) {
-                try {
-                    filter.addDataType(mimeType);
-                } catch (IntentFilter.MalformedMimeTypeException e) {
-                    Log.w("ResolverActivity", e);
-                    filter = null;
+            Set<String> categories = intent.getCategories();
+            if (categories != null) {
+                for (String cat : categories) {
+                    filter.addCategory(cat);
                 }
             }
-        }
-        if (data != null && data.getScheme() != null) {
-            // We need the data specification if there was no type,
-            // OR if the scheme is not one of our magical "file:"
-            // or "content:" schemes (see IntentFilter for the reason).
-            if (cat != IntentFilter.MATCH_CATEGORY_TYPE
-                    || (!"file".equals(data.getScheme())
-                            && !"content".equals(data.getScheme()))) {
-                filter.addDataScheme(data.getScheme());
+            filter.addCategory(Intent.CATEGORY_DEFAULT);
 
-                // Look through the resolved filter to determine which part
-                // of it matched the original Intent.
-                Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
-                if (pIt != null) {
-                    String ssp = data.getSchemeSpecificPart();
-                    while (ssp != null && pIt.hasNext()) {
-                        PatternMatcher p = pIt.next();
-                        if (p.match(ssp)) {
-                            filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
-                            break;
-                        }
+            int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
+            Uri data = intent.getData();
+            if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
+                String mimeType = intent.resolveType(this);
+                if (mimeType != null) {
+                    try {
+                        filter.addDataType(mimeType);
+                    } catch (IntentFilter.MalformedMimeTypeException e) {
+                        Log.w("ResolverActivity", e);
+                        filter = null;
                     }
                 }
-                Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
-                if (aIt != null) {
-                    while (aIt.hasNext()) {
-                        IntentFilter.AuthorityEntry a = aIt.next();
-                        if (a.match(data) >= 0) {
-                            int port = a.getPort();
-                            filter.addDataAuthority(a.getHost(),
-                                    port >= 0 ? Integer.toString(port) : null);
-                            break;
+            }
+            if (data != null && data.getScheme() != null) {
+                // We need the data specification if there was no type,
+                // OR if the scheme is not one of our magical "file:"
+                // or "content:" schemes (see IntentFilter for the reason).
+                if (cat != IntentFilter.MATCH_CATEGORY_TYPE
+                        || (!"file".equals(data.getScheme())
+                                && !"content".equals(data.getScheme()))) {
+                    filter.addDataScheme(data.getScheme());
+
+                    // Look through the resolved filter to determine which part
+                    // of it matched the original Intent.
+                    Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
+                    if (pIt != null) {
+                        String ssp = data.getSchemeSpecificPart();
+                        while (ssp != null && pIt.hasNext()) {
+                            PatternMatcher p = pIt.next();
+                            if (p.match(ssp)) {
+                                filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
+                                break;
+                            }
                         }
                     }
-                }
-                pIt = ri.filter.pathsIterator();
-                if (pIt != null) {
-                    String path = data.getPath();
-                    while (path != null && pIt.hasNext()) {
-                        PatternMatcher p = pIt.next();
-                        if (p.match(path)) {
-                            filter.addDataPath(p.getPath(), p.getType());
-                            break;
+                    Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
+                    if (aIt != null) {
+                        while (aIt.hasNext()) {
+                            IntentFilter.AuthorityEntry a = aIt.next();
+                            if (a.match(data) >= 0) {
+                                int port = a.getPort();
+                                filter.addDataAuthority(a.getHost(),
+                                        port >= 0 ? Integer.toString(port) : null);
+                                break;
+                            }
+                        }
+                    }
+                    pIt = ri.filter.pathsIterator();
+                    if (pIt != null) {
+                        String path = data.getPath();
+                        while (path != null && pIt.hasNext()) {
+                            PatternMatcher p = pIt.next();
+                            if (p.match(path)) {
+                                filter.addDataPath(p.getPath(), p.getType());
+                                break;
+                            }
                         }
                     }
                 }
             }
-        }
 
-        if (filter != null) {
-            final int N = mAdapter.mList.size();
-            ComponentName[] set = new ComponentName[N];
-            int bestMatch = 0;
-            for (int i=0; i<N; i++) {
-                ResolveInfo r = mAdapter.mList.get(i).ri;
-                set[i] = new ComponentName(r.activityInfo.packageName,
-                        r.activityInfo.name);
-                if (r.match > bestMatch) bestMatch = r.match;
-            }
-            if (alwaysCheck) {
-                getPackageManager().addPreferredActivity(filter, bestMatch, set,
-                        intent.getComponent());
-            } else {
-                try {
-                    AppGlobals.getPackageManager().setLastChosenActivity(intent,
-                            intent.resolveTypeIfNeeded(getContentResolver()),
-                            PackageManager.MATCH_DEFAULT_ONLY,
-                            filter, bestMatch, intent.getComponent());
-                } catch (RemoteException re) {
-                    Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
+            if (filter != null) {
+                final int N = mAdapter.mList.size();
+                ComponentName[] set = new ComponentName[N];
+                int bestMatch = 0;
+                for (int i=0; i<N; i++) {
+                    ResolveInfo r = mAdapter.mList.get(i).ri;
+                    set[i] = new ComponentName(r.activityInfo.packageName,
+                            r.activityInfo.name);
+                    if (r.match > bestMatch) bestMatch = r.match;
+                }
+                if (alwaysCheck) {
+                    getPackageManager().addPreferredActivity(filter, bestMatch, set,
+                            intent.getComponent());
+                } else {
+                    try {
+                        AppGlobals.getPackageManager().setLastChosenActivity(intent,
+                                intent.resolveTypeIfNeeded(getContentResolver()),
+                                PackageManager.MATCH_DEFAULT_ONLY,
+                                filter, bestMatch, intent.getComponent());
+                    } catch (RemoteException re) {
+                        Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
+                    }
                 }
             }
         }
diff --git a/core/java/com/android/internal/app/RestrictionsPinActivity.java b/core/java/com/android/internal/app/RestrictionsPinActivity.java
index f8ce108..2112474 100644
--- a/core/java/com/android/internal/app/RestrictionsPinActivity.java
+++ b/core/java/com/android/internal/app/RestrictionsPinActivity.java
@@ -16,9 +16,7 @@
 
 package com.android.internal.app;
 
-import android.app.AlertDialog;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.text.Editable;
@@ -26,7 +24,8 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.WindowManager;
+import android.view.View.OnClickListener;
+import android.widget.Button;
 import android.widget.EditText;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
@@ -38,14 +37,15 @@
  * challenge for an existing PIN. The PIN is maintained by UserManager.
  */
 public class RestrictionsPinActivity extends AlertActivity
-        implements DialogInterface.OnClickListener, TextWatcher, OnEditorActionListener {
+        implements OnClickListener, TextWatcher, OnEditorActionListener {
 
     protected UserManager mUserManager;
     protected boolean mHasRestrictionsPin;
 
     protected EditText mPinText;
     protected TextView mPinErrorMessage;
-    protected TextView mPinMessage;
+    private Button mOkButton;
+    private Button mCancelButton;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -59,19 +59,20 @@
 
     protected void initUi() {
         AlertController.AlertParams ap = mAlertParams;
-        ap.mTitle = getString(R.string.restr_pin_enter_pin);
-        ap.mPositiveButtonText = getString(R.string.ok);
-        ap.mNegativeButtonText = getString(R.string.cancel);
-        ap.mPositiveButtonListener = this;
-        ap.mNegativeButtonListener = this;
+        ap.mTitle = getString(R.string.restr_pin_enter_admin_pin);
         LayoutInflater inflater =
                 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         ap.mView = inflater.inflate(R.layout.restrictions_pin_challenge, null);
 
-        mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
-        mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
         mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
+        mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
+        mOkButton = (Button) ap.mView.findViewById(R.id.pin_ok_button);
+        mCancelButton = (Button) ap.mView.findViewById(R.id.pin_cancel_button);
+
         mPinText.addTextChangedListener(this);
+
+        mOkButton.setOnClickListener(this);
+        mCancelButton.setOnClickListener(this);
     }
 
     protected boolean verifyingPin() {
@@ -84,8 +85,7 @@
         setPositiveButtonState(false);
         boolean hasPin = mUserManager.hasRestrictionsPin();
         if (hasPin) {
-            mPinMessage.setVisibility(View.GONE);
-            mPinErrorMessage.setVisibility(View.GONE);
+            mPinErrorMessage.setVisibility(View.INVISIBLE);
             mPinText.setOnEditorActionListener(this);
             updatePinTimer(-1);
         } else if (verifyingPin()) {
@@ -94,39 +94,37 @@
         }
     }
 
-    private void setPositiveButtonState(boolean enabled) {
-        mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
+    protected void setPositiveButtonState(boolean enabled) {
+        mOkButton.setEnabled(enabled);
     }
 
-    private void updatePinTimer(int pinTimerMs) {
+    private boolean updatePinTimer(int pinTimerMs) {
         if (pinTimerMs < 0) {
             pinTimerMs = mUserManager.checkRestrictionsPin(null);
         }
+        boolean enableInput;
         if (pinTimerMs >= 200) {
-            final int seconds = (pinTimerMs + 200) / 1000;
-            final String formatString = getResources().getQuantityString(
-                    R.plurals.restr_pin_countdown,
-                    seconds);
-            mPinErrorMessage.setText(String.format(formatString, seconds));
+            // Do the count down timer for less than a minute, otherwise just say try again later.
+            if (pinTimerMs <= 60000) {
+                final int seconds = (pinTimerMs + 200) / 1000;
+                final String formatString = getResources().getQuantityString(
+                        R.plurals.restr_pin_countdown,
+                        seconds);
+                mPinErrorMessage.setText(String.format(formatString, seconds));
+            } else {
+                mPinErrorMessage.setText(R.string.restr_pin_try_later);
+            }
+            enableInput = false;
             mPinErrorMessage.setVisibility(View.VISIBLE);
-            mPinText.setEnabled(false);
             mPinText.setText("");
-            setPositiveButtonState(false);
             mPinText.postDelayed(mCountdownRunnable, Math.min(1000, pinTimerMs));
         } else {
-            mPinErrorMessage.setVisibility(View.INVISIBLE);
-            mPinText.setEnabled(true);
-            mPinText.setText("");
+            enableInput = true;
+            mPinErrorMessage.setText(R.string.restr_pin_incorrect);
         }
-    }
-
-    public void onClick(DialogInterface dialog, int which) {
-        setResult(RESULT_CANCELED);
-        if (which == AlertDialog.BUTTON_POSITIVE) {
-            performPositiveButtonAction();
-        } else if (which == AlertDialog.BUTTON_NEGATIVE) {
-            finish();
-        }
+        mPinText.setEnabled(enableInput);
+        setPositiveButtonState(enableInput);
+        return enableInput;
     }
 
     protected void performPositiveButtonAction() {
@@ -135,7 +133,10 @@
             setResult(RESULT_OK);
             finish();
         } else if (result >= 0) {
+            mPinErrorMessage.setText(R.string.restr_pin_incorrect);
+            mPinErrorMessage.setVisibility(View.VISIBLE);
             updatePinTimer(result);
+            mPinText.setText("");
         }
     }
 
@@ -161,7 +162,20 @@
 
     private Runnable mCountdownRunnable = new Runnable() {
         public void run() {
-            updatePinTimer(-1);
+            if (updatePinTimer(-1)) {
+                // If we are no longer counting down, clear the message.
+                mPinErrorMessage.setVisibility(View.INVISIBLE);
+            }
         }
     };
+
+    @Override
+    public void onClick(View v) {
+        if (v == mOkButton) {
+            performPositiveButtonAction();
+        } else if (v == mCancelButton) {
+            setResult(RESULT_CANCELED);
+            finish();
+        }
+    }
 }
diff --git a/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java b/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java
index 1d09292..f7fc6c6 100644
--- a/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java
+++ b/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java
@@ -16,9 +16,7 @@
 
 package com.android.internal.app;
 
-import android.app.AlertDialog;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.os.UserManager;
 import android.text.Editable;
 import android.text.TextUtils;
@@ -44,17 +42,13 @@
         ap.mTitle = getString(R.string.restr_pin_enter_pin);
         ap.mPositiveButtonText = getString(R.string.ok);
         ap.mNegativeButtonText = getString(R.string.cancel);
-        ap.mPositiveButtonListener = this;
-        ap.mNegativeButtonListener = this;
         LayoutInflater inflater =
                 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         ap.mView = inflater.inflate(R.layout.restrictions_pin_setup, null);
 
         mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
-        mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
         mNewPinText = (EditText) ap.mView.findViewById(R.id.pin_new_text);
         mConfirmPinText = (EditText) ap.mView.findViewById(R.id.pin_confirm_text);
-        mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
         mNewPinText.addTextChangedListener(this);
         mConfirmPinText.addTextChangedListener(this);
 
@@ -72,19 +66,7 @@
         return false;
     }
 
-    private void setPositiveButtonState(boolean enabled) {
-        mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
-    }
-
-    public void onClick(DialogInterface dialog, int which) {
-        setResult(RESULT_CANCELED);
-        if (which == AlertDialog.BUTTON_POSITIVE) {
-            performPositiveButtonAction();
-        } else if (which == AlertDialog.BUTTON_NEGATIVE) {
-            finish();
-        }
-    }
-
+    @Override
     protected void performPositiveButtonAction() {
         if (mHasRestrictionsPin) {
             int result = mUserManager.checkRestrictionsPin(mPinText.getText().toString());
@@ -115,7 +97,6 @@
         boolean showError = !TextUtils.isEmpty(pin1) && !TextUtils.isEmpty(pin2);
         // TODO: Check recovery email address as well
         setPositiveButtonState(match);
-        mPinErrorMessage.setVisibility((match || !showError) ? View.INVISIBLE : View.VISIBLE);
     }
 
     @Override
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index c092807..30ca73e 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -35,7 +35,7 @@
 import java.util.StringTokenizer;
 
 public class ProcessCpuTracker {
-    private static final String TAG = "ProcessStats";
+    private static final String TAG = "ProcessCpuTracker";
     private static final boolean DEBUG = false;
     private static final boolean localLOGV = DEBUG || false;
 
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 527aee4..40e0731 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -764,8 +764,6 @@
     static void doTextBounds(JNIEnv* env, const jchar* text, int count,
                              jobject bounds, const SkPaint& paint, jint bidiFlags) {
         SkRect  r;
-        r.set(0,0,0,0);
-
         SkIRect ir;
 
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index ae0113b..4290a6e 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -31,6 +31,7 @@
 static struct {
     jclass clazz;
     jmethodID dispatchSensorEvent;
+    jmethodID dispatchFlushCompleteEvent;
 } gBaseEventQueueClassInfo;
 
 namespace android {
@@ -46,6 +47,8 @@
     jfieldID    resolution;
     jfieldID    power;
     jfieldID    minDelay;
+    jfieldID    fifoReservedEventCount;
+    jfieldID    fifoMaxEventCount;
 } gSensorOffsets;
 
 
@@ -67,6 +70,9 @@
     sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
     sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
     sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
+    sensorOffsets.fifoReservedEventCount =
+            _env->GetFieldID(sensorClass, "mFifoReservedEventCount",  "I");
+    sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount",  "I");
 }
 
 static jint
@@ -78,7 +84,7 @@
     size_t count = mgr.getSensorList(&sensorList);
     if (size_t(next) >= count)
         return -1;
-    
+
     Sensor const* const list = sensorList[next];
     const SensorOffsets& sensorOffsets(gSensorOffsets);
     jstring name = env->NewStringUTF(list->getName().string());
@@ -92,7 +98,9 @@
     env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
     env->SetFloatField(sensor, sensorOffsets.power,      list->getPowerUsage());
     env->SetIntField(sensor, sensorOffsets.minDelay,     list->getMinDelay());
-    
+    env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
+                     list->getFifoReservedEventCount());
+    env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, list->getFifoMaxEventCount());
     next++;
     return size_t(next) < count ? next : 0;
 }
@@ -150,12 +158,20 @@
                     env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
                 }
 
-                env->CallVoidMethod(mReceiverObject,
-                        gBaseEventQueueClassInfo.dispatchSensorEvent,
-                        buffer[i].sensor,
-                        mScratch,
-                        buffer[i].vector.status,
-                        buffer[i].timestamp);
+                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+                    // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
+                    // method.
+                    env->CallVoidMethod(mReceiverObject,
+                                        gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+                                        buffer[i].meta_data.sensor);
+                } else {
+                    env->CallVoidMethod(mReceiverObject,
+                                        gBaseEventQueueClassInfo.dispatchSensorEvent,
+                                        buffer[i].sensor,
+                                        mScratch,
+                                        buffer[i].vector.status,
+                                        buffer[i].timestamp);
+                }
 
                 if (env->ExceptionCheck()) {
                     ALOGE("Exception dispatching input event.");
@@ -186,9 +202,11 @@
     return jint(receiver.get());
 }
 
-static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle, jint us) {
+static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle, jint rate_us,
+                               jint maxBatchReportLatency, jint reservedFlags) {
     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
-    return receiver->getSensorEventQueue()->enableSensor(handle, us);
+    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
+                                                         reservedFlags);
 }
 
 static jint nativeDisableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
@@ -202,6 +220,10 @@
     receiver->decStrong((void*)nativeInitSensorEventQueue);
 }
 
+static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
+    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
+    return receiver->getSensorEventQueue()->flushSensor(handle);
+}
 
 //----------------------------------------------------------------------------
 
@@ -221,7 +243,7 @@
             (void*)nativeInitSensorEventQueue },
 
     {"nativeEnableSensor",
-            "(III)I",
+            "(IIIII)I",
             (void*)nativeEnableSensor },
 
     {"nativeDisableSensor",
@@ -231,6 +253,10 @@
     {"nativeDestroySensorEventQueue",
             "(I)V",
             (void*)nativeDestroySensorEventQueue },
+
+    {"nativeFlushSensor",
+            "(II)I",
+            (void*)nativeFlushSensor },
 };
 
 }; // namespace android
@@ -260,5 +286,9 @@
             gBaseEventQueueClassInfo.clazz,
             "dispatchSensorEvent", "(I[FIJ)V");
 
+    GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+                  gBaseEventQueueClassInfo.clazz,
+                  "dispatchFlushCompleteEvent", "(I)V");
+
     return 0;
 }
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 51ba52a..225bf06 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -742,6 +742,30 @@
 
 
 // ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_timestamp(JNIEnv *env,  jobject thiz, jlongArray jTimestamp) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+
+    if (lpTrack == NULL) {
+        ALOGE("Unable to retrieve AudioTrack pointer for getTimestamp()");
+        return AUDIOTRACK_ERROR;
+    }
+    AudioTimestamp timestamp;
+    status_t status = lpTrack->getTimestamp(timestamp);
+    if (status == OK) {
+        jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL);
+        if (nTimestamp == NULL) {
+            ALOGE("Unable to get array for getTimestamp()");
+            return AUDIOTRACK_ERROR;
+        }
+        nTimestamp[0] = (jlong) timestamp.mPosition;
+        nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec);
+        env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0);
+    }
+    return (jint) android_media_translateErrorCode(status);
+}
+
+
+// ----------------------------------------------------------------------------
 static jint android_media_AudioTrack_set_loop(JNIEnv *env,  jobject thiz,
         jint loopStart, jint loopEnd, jint loopCount) {
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
@@ -869,6 +893,7 @@
     {"native_set_position",  "(I)I",     (void *)android_media_AudioTrack_set_position},
     {"native_get_position",  "()I",      (void *)android_media_AudioTrack_get_position},
     {"native_get_latency",   "()I",      (void *)android_media_AudioTrack_get_latency},
+    {"native_get_timestamp", "([J)I",    (void *)android_media_AudioTrack_get_timestamp},
     {"native_set_loop",      "(III)I",   (void *)android_media_AudioTrack_set_loop},
     {"native_reload_static", "()I",      (void *)android_media_AudioTrack_reload},
     {"native_get_output_sample_rate",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9613df3..49945f0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -247,6 +247,7 @@
 
     <protected-broadcast android:name="android.location.GPS_ENABLED_CHANGE" />
     <protected-broadcast android:name="android.location.PROVIDERS_CHANGED" />
+    <protected-broadcast android:name="android.location.MODE_CHANGED" />
     <protected-broadcast android:name="android.location.GPS_FIX_CHANGE" />
     <protected-broadcast android:name="android.net.proxy.PAC_REFRESH" />
 
diff --git a/core/res/res/drawable-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
index 7f87ee7..f8f9503 100644
--- a/core/res/res/drawable-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_secure.png b/core/res/res/drawable-hdpi/stat_sys_secure.png
deleted file mode 100644
index 5e979db..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index 765be61..d5bb37f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_secure.png b/core/res/res/drawable-ldpi/stat_sys_secure.png
deleted file mode 100644
index 096aa95..0000000
--- a/core/res/res/drawable-ldpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
index 58e0cbc..79683c7 100644
--- a/core/res/res/drawable-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_secure.png b/core/res/res/drawable-mdpi/stat_sys_secure.png
deleted file mode 100644
index da3e318..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index d82704e..df0597f 100644
--- a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
index b753764..5d4ad05 100644
--- a/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
index b47a9f6..66895fa 100644
--- a/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
index 951197c..08017ac 100644
--- a/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
index 5893db9..276dea1 100644
--- a/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
index 1d72243..cdef5d9 100644
--- a/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
index 76dee9e..262af38 100644
--- a/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xxhdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-xxhdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..13ec34e
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xxhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xxhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-xxhdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..34a4c45
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xxhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
index adbd7b1..e143366 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_secure.png b/core/res/res/drawable-xhdpi/stat_sys_secure.png
deleted file mode 100644
index bef2fd7..0000000
--- a/core/res/res/drawable-xhdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
index 51e648c..f7f7871 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png b/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png
index 54fc740..8c6176c 100644
--- a/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_secure.png b/core/res/res/drawable-xxhdpi/stat_sys_secure.png
deleted file mode 100755
index 07c27cb..0000000
--- a/core/res/res/drawable-xxhdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png
index 40d1a35..a53913f 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/layout/restrictions_pin_challenge.xml b/core/res/res/layout/restrictions_pin_challenge.xml
index 954af92..f41924c 100644
--- a/core/res/res/layout/restrictions_pin_challenge.xml
+++ b/core/res/res/layout/restrictions_pin_challenge.xml
@@ -18,42 +18,73 @@
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_marginTop="48dp"
-    android:layout_marginBottom="48dp"
     android:overScrollMode="ifContentScrolls">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:padding="8dip"
         android:orientation="vertical">
-
-        <TextView android:id="@+id/pin_message"
-            style="?android:attr/textAppearanceMedium"
-            android:layout_marginTop="16dp"
-            android:layout_marginBottom="16dp"
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/restr_pin_create_pin"
-            android:textColor="?android:attr/textColorSecondary" />
+            android:padding="8dip"
+            android:orientation="vertical">
 
-        <EditText android:id="@+id/pin_text"
-            style="?android:attr/textAppearanceMedium"
-            android:layout_marginBottom="16dp"
+            <EditText android:id="@+id/pin_text"
+                android:layout_marginLeft="8dip"
+                android:layout_marginStart="8dip"
+                android:layout_marginRight="8dip"
+                android:layout_marginEnd="8dip"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:inputType="numberPassword"
+                android:textColor="?android:attr/textColorPrimary" />
+
+            <TextView android:id="@+id/pin_error_message"
+                android:layout_marginTop="8dp"
+                android:layout_marginBottom="8dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/restr_pin_incorrect"
+                android:gravity="center"/>
+        </LinearLayout>
+
+        <LinearLayout android:id="@+id/buttonPanel"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:hint="@string/restr_pin_enter_pin"
-            android:inputType="numberPassword"
-            android:textColor="?android:attr/textColorPrimary" />
-
-        <TextView android:id="@+id/pin_error_message"
-            style="?android:attr/textAppearanceSmall"
-            android:layout_marginBottom="16dp"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/restr_pin_error_doesnt_match"
-            android:textColor="#FFFF0000" />
-
+            android:minHeight="@dimen/alert_dialog_button_bar_height"
+            android:orientation="vertical"
+            android:divider="?android:attr/dividerHorizontal"
+            android:showDividers="beginning"
+            android:dividerPadding="0dip">
+            <LinearLayout
+                style="?android:attr/buttonBarStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layoutDirection="locale"
+                android:measureWithLargestChild="true">
+                <Button android:id="@+id/pin_cancel_button"
+                    android:layout_width="wrap_content"
+                    android:layout_gravity="start"
+                    android:layout_weight="1"
+                    android:maxLines="2"
+                    android:minHeight="@dimen/alert_dialog_button_bar_height"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:textSize="14sp"
+                    android:layout_height="wrap_content"
+                    android:text="@string/cancel" />
+                <Button android:id="@+id/pin_ok_button"
+                    android:layout_width="wrap_content"
+                    android:layout_gravity="end"
+                    android:layout_weight="1"
+                    android:maxLines="2"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:textSize="14sp"
+                    android:minHeight="@dimen/alert_dialog_button_bar_height"
+                    android:layout_height="wrap_content"
+                    android:text="@string/ok" />
+            </LinearLayout>
+        </LinearLayout>
     </LinearLayout>
-
 </ScrollView>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7abdc6d..575bf55 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Dit laat die houer toe om aan die top-koppelvlak van \'n toeganklikheidsdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"verbind aan \'n drukdiens"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Laat die houer toe om aan die top-koppelvlak van \'n drukdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"kry toegang tot alle druktake"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Gee die houer toegang tot druktake wat deur \'n ander program geskep is. Behoort nooit vir normale programme nodig te wees nie."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"verbind aan \'n drukdatabufferdiens"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Laat die houer toe om aan die top-koppelvlak van \'n drukdatabufferdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"verbind aan NFC-diens"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Laat die houer toe om te verbind aan programme wat NFC-kaarte nastrewe. Behoort nooit vir normale programme nodig te wees nie."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind aan \'n teksdiens"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Gekanselleer"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kon nie inhoud skryf nie"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"onbekend"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Voer PIN in"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Huidige PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nuwe PIN"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ce827f9..0425180 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ያዢው ወደ የአንድ ተደራሽነት አገልግሎት ከፍተኛ-ደረጃ በይነገጽ እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች መቼም ቢሆን ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"ከአንድ የህትመት አገልግሎት ጋር ማያያዝ"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ያዢው የህትመት አገልግሎቱን ወደ ከፍተኛ-ደረጃ በይነገጽ እንዲጠርዝ ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ሁሉንም የህትመት ስራዎችን መድረስ"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ያዢው በሌላ መተግበሪያ የተፈጠሩ የህትመት ስራዎች እንዲደርስባቸው ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ከአንድ የህትመት አስተላላፊ አገልግሎት ጋር ይሰሩ"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"ያዢው የህትመት አስተላላፊ አገልግሎቱን ከከፍተኛ-ደረጃ በይነገጽ ጋር እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"ከNFC አገልግሎት ጋር ይሰሩ"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"ያዢው የNFC ካርዶችን የሚያስመስሉ መተግበሪያዎችን እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"ለፅሁፍ አገልግሎት አሰረ"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ታብሎይድ"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ተትቷል"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ይዘት መጻፍ ላይ ስህተት"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"አይታወቅም"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ፒን ያስገቡ"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"የአሁኑ ፒን"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"አዲስ ፒን"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 81b3464..dbd270c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إمكانية الدخول. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"الالتزام بخدمة طباعة"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الطباعة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"الدخول إلى جميع وظائف الطباعة"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"للسماح للمالك بالدخول إلى وظائف الطباعة التي أنشأها تطبيق آخر. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"الالتزام بخدمة التخزين المؤقت للطباعة"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة التخزين المؤقت للطباعة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"الربط بخدمة NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"للسماح لحامل البطاقة بالربط بالتطبيقات التي تحاكي بطاقات NFC. لا يتوجب استخدامه على الإطلاق للتطبيقات العادية."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"الالتزام بخدمة إدخال النصوص"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ملغاة"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"حدث خطأ أثناء كتابة المحتوى"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"غير معروف"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"إدخال رقم التعريف الشخصي"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"رقم التعريف الشخصي الحالي"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"رقم التعريف الشخصي الجديد"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 0ae4dda..e6d8c9b 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Sahibə giriş xidmətin ən üst səviyyə interfeysi bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"çap servisini qoşma"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Sahibinə bir çap xidmətinin ən üst səviyə araüzünü bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"bütün çap işlərinə giriş əldə et"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Sahibinə digər tətbiqlər tərəfindən yaradılan çap işlərinə giriş hüququ verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"çap spuler servisinə qoş"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Sahibinə çap spuler xidmətinin ən üst səviyyə interfeysinə bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC xidmətlərinə qoşun"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sahibinə NFC kartlarını emulyasiya edən tətbiqləri bir-birinə qoşmağa icazə verin. Normal tətbiqlər üçün lazım deyil."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"mətn servisini qoşma"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Qısa"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ləğv edildi"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kontent yazmna xətası"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"naməlum"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN daxil edin"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Cari PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index e04c6e6..d3782e0 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -365,9 +365,9 @@
     <skip />
     <!-- no translation found for permdesc_bindPrintService (7960067623209111135) -->
     <skip />
-    <!-- no translation found for permlab_accessAllPrintJobs (1120792468465711159) -->
+    <!-- no translation found for permlab_bindPrintSpoolerService (6807762783744125954) -->
     <skip />
-    <!-- no translation found for permdesc_accessAllPrintJobs (2978185311041864762) -->
+    <!-- no translation found for permdesc_bindPrintSpoolerService (3680552285933318372) -->
     <skip />
     <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
     <skip />
@@ -1637,6 +1637,8 @@
     <skip />
     <!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
     <skip />
+    <!-- no translation found for reason_unknown (6048913880184628119) -->
+    <skip />
     <!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
     <skip />
     <!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 46f211e..3bb818b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за достъпност. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"обвързване с услуга за отпечатване"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"достъп до всички задания за отпечатване"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Разрешава на притежателя да осъществява достъп до създадените от друго приложение задания за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"обвързване с услуга за спулер за отпечатване"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за спулер за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"обвързване с услуга за КБП"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Разрешава на притежателя да се обвързва с приложения, които емулират карти за КБП. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обвързване с текстова услуга"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Анулирано"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Грешка при записване на съдържанието"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"неизвестно"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Въведете ПИН кода"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Текущ ПИН код"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Нов ПИН код"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a6fd663..3d6315f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet vincular amb la interfície de nivell superior d\'un servei d\'accessibilitat. Les aplicacions normals no haurien de necessitar-ho."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"vincula amb un servei d\'impressió"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei d\'impressió. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accedeix a totes les tasques d\'impressió"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permet que el propietari accedeixi a les tasques d\'impressió creades per una altra aplicació. Les aplicacions normals no l\'haurien de necessitar mai."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"vincula amb un servei de gestor de cues d\'impressió"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de gestor de cues d\'impressió. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"vincula al servei NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet que el titular es vinculi a les aplicacions que emulen les targetes de NFC. No hauria de ser mai necessari per a les aplicacions normals."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincula a un servei de text"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancel·lada"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error en escriure el contingut"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconegut"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introdueix el PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nou"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 98e1783..0d0e95c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"navázat se na tiskovou službu"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Umožňuje navázání na nejvyšší úroveň tiskové služby. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"přístup ke všem tiskovým úlohám"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Umožňuje přístup k tiskovým úlohám vytvořeným jinou aplikací. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"navázat se na službu zařazování tisku"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Umožňuje držiteli navázat se na nejvyšší úroveň služby zařazování tisku. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"navázat se na službu NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umožňuje držiteli navázat se na aplikace, které emulují karty NFC. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"navázat se na textovou službu"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Zrušeno"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Při zápisu obsahu došlo k chybě"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"neznámé"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Zadejte kód PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuální kód PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nový kód PIN"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 5f100cf..36272ab 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at brugeren binder sig til en grænseflade for en tilgængelighedstjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"forbinde til en udskriftstjeneste"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Tillader, at brugeren forbinder til grænsefladen for en udskriftstjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"få adgang til alle udskriftsjob"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Tillader, at brugeren får adgang til udskriftsjob, der er oprettet af en anden app. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"forbinde til en udskriftsspoolertjeneste"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Tillader, at brugeren forbinder til grænsefladen for en udskriftsspoolertjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"Knyt til NFC-tjeneste"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Tillader, at indehaveren opretter tilknytninger til applikationer, der efterligner NFC-kort. Dette bør aldrig være nødvendigt for normale apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"forpligte sig til en sms-tjeneste"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Amerikansk \"Tabloid\""</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulleret"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fejl ved skrivning af indhold"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ukendt"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Indtast pinkode"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuel pinkode:"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny pinkode"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0170f2e..863c2c0 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ermöglicht dem Halter, sich an die Oberfläche einer Bedienungshilfe auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"An einen Druckdienst binden"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druckdienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Auf alle Druckaufträge zugreifen"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ermöglicht dem Inhaber den Zugriff auf von einer anderen App erstellte Druckaufträge. Sollte für normale Apps nie benötigt werden."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"An Druck-Spooler-Dienst binden"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druck-Spooler-Dienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"An NFC-Dienst binden"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ermöglicht dem Inhaber die Bindung an Apps, die NFC-Karten emulieren. Dies sollte für normale Apps niemals notwendig sein."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"An einen Textdienst binden"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Abgebrochen"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fehler beim Schreiben von Inhalten"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"Unbekannt"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN eingeben"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuelle PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Neue PIN"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b172f2b..be12c74 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανώτατου επιπέδου μιας υπηρεσίας προσβασιμότητας. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"δέσμευση σε υπηρεσία εκτύπωσης"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας εκτύπωσης. Δεν απαιτείται για κανονικές εφαρμογές."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"πρόσβαση σε όλες τις εργασίες εκτύπωσης"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Επιτρέπει στον κάτοχο να αποκτά πρόσβαση σε εργασίες εκτύπωσης από άλλες εφαρμογές. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"σύνδεση με μια υπηρεσία εκτύπωσης σε ουράς"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Επιτρέπει στον κάτοχο τη σύνδεση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας εκτύπωσης σε ουρά. Δεν απαιτείται για κανονικές εφαρμογές."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"σύνδεση με υπηρεσία NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Δίνει στον κάτοχο τη δυνατότητα σύνδεσης με εφαρμογές που προσομοιώνουν κάρτες NFC. Δεν ζητείται ποτέ για κανονικές εφαρμογές."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"δέσμευση σε υπηρεσία ανταλλαγής μηνυμάτων"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ακυρώθηκε"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Σφάλμα κατά την εγγραφή περιεχομένου"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"άγνωστο"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Εισαγωγή PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Ισχύων κωδικός PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Νέος κωδικός PIN"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 63004a8..5b431fd 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"access all print jobs"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Allows the holder to access print jobs created by another app. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 63004a8..5b431fd 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"access all print jobs"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Allows the holder to access print jobs created by another app. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b0737e5..ee051db 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"vincular a un servicio de impresión"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acceder a todos los trabajos de impresión"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite al propietario acceder a trabajos de impresión creados con otra aplicación. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"Vincular a un servicio de administrador de trabajos de impresión"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite al propietario vincularse con la interfaz de nivel superior de un servicio de administrador de trabajos de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"Vincular con servicio NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite vincular con aplicaciones que emulen tarjetas NFC. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelada"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error al escribir contenido"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconocido"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ingresar PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nuevo"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 170abd2..844412d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite enlazar con la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"enlazar con un servicio de impresión"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite enlazar con la interfaz de nivel superior de un servicio de impresión. No debe ser necesario para las aplicaciones normales."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acceder a todos los trabajos de impresión"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite acceder a trabajos de impresión creados con otra aplicación. No debe ser necesario para aplicaciones normales."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"enlazar con un servicio de cola de impresión"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite enlazar con la interfaz de nivel superior de un servicio de cola de impresión. No debe ser necesario para las aplicaciones normales."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"enlazar con servicio NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite enlazar con aplicaciones que emulen tarjetas NFC. No debe ser necesario para las aplicaciones normales."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"enlazar con un servicio de texto"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error al escribir contenido"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconocido"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introducir PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nuevo"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index b58bf7b..f99f774 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lubab omanikul luua sideme juurdepääsuteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"sidumine printimisteenusega"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lubab omanikul siduda printimisteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"juurdepääs kõikidele printimistöödele"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lubab omanikule juurdepääsu teise rakenduse loodud printimistöödele. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"seo printimise spuulerteenusega"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lubab omanikul siduda printimise spuulerteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC-teenusega sidumine"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Lubab õiguste omajal luua seosed rakendustega, mis emuleerivad NFC-kaarte. Pole kunagi vajalik tavaliste rakenduste korral."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tühistatud"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Viga sisu kirjutamisel"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"teadmata"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Sisestage PIN-kood"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Praegune PIN-kood"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uus PIN-kood"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 65f26aa..0135830 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"به دارنده اجازه می‌دهد که به رابط سطح بالای سرویس دسترسی متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"اتصال به یک سرویس چاپ"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"به برنامه اجازه می‌دهد که به رابط سطح بالای سرویس چاپ متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"دسترسی به تمام کارهای چاپ"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"به دارنده اجازه دسترسی به کارهای چاپی ایجاد شده توسط برنامه‌ای دیگر را می‌دهد.هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"اتصال به سرویس هماهنگ‌کننده چاپ"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"به دارنده اجازه می‌دهد که به واسط سطح بالای سرویس هماهنگ‌کننده چاپ متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"اتصال به سرویس NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"به دارنده اجازه می‌دهد به برنامه‌هایی متصل شود که مشابه با کارت‌های NFC عمل می‌کنند. هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"اتصال به یک سرویس متنی"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"لغو شد"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"خطا هنگام نوشتن محتوا"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"نامعلوم"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"پین را وارد کنید"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"پین کنونی"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"پین جدید"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 524128dc..fd11b88 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Antaa sovelluksen sitoutua esteettömyyspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"Tulostuspalveluun sitoutuminen"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Antaa sovelluksen sitoutua tulostuspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Kaikkien tulostustöiden käyttäminen"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Antaa luvanhaltijan käyttää toisen sovelluksen luomia tulostustöitä. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"tulostuspalveluun sitoutuminen"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Antaa sovelluksen sitoutua tulostuspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"luo sidos NFC-palveluun"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sallii oikeuden haltijan luoda sidoksia sovelluksiin, jotka jäljittelevät NFC-kortteja. Tämän ei pitäisi olla tarpeen tavallisille sovelluksille."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstipalveluun sitoutuminen"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Peruutettu"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Sisällön kirjoittamisessa tapahtui virhe"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"tuntematon"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Anna PIN-koodi"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Nykyinen PIN-koodi"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uusi PIN-koodi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2b48342..051fea1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"lier à un service d\'impression"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accéder à tous les travaux d\'impression"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permet à l\'application d\'accéder aux travaux d\'impression créés par une autre application. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"s\'associer à un service d\'impression désynchronisée"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service d\'impression désynchronisée. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"s\'associer au service NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet à l\'application autorisée de s\'associer aux applications qui reproduisent le fonctionnement des cartes NFC. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"s\'associer à un service de texte"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulé"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erreur lors de l\'écriture du contenu"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"inconnu"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Saisissez le NIP"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"NIP actuel"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau NIP"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3017dd2..379bc13 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"s\'associer à un service d\'impression"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service d\'impression. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accéder à l\'ensemble des tâches d\'impression"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permet à l\'application autorisée d\'accéder aux tâches d\'impression créées via une autre application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"s\'associer à un service de spouleur d\'impression"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service de spouleur d\'impression. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"s\'associer au service NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet à l\'application autorisée de s\'associer aux applications qui reproduisent le fonctionnement des cartes NFC. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"associer à un service de texte"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloïd"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tâche annulée."</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erreur lors de la modification du contenu."</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"inconnu"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Saisir le code PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Code PIN actuel"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau code PIN"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 113757b..b88f663d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी पहुंच-योग्यता सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"प्रिंट सेवा से आबद्ध करें"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"धारक को किसी प्रिंट सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"सभी प्रिंट कार्य एक्सेस करें"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"धारक को अन्य एप्लिकेशन के द्वारा बनाए गए प्रिंट कार्य एक्सेस करने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिंट स्पूलर सेवा से आबद्ध करें"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"धारक को प्रिंट स्पूलर सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवा से आबद्ध रहें"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"धारक को ऐसे एप्लिकेशन से आबद्ध रहने देता है जो NFC कार्ड का अनुकरण कर रहे हैं. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"टेबलॉइड"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द कर दी गई"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामग्री लिखने में त्रुटि"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN डालें"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान पिन"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नया पिन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 9a3c50c..136b704 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge dostupnosti. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"veži se uz uslugu ispisa"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Dopušta nositelju vezanje uza sučelje usluge ispisa najviše razine. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"pristupi svim zadacima ispisa"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Dopušta nositelju pristup zadacima ispisa koje je izradila neka druga aplikacija. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"veži se uz uslugu predmemoriranja ispisa"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Dopušta nositelju vezanje uza sučelje usluge predmemoriranja ispisa najviše razine. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"povezivanje s NFC uslugom"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Omogućuje nositelju povezivanje s aplikacijama koje emuliraju NFC kartice. Nikada ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vezanje na tekstualnu uslugu"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Otkazano"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Pogreška prilikom pisanja sadržaja"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nepoznato"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutačni PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 2ef6d9b..8351c56 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lehetővé teszi a használó számára, hogy csatlakozzon egy kisegítő szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"csatlakozás egy nyomtatási szolgáltatáshoz"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lehetővé teszi a használó számára, hogy csatlakozzon egy nyomtatási szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"hozzáférés valamennyi nyomtatási feladathoz"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lehetővé teszi a használó számára, hogy megtekintsen más alkalmazások által létrehozott nyomtatási feladatokat. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"csatlakozás egy nyomtatásisor-kezelő szolgáltatáshoz"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lehetővé teszi a használó számára, hogy csatlakozzon egy nyomtatásisor-kezelő legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"csatlakozás NFC-szolgáltatáshoz"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Az eszköz kezelője csatlakozhat NFC-kártyákat emuláló alkalmazásokhoz. A normál alkalmazásoknak nincs rá szükségük."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"csatlakozás szövegszolgáltatáshoz"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"„Tabloid” méret"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Törölve"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Hiba történt a tartalomírás közben"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ismeretlen"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN kód megadása"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Jelenlegi PIN kód"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Új PIN kód"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 337027c..232add4 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Թույլ է տալիս սեփականատիրոջը միանալ հասանելիության ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"միանալ տպման ծառայությանը"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Թույլ է տալիս սեփականատիրոջը միանալ տպման ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"մուտքի գործել բոլոր տպման աշխատանքներ"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Թույլ է տալիս սեփականատիրոջը մուտք ունենալ մեկ այլ ծրագրի կողմից ստեղծված տպման աշխատանքներ: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"միանալ տպման կարգավարի ծառայությանը"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Թույլ է տալիս սեփականատիրոջը միանալ տպման կարգավարի ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ  անհրաժեշտ չպետք է լինի:"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"կապվել NFC ծառայությանը"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Թույլ է տալիս տիրոջը կապվել ծրագրերին, որոնք օգտագործում են NFC քարտեր: Սովորական ծրագրերի համար երբեք անհրաժեշտ չէ:"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"միանալ տեքստային ծառայությանը"</string>
@@ -1093,8 +1093,8 @@
     <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>
-    <string name="capital_off" msgid="6815870386972805832">"Անջատել"</string>
+    <string name="capital_on" msgid="1544682755514494298">"I"</string>
+    <string name="capital_off" msgid="6815870386972805832">"O"</string>
     <string name="whichApplication" msgid="4533185947064773386">"ավարտել գործողությունը` օգտագործելով"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Օգտագործել լռելյայն այս գործողության համար:"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Մաքրել լռելյայնը Համակարգի կարգավորումներ &gt; Ծրագրեր &gt;Ներբեռնված էջից:"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Չեղարկված է"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Բովանդակության գրելու սխալ"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"անհայտ"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Մուտքագրեք PIN-ը"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Ընթացիկ PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Նոր PIN"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3b9a280..d69e121 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Mengizinkan pemegang untuk mengikat antarmuka tingkat tinggi dari suatu layanan. Tidak pernah diperlukan oleh aplikasi normal."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"mengikat ke layanan pencetakan"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan pencetakan. Tidak pernah diperlukan oleh aplikasi normal."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"mengakses semua tugas pencetakan"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Memungkinkan pemegang mengakses tugas pencetakan yang dibuat oleh aplikasi lain. Tidak pernah diperlukan aplikasi normal."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"mengikat ke layanan penampung pencetakan"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari layanan penampung pencetakan. Tidak pernah diperlukan oleh aplikasi normal."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"mengikat ke layanan NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Memungkinkan pemegang mengikat ke aplikasi yang meniru kartu NFC. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"mengikat ke layanan SMS"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Terjadi kesalahan saat menulis konten"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"tak diketahui"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Saat Ini"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN Baru"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1195923..0a1dad1 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di accessibilità. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"collegamento a un servizio di stampa"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di stampa. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accesso a tutti i processi di stampa"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Consente al titolare di accedere ai processi di stampa creati da un\'altra app. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"collegamento a un servizio spooler di stampa"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio spooler di stampa. Non dovrebbe essere mai necessaria per le normali app."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"associazione a servizio NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Consente al titolare di collegarsi alle applicazioni che emulano carte NFC. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"associazione a un servizio di testo"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annullato"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Errore nella scrittura dei contenuti"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"sconosciuto"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Inserisci PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN corrente"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nuovo PIN"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5d2b391..ba52642 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"מתיר לבעלים להכפיף לממשק ברמה העליונה של שירות זמינות. הרשאה זו אף פעם אינה אמורה להיות נחוצה ליישומים רגילים."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"איגוד לשירות הדפסה"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ההרשאה הזו מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות הדפסה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"גישה אל כל עבודות ההדפסה"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ההרשאה הזו מאפשרת לבעלים לגשת לעבודות הדפסה שנוצרו על ידי אפליקציה אחרת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"איגוד לשירות הדפסה"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"מאפשרת לבעלים לבצע איגוד לממשק ברמה העליונה של שירות הדפסה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"איגוד לשירות NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"מאפשרת לבעלים לאגד את האפליקציות המחקות כרטיסיות NFC. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"הכפפה לשירות טקסט"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"בוטלה"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"שגיאה בכתיבת תוכן"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"לא ידוע"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"הזן מספר PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"מספר PIN נוכחי"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"מספר PIN חדש"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index b86ba32..7d38f88 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ユーザー補助サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"印刷サービスへのバインド"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"印刷サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"すべての印刷ジョブへのアクセス"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"別のアプリが作成した印刷ジョブにアクセスすることを所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"印刷スプーラサービスへのバインド"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"印刷スプーラサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFCサービスへのバインド"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFCカードをエミュレートしているアプリにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"テキストサービスにバインド"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"タブロイド"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"キャンセルされました"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"コンテンツの書き込み中にエラーが発生しました"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PINを入力"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"現在のPIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新しいPIN"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 43f0be6..b2c1c3d 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"აპს შეეძლება გამარტივებული წვდომის სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"ბეჭდვის სევისზე მიბმა"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"მფლობელს შეეძლება მიებას ბეჭდვის სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ბეჭდვის ყველა დავალებაზე წვდომა"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"საშუალებას აძლევს მფლობელს იქონიოს წვდომა სხვა აპის მიერ შექმნილ ბეჭდვის დავალებებზე. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ბეჭდვის spooler სევისზე მიბმა"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"მფლობელს შეეძლება მიებას ბეჭდვის spooler სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC სერვისთან შეკავშირება"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"საშუალებას აძლევს მფლობელს შეკავშირდეს აპლიკაციებთან, რომლებიც NFC ბარათების სიმულაციას ახდენს. ჩვეულებრივ აპებს უმეტეს შემთხვევაში არ დაჭირდება."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"ტექსტ სერვისთან დაკავშირება"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"გაუქმებული"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"შეცდომა კონტენტის ჩაწერისას"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"უცნობი"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"შეიყვანეთ PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ამჟამინდელი PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ახალი PIN"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index fee8e66..4feebe5 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យ​​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ភាព​ងាយស្រួល។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"ចង​សេវាកម្ម​​បោះពុម្ព"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ចូល​ដំណើរការ​​ការងារ​បោះពុម្ព​ទាំងអស់"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​អាច​បោះពុម្ព​ការងារ​ដែល​បាន​បង្កើត​ដោយ​កម្មវិធី​ផ្សេង។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ភ្ជាប់​ទៅ​សេវាកម្ម print spooler"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​ទៅ​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម print spooler ។ មិន​គួរ​ទាមទារ​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"ភ្ជាប់​ជាមួយ​សេវាកម្ម NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"អនុញ្ញាត​ឲ្យ​​ភ្ជាប់​​​បញ្ជី​ជាមួយ​​កម្មវិធី​ដែល​ត្រូវ​បាន​ត្រាប់​តាម​​កាត NFC ។ មិន​គួរ​ត្រូវ​​ការ​សម្រាប់​កម្មវិធី​ធម្មតា​។"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"ចង​សេវា​កម្ម​អត្ថបទ"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បាន​បោះ​បង់"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុស​ក្នុង​ការ​សរសេរ​មាតិកា"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"មិន​ស្គាល់"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"បញ្ចូល​​កូដ PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"កូដ PIN បច្ចុប្បន្ន"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"កូដ PIN ថ្មី"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 23fbda9..cdbf256 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"권한을 가진 프로그램이 접근성 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"인쇄 서비스 사용"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"권한을 가진 프로그램이 인쇄 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"모든 인쇄 작업에 액세스"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"권한을 가진 프로그램이 다른 앱에서 생성한 인쇄 작업에 액세스하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"인쇄 스풀러 서비스 사용"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"권한을 가진 프로그램이 인쇄 스풀러 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC 서비스 사용"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"권한을 가진 프로그램이 NFC 카드를 에뮬레이션하는 애플리케이션을 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"텍스트 서비스 연결"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"타블로이드"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"취소됨"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"콘텐츠 작성 중 오류"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"알 수 없음"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN 입력"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"현재 PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"새 PIN"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 37770d4..d55a2c8 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງ ເຊື່ອມໂຍງສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງບໍລິການການເຂົ້າເຖິງ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"ຜູກ​ມັດ​ກັບ​ການ​ບໍ​ລິ​ການ​ພິມ"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ເຂົ້າເຖິງວຽກການພິມທັງໝົດ"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຂົ້າເຖິງວຽກການພິມທີ່ຖືກສ້າງໂດຍແອັບຯອື່ນ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ຜູກ​ມັດ​ກັບບໍລິການການພິມແບບ spooler"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"ເຊື່ອມໂຍງກັບບໍລິການ NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"ອະນຸຍາດໃຫ້ຜູ່ຖືອຸປະກອນໃຫ້ສາມາດເຊື່ອມໂຍງແອັບພລິເຄຊັນ ທີ່ຄ້າຍກັບບັດ NFC. ມັນບໍ່ຈຳເປັນຕ້ອງໃຊ້ໃນແອັບຯທຳມະດາ."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"ເຊື່ອມໂຍງໄປຫາບໍລິການສົ່ງຂໍ້ຄວາມ"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ແຖບບລອຍ"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ຍົກເລີກແລ້ວ"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ເນື້ອ​ໃນ​ການຂຽນຜິດພາດ"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ບໍ່ຮູ້ຈັກ"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ໃສ່ລະຫັດ PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະ​ຈຸ​ບັນ"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4548ebe..ca810ae 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Savininkui leidžiama susisaistyti su aukščiausio lygio pasiekiamumo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"susisaistyti su spausdinimo paslauga"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Turėtojui leidžiama susisaistyti su spausdinimo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"pasiekti visas spausdinimo užduotis"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Turėtojui leidžiama pasiekti spausdinimo užduotis, sukurtas naudojant kitą programą. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"susaistyti su spausdinimo kaupimo paslauga"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Turėtojui leidžiama susaistyti programą su spausdinimo kaupimo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"susaistyti su ALR paslauga"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Savininkui leidžiama susaistyti programas, kurios kopijuoja ALR korteles. Neturėtų prireikti įprastoms programoms."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"priskirti teksto paslaugą"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Bulvarinė spauda"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Atšaukta"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Klaida rašant turinį"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nežinoma"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Įveskite PIN kodą"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Dabartinis PIN kodas"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Naujas PIN kodas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f0314cf..529e763 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ļauj īpašniekam izveidot saiti ar pieejamības pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"Savienojuma izveide ar drukāšanas pakalpojumu"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ļauj īpašniekam izveidot savienojumu ar drukāšanas pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Piekļuve visiem drukas darbiem"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ļauj īpašniekam piekļūt drukas darbiem, kas izveidoti citā lietotnē. Parastām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"izveidot savienojumu ar drukas spolētāja pakalpojumu"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ļauj īpašniekam izveidot savienojumu ar drukas spolētāja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"Saistīt ar TDLS pakalpojumu"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ļauj īpašniekam saistīt lietojumprogrammas, kas emulē TDLS kartes. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Atcelts"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Rakstot saturu, radās kļūda."</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nezināms"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ievadiet PIN."</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Pašreizējais PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Jaunais PIN"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 67ec195..25a4f1b 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Эзэмшигч нь хандах үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"хэвлэх үйлчилгээтэй холбох"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"бүх хэвлэх ажилд хандалт хийх"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Эзэмшигчид өөр апп-аас үүсгэсэн хэвлэх ажилд хандалт хийх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"хэвлэгчийн буфер үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC үйлчилгээтэй холбох"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Эзэмшигчид NFC картуудыг дуурайлгадаг аппликешнүүдийг холбох боломж олгоно. Энгийн апп-уудад хэзээ ч шаардагдахгүй."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"текст үйлчилгээтэй холбох"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Цуцлагдсан"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Контентыг бичих явцад алдаа гарсан"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"тодорхойгүй"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN оруулна уу"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Одоогийн PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Шинэ PIN"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 9031a79..0088f44 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan yang boleh diakses. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"terikat kepada perkhidmatan cetakan"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"akses semua kerja cetakan"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Membenarkan pemegang mengakses kerja cetakan yang dibuat oleh apl lain. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"terikat kepada perkhidmatan penspul cetakan"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan penspul cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"terikat kepada perkhidmatan NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Membenarkan pemegang untuk terikat kepada aplikasi yang mengikut kad NFC. Tidak sekali-kali diperlukan untuk apl normal."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ralat menulis kandungan"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"tidak diketahui"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN semasa"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN baharu"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3e20e6e..ba81a46 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Gir innehaveren tillatelse til å bindes til det øverste nivået av grensesnittet for en tilgjengelighetstjeneste. Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"binding til en utskriftstjeneste"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en utskriftstjeneste. Dette skal ikke være nødvendig for vanlige apper."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"tilgang til alle utskriftsjobber"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Gir innehaveren tillatelse til å åpne utskriftsjobber som er opprettet av andre apper. Dette skal ikke være nødvendig for vanlige apper."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"binde til en tjeneste for utskriftskø"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en tjeneste for utskriftskø. Dette skal ikke være nødvendig for vanlige apper."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"binding til NFC-tjenesten"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Tillater eieren å binde seg til apper som emulerer NFC-kort. Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"binde til en teksttjeneste"</string>
@@ -415,7 +415,7 @@
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige telefonfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
     <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"gi eller trekke tilbake tillatelser"</string>
-    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar programmer gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre programmer. Skadelige programmer kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar apper gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre apper. Skadelige apper kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angi foretrukne apper"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lar appen endre de foretrukne appene dine. Ondsinnede apper kan ubemerket endre apper som kjøres, og forfalske eksisterende apper til å samle private data fra deg."</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"endre systeminnstillingene"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kansellert"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Feil under skriving av innhold"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ukjent"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Skriv inn PIN-koden"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Gjeldende PIN-kode:"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny PIN-kode"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index bd8dece..e00d0af 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"एक पहुँच सेवाको उच्च स्तरको कुराकानीलाई पक्का गर्नको लागि समाती राख्नेले अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"एउटा प्रिन्ट सेवासँग जोड्नुहोस्"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"एउटा प्रिन्ट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि प्रयोगकर्तालाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"सबै प्रिन्ट कार्यहरूको पहुँच गर्नुहोस्"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"प्रयोगकर्तालाई अन्य अनुप्रयोगद्वारा निर्मित प्रिन्ट कार्यहरू पहुँच गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिन्ट स्पुलर सेवासँग बाध्नुहोस्"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"प्रिन्ट स्पुलर सेवाको शीर्ष तह इन्टर्फेसलाई बाहकसँग बाँध्न अनुमति दिन्छ। सामान्य अनुप्रयोगलाई कहिल्यै पनि आवाश्यक नपर्न सक्छ।"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवामा बाँध्नुहोस्"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC कार्डहरू इमुलेट गर्ने अनुप्रयोगहरूलाई बाँध्नका लागि होल्डरलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूका लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"एउटा पाठ सेवासँग संगठित हुनुहोस्"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द गरियो"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामाग्री लेखनमा त्रुटि"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN प्रविष्टि गर्नुहोस्"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नयाँ PIN"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 20a3f99..1ae4607 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een toegankelijkheidsservice. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"koppelen aan een afdrukservice"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Hiermee kan de houder verbinding maken met de hoofdinterface van een afdrukservice. Nooit vereist voor normale apps."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"toegang krijgen tot alle afdruktaken"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Hiermee kan de houder toegang krijgen tot afdruktaken die zijn gemaakt door een andere app. Nooit vereist voor normale apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"koppelen aan een afdrukspoolerservice"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Hiermee kan de houder verbinding maken met de hoofdinterface van een afdrukspoolerservice. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"koppelen aan NFC-service"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Hiermee kan de houder apps koppelen die NFC-kaarten emuleren. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"koppelen aan een sms-service"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Geannuleerd"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fout bij schrijven van inhoud"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"onbekend"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Geef de pincode op"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Huidige pincode"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nieuwe pincode"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d4be6ba..ade7c40 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi ułatwień dostępu. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"tworzenie powiązania z usługą drukowania"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi drukowania. Nieprzeznaczone dla zwykłych aplikacji."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"dostęp do wszystkich zadań drukowania"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Zezwala na dostęp do zadań drukowania utworzonych przez inną aplikację. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"tworzenie powiązania z usługą buforowania wydruku"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi buforowania wydruku. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"powiązanie z usługą NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umożliwia właścicielowi powiązanie z aplikacjami emulującymi karty NFC. Nie powinno być nigdy potrzebne w normalnych aplikacjach."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tworzenie powiązania z usługą tekstową"</string>
@@ -442,7 +442,7 @@
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisywanie rejestru połączeń"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Zezwala aplikacji na modyfikowanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Zezwala aplikacji na modyfikowanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
-    <string name="permlab_readProfile" msgid="4701889852612716678">"odczyt własnej karty kontaktu"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"odczytywanie własnej karty kontaktu"</string>
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Pozwala aplikacji na odczyt osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
     <string name="permlab_writeProfile" msgid="907793628777397643">"zmiana własnej karty kontaktu"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pozwala aplikacji na zmianę lub dodanie osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
@@ -597,7 +597,7 @@
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Pozwala aplikacji na konfigurowanie lokalnego telefonu z funkcją Bluetooth oraz na wykrywanie urządzeń zdalnych i parowanie z nimi."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"łączenie się i rozłączanie z siecią WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Pozawala aplikacji określić, czy obsługa WiMAX jest włączona, oraz uzyskać informacje o wszystkich podłączonych sieciach WiMAX."</string>
-    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Zmień stan WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"zmienianie stanu WiMAX"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Pozwala aplikacji na nawiązywanie i kończenie połączeń z sieciami WiMAX w tablecie."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Pozwala aplikacji na nawiązywanie i kończenie połączeń z sieciami WiMAX w telefonie."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"parowanie z urządzeniami Bluetooth"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Anulowane"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Błąd podczas zapisu treści"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"brak informacji"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Podaj PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Bieżący PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nowy PIN"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index cd26fc7..810b5b3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o titular vincule a interface de nível superior de um serviço de acessibilidade. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"vincular a um serviço de impressão"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o titular vincule a interface de nível superior de um serviço de impressão. Nunca deverá ser necessário para aplicações normais."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"aceder a todas as tarefas de impressão"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite que o titular aceda a tarefas de impressão criadas por outra aplicação. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"vincular a um serviço spooler de impressão"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite que o titular vincule a interface de nível superior de um serviço spooler de impressão. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"vincular a serviço NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao titular vincular a aplicações que recriam cartões NFC. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a um serviço de texto"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelada"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao escrever conteúdo"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduzir PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Atual"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 22c5774..f457e21 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o proprietário use a interface de nível superior de um serviço de acessibilidade. Nunca deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"associar a um serviço de impressão"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o proprietário use a interface de nível superior de um serviço de impressão. Não deve ser necessário para aplicativos comuns."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acessar todos os trabalhos de impressão"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite que o proprietário acesse trabalhos de impressão criados por outro aplicativo. Não deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"associar a um serviço de spooler de impressão"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite que o proprietário use a interface de nível superior de um serviço de spooler de impressão. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"associar ao serviço NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao proprietário associar a aplicativos que emulam cartões NFC. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao gravar o conteúdo"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Insira o PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN atual"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 84632f9..74830ef 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -561,9 +561,9 @@
     <skip />
     <!-- no translation found for permdesc_bindPrintService (7960067623209111135) -->
     <skip />
-    <!-- no translation found for permlab_accessAllPrintJobs (1120792468465711159) -->
+    <!-- no translation found for permlab_bindPrintSpoolerService (6807762783744125954) -->
     <skip />
-    <!-- no translation found for permdesc_accessAllPrintJobs (2978185311041864762) -->
+    <!-- no translation found for permdesc_bindPrintSpoolerService (3680552285933318372) -->
     <skip />
     <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
     <skip />
@@ -2576,6 +2576,8 @@
     <skip />
     <!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
     <skip />
+    <!-- no translation found for reason_unknown (6048913880184628119) -->
+    <skip />
     <!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
     <skip />
     <!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index aad5797..4ab2b43 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu de accesibilitate. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"conectarea la un serviciu de printare"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de printare. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acces la toate procesele de printare"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite proprietarului să acceseze procesele de printare create de o altă aplicație. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"conectare la un serviciu derulator de printare"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu derulator de printare. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"conectare la serviciul NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite aplicației autorizate să se asocieze cu aplicații care emulează carduri NFC. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"conectare la un serviciu text"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Anulat"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Eroare la scrierea conținutului"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"necunoscut"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduceți codul PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Codul PIN actual"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Codul PIN nou"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e32b6de..5635381 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Приложение сможет подключаться к базовому интерфейсу службы специальных возможностей. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"Подключение к службе печати"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Приложение сможет подключаться к базовому интерфейсу службы печати. Это разрешение не используется обычными приложениями."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Доступ к заданиям печати"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Владелец сможет просматривать задания печати, созданные другими приложениями. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"подключение к спулеру печати"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Приложение сможет подключаться к базовому интерфейсу спулера печати. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"подключаться к службе NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Приложение сможет подключаться к программам с имитацией карт NFC. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Подключение к службе текстовых сообщений"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid (279 х 432 мм)"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Печать отменена"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ошибка записи"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"неизвестно"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Введите PIN-код"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Текущий PIN-код"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Новый PIN-код"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 3a01bad..50aa81c 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ප‍්‍රවේශ්‍යතා සේවාවේ ඉහළ මට්ටමේ අතුරුමුහුණතට බැඳීමට දරන්නාට අවසර දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිවිටක අවශ්‍ය නොවේ."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"මුද්‍රණ සේවාවකට බද්ධ වී ඇත"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"මුද්‍රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"සියලු මුද්‍රණ කාර්යයන් වෙත පිවිසෙන්න"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"වෙනත් යෙදුමකින් සෑදු මුද්‍රණ කාර්ය වෙත පිවිසීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"මුද්‍රණ සේවාවකට බද්ධ වී ඇත"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"මුද්‍රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC සේවාව වෙත බැඳෙන්න"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC කාඩ් පත් ආදර්ශනය කරන යෙදුම් රඳවනයට සම්බන්ධ වීමට ඉඩ දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"පෙළ සේවාවකට බඳින්න"</string>
@@ -1571,6 +1571,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"කුඩා පුවත්පත"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"අවලංගු කරන ලදි"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"අන්තර්ගතය ලිවීමේදී දෝෂයකි"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"නොදනී"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN එක ඇතුළු කරන්න"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"වත්මන් PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"නව PIN"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 49486675..b4ba202 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby zjednodušeného ovládania. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"viazanie na tlačovú službu"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tlačovej služby. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"prístup ku všetkým tlačovým úlohám"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Umožňuje držiteľovi prístup k tlačovým úlohám vytvoreným inou aplikáciou. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"väzba na tlačovú službu"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tlačovej služby. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"previazať so službou NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umožňuje držiteľovi previazať sa s aplikáciami, ktoré vydávajú karty NFC. Bežné aplikácie toto povolenie nikdy nepotrebujú."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"väzba na textovú službu"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Zrušené"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Pri zapisovaní obsahu došlo ku chybe"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"neznáme"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Zadajte kód PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuálny kód PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nový kód PIN"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 04c2adf..3336dab 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lastniku omogoča povezovanje z vmesnikom najvišje ravni storitve za ljudi s posebnimi potrebami. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"povezava s storitvijo tiskanja"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lastniku omogoča povezovanje z vmesnikom storitve tiskanja najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"dostop do vseh tiskalnih poslov"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lastniku omogoča dostop do tiskalnih poslov, ki jih je ustvarila druga aplikacija. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"povezava s storitvijo čakalne vrste za tiskanje"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lastniku omogoča povezovanje z vmesnikom storitve čakalne vrste za tiskanje najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"povezava s storitvijo NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Dovoljuje, da se lastnik poveže z aplikacijami, ki posnemajo kartice za NFC. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"poveži z besedilno storitvijo"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Preklicano"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Napaka pri pisanju vsebine"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"neznano"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Vnesite PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 26de499..d66f18c 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозвољава власнику да се повеже са интерфејсом услуге приступачности највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"повезивање са услугом штампања"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Дозвољава власнику да се повеже са интерфејсом услуге штампања највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"приступ свим задацима за штампање"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Дозвољава власнику да приступа задацима за штампање које је направила друга апликација. Уобичајене апликације никада не би требало да је користе."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"повезивање са услугом штампања из меморије"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге штампања из меморије. Не би требало никада да буде потребно за нормалне апликације."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"повезивање са NFC услугом"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Дозвољава власнику да се повеже са апликацијама које опонашају NFC картице. Никада не би требало да буде потребно за обичне апликације."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обавезивање на текстуалну услугу"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Отказано је"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Грешка при исписивању садржаја"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"непознато"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Унесите PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Актуелни PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Нови PIN"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3eac87f..00aa419 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en tillgänglighetstjänst. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"binda till en utskriftstjänst"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en utskriftstjänst. Ska inte behövas för vanliga appar."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"få tillgång till alla utskriftsjobb"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ger innehavaren tillgång till utskriftsjobb som skapas med en annan app. Ska inte behövas för normala appar."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"binda till en utskriftskö"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en utskriftskö. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"låsa till NFC-tjänsten"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Innehavaren får låsa appar som fungerar som NFC-kort. Behövs normalt inte för vanliga appar."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind till en texttjänst"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Inställd"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Det gick inte att skriva innehållet"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"okänt"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ange pinkod"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuell pinkod"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny pinkod"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 58f8723..b7b6506 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -160,9 +160,9 @@
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mtindo wa kimya"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sauti Imezimwa"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sauti imewashwa"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modi ya ndege"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Hali ya ndege"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Hali ya ndege IMEWASHWA"</string>
-    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modi ya ndege IMEZIMWA"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Hali ya ndege IMEZIMWA"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Inamuruhusu mmiliki kufunga kipengee kinachojitokeza katika nyanja mbalimbali za kiwango cha juu cha huduma ya afikiaji. Hapaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"tundika kwenye huduma ya kuchapisha"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Inaruhusu kishikiliaji kujifungilia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"fikia kazi zote za kuchapisha"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Huruhusu mmiliki kufikia kazi za kuchapisha zilizoundwa na programu nyingine. Haipaswi kuhitajika kwa programu za kawaida kamwe."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"Fungia kwenye huduma ya kuchapisha"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Inaruhusu mtumiaji kujifungia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"funga kwenye huduma za NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Huruhusu mmiliki kufunga kwa programu zinazoiga kadi za NFC. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
@@ -555,7 +555,7 @@
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"rekebisha ukubwa wa mandhari yako"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Inaruhusu programu kuweka vidokezo vya ukubwa wa mandhari ya mfumo."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"weka upya mfumo kwa chaguo-msingi za kiwanda"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"Huruhusu programu kurudisha mfumo kwenye mipangilio yake ya mwanzo, hatua ambayo hufuta data, usanidi, na programu zote zilizosanikishwa."</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Huruhusu programu kurudisha mfumo kwenye mipangilio yake ya mwanzo, hatua ambayo hufuta data, mipangilio, na programu zote zilizosanikishwa."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"weka muda"</string>
     <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Inaruhusu programu kubadilisha wakati wa saa ya kompyuta kibao."</string>
     <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Inaruhusu programu kubadilisha wakati wa saa ya simu."</string>
@@ -1121,7 +1121,7 @@
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Wezesha tena hii katika mipangilio ya Mfumo &gt; Programu &gt;  iliyopakuliwa."</string>
     <string name="smv_application" msgid="3307209192155442829">"Programu <xliff:g id="APPLICATION">%1$s</xliff:g>  (utaratibu  <xliff:g id="PROCESS">%2$s</xliff:g>) imeenda kinyume na sera yake ya StrictMode."</string>
     <string name="smv_process" msgid="5120397012047462446">"Shughuli ya <xliff:g id="PROCESS">%1$s</xliff:g> imeenda kinyume na kulazimisha sera yake ya StrictMode."</string>
-    <string name="android_upgrading_title" msgid="1584192285441405746">"Android inapandishwa gredi..."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Toleo jipya la Android linawekwa..."</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Inasadifisha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> ya <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Inamaliza kuwasha."</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Kijigazeti"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Imeghairiwa"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Hitilafu katika kuandika maudhui"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"haijulikani"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ingiza PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ya sasa"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN mpya"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 54728fb..376ee26 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"อนุญาตให้เจ้าของเชื่อมโยงกับส่วนติดต่อระดับบนสุดของบริการการเข้าถึง ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"เชื่อมโยงกับบริการการพิมพ์"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"อนุญาตให้ผู้ใช้เชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการการพิมพ์ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"เข้าถึงงานพิมพ์ทั้งหมด"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"อนุญาตให้ผู้ใช้สามารถเข้าถึงงานพิมพ์ที่สร้างโดยแอปอื่นได้ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"เชื่อมโยงกับบริการจัิดคิวและจัดการการพิมพ์"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"อนุญาตให้ผู้ใช้เชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการจัดคิวและจัดการการพิมพ์ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"เชื่อมโยงกับบริการ NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"อนุญาตให้ผู้ถือเชื่อมโยงกับแอปพลิเคชันที่เลียนแบบการ์ด NFC ไม่จำเป็นสำหรับแอปทั่วไป"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"เชื่อมโยงกับบริการข้อความ"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ยกเลิก"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ข้อผิดพลาดในการเขียนเนื้อหา"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ไม่ทราบ"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ป้อน PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ปัจจุบัน"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN ใหม่"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 1bd10ae..b6bca5d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Binibigyang-daan ang may-ari na sumailalim sa nasa nangungunang antas na interface ng isang serbisyo sa accessibility. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"sumailalim sa isang serbisyo sa pag-print"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Nagbibigay-daan sa may-ari na sumailalim sa interface sa nangungunang antas ng isang serbisyo sa pag-print. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"i-access ang lahat ng pag-print"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Nagbibigay-daan sa may-ari na i-access ang mga pag-print na ginawa ng ibang app. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"mag-bind sa isang serbisyo ng print spooler"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Nagbibigay-daan sa may-ari na mag-bind sa interface sa nangungunang antas ng isang serbisyo ng print spooler. Hindi dapat kailanganin para sa normal na apps."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"i-bind sa serbisyo ng NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Nagbibigay-daan sa may-ari na mag-bind sa mga application na nag-e-emulate ng mga NFC card. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sumailalim sa serbisyo ng teksto"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kinansela"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"May error sa pagsusulat ng nilalaman"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"hindi alam"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ilagay ang PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Kasalukuyang PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Bagong PIN"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 5ab9165..44168d2 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"İzin sahibine bir erişilebilirlik hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"bir yazdırma hizmetine bağlan"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"İzin sahibine, bir yazdırma hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"tüm yazdırma işlerine eriş"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"İzin sahibine, başka uygulama tarafından oluşturulan yazdırma işlerine erişim izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bir yazdırma biriktirici hizmetine bağlan"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"İzin sahibine, bir yazdırma biriktirici hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC hizmetine bağla"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"İzin sahibine, NFC kartlara öykünen uygulamalara bağlama izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"İptal edildi"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"İçerik yazılırken hata oluştu"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"bilinmiyor"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN\'i girin"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Mevcut PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 8877a05..2dcb546 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби доступності. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"прив’язуватися до служби друку"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби друку. Ніколи не застосовується для звичайних програм."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"отримувати доступ до всіх завдань друку"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Дозволяє власнику отримувати доступ до завдань друку, створених в іншій програмі. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"прив’язуватися до служби спулера друку"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби спулера друку. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"прив’язуватися до служби NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Дозволяє власникові прив’язуватися до програм, які емулюють картки NFC. Ніколи не використовується звичайними програмами."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"прив’язати до текстової служби"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Скасовано"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Помилка записування вмісту"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"невідомо"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Введіть PIN-код"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Поточний PIN-код"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Новий PIN-код"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 5e1a9ae..0f417fe 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ truy cập. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"liên kết với dịch vụ in"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ in. Không cần thiết cho các ứng dụng thông thường."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"truy cập tất cả các lệnh in"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Cho phép chủ sở hữu truy cập các lệnh in được tạo ra bởi ứng dụng khác. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"liên kết với dịch vụ bộ đệm in"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ bộ đệm in. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"liên kết với dịch vụ NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Cho phép chủ sở hữu liên kết với ứng dụng đang mô phỏng thẻ NFC. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"liên kết với dịch vụ văn bản"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Đã hủy"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Lỗi ghi nội dung"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"không xác định"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Nhập mã PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Mã PIN hiện tại"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Mã PIN mới"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 529997b..3bd2566 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允许应用绑定至辅助服务的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"绑定至打印服务"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"允许应用绑定至打印服务的顶级接口。普通应用绝不需要此权限。"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"查看或修改所有打印作业"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"允许应用查看或修改其他应用创建的打印作业。普通应用绝不需要此权限。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"绑定至打印后台处理程序服务"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允许应用绑定至打印后台处理程序服务的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"绑定到 NFC 服务"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"允许应用绑定到模拟 NFC 卡的应用。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"绑定至文字服务"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"写入内容时出错"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"未知"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"输入 PIN 码"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"当前 PIN 码"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新 PIN 码"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 0252a81..c27890f 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (不建議一般應用程式使用)。"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"繫結至列印服務"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"允許應用程式繫結至列印服務的頂層介面 (不建議一般應用程式使用)。"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"存取所有列印工作"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"允許應用程式存取其他應用程式所建立的列印工作 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"繫結至列印多工緩衝處理器服務"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允許應用程式繫結至列印多工緩衝處理器服務的頂層介面 (不建議一般應用程式使用)。"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"繫結至 NFC 服務"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"允許應用程式繫結至模擬 NFC 卡的應用程式 (不建議一般應用程式使用)。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"寫入內容時發生錯誤"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"輸入 PIN 碼"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"目前的 PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新的 PIN"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5b8d8e8..571e01c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"繫結至列印服務"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"允許應用程式繫結至列印服務的頂層介面 (一般應用程式並不需要)。"</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"存取所有列印工作"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"允許應用程式存取其他應用程式所建立的列印工作 (一般應用程式並不需要)。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"繫結至列印多工緩衝處理器服務"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允許應用程式繫結至列印多工緩衝處理器服務的頂層介面 (一般應用程式並不需要)。"</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"繫結至 NFC 服務"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"允許應用程式繫結至模擬 NFC 卡的應用程式 (一般應用程式並不需要)。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"寫入內容時發生錯誤"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"輸入 PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"目前的 PIN"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新 PIN"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 3ff3303..c0b5c86 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -360,8 +360,8 @@
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ivumela isibambi ukuhlanganisa uxhumo nomsebenzisi kwezinga eliphezulu lesevisi yesinqunjwana. Akusoze kwadingekela izinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindPrintService" msgid="8462815179572748761">"bophezela kusevisi yokuphrinta"</string>
     <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ivumela umnikazi ukuthi abophezele isixhumanisi esibonakalayo sezinga eliphezulu sesevisi lokuphrinta. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
-    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"finyelela kuyo yonke imisebenzi yokuphrinta"</string>
-    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ivumela umnikazi ukuthi afinyelele imisebenzi yokushicilela edalwe olunye uhlelo lokusebenza. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bophezela kusevisi yendawo yokuphrinta"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ivumela umnikazi ukuthi abophezele isixhumanisi esibonakalayo sezinga eliphezulu sesevisi yendawo yokuphrinta. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_bindNfcService" msgid="2752731300419410724">"bophezela kusevisi ye-NFC"</string>
     <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ivumela umnikazi ukuthi abophezele izinhlelo zokusebenza ezifana namakhadi we-NFC. Akumele idingeke kuzinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bophezela kunsizakalo yombhalo"</string>
@@ -1568,6 +1568,7 @@
     <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Iphephandaba"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kukhanseliwe"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Iphutha ekubhaleni okuqukethwe"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"akwaziwa"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Faka i-PIN"</string>
     <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"I-PIN yamanje"</string>
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"I-PIN entsha"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f8cffa7..a47e518 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2611,6 +2611,9 @@
         <!-- Whether the device must be unlocked before routing data to this service.
              The default is false.-->
         <attr name="requireDeviceUnlock" format="boolean"/>
+        <!-- A drawable that can be rendered in Android's system UI for representing
+             the service. -->
+        <attr name="apduServiceBanner" format="reference"/>
     </declare-styleable>
 
     <!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
@@ -2621,6 +2624,9 @@
         <!-- Short description of the functionality the service implements. This attribute
              is mandatory.-->
         <attr name="description" />
+        <!-- A drawable that can be rendered in Android's system UI for representing
+             the service. -->
+        <attr name="apduServiceBanner"/>
     </declare-styleable>
 
     <!-- Specify one or more <code>aid-group</code> elements inside a
@@ -4505,24 +4511,71 @@
     </declare-styleable>
 
     <!-- ========================== -->
-    <!-- State class attributes -->
+    <!-- Transition attributes -->
     <!-- ========================== -->
     <eat-comment />
 
-    <declare-styleable name="Scene">
-        <attr name="layout" />
-    </declare-styleable>
-
+    <!-- Use specific transition subclass names as the root tag of the XML resource that
+         describes a {@link android.transition.Transition Transition},
+         such as <code>move</code>, <code>fade</code>, and <code>set</code>. -->
     <declare-styleable name="Transition">
+        <!-- Amount of time (in milliseconds) that the transition should run. -->
         <attr name="duration" />
-        <attr name="startOffset" />
+        <!-- Delay in milliseconds before the transition starts. -->
+        <attr name="startDelay" format="integer" />
+        <!-- Interpolator to be used in the animations spawned by this transition. -->
         <attr name="interpolator" />
-        <attr name="targetID" format="reference" />
     </declare-styleable>
 
+    <!-- Use <code>fade</code>as the root tag of the XML resource that
+         describes a {@link android.transition.Fade Fade} transition.
+         The attributes of the {@link android.R.styleable#Transition Transition}
+         resource are available in addition to the specific attributes of Fade
+         described here. -->
+    <declare-styleable name="Fade">
+        <attr name="fadingMode">
+            <!-- Fade will only fade appearing items in. -->
+            <enum name="fade_in" value="1" />
+            <!-- Fade will only fade disappearing items out. -->
+            <enum name="fade_out" value="2" />
+            <!-- Fade will fade appearing items in and disappearing items out. -->
+            <enum name="fade_in_out" value="3" />
+        </attr>
+    </declare-styleable>
+
+    <!-- Use <code>target</code> as the root tag of the XML resource that
+     describes a {@link android.transition.Transition#addTargetId(int)
+     targetId} of a transition. There can be one or more targets inside
+     a <code>targets</code> tag, which is itself inside an appropriate
+     {@link android.R.styleable#Transition Transition} tag.
+     -->
+    <declare-styleable name="TransitionTarget">
+        <!-- The id of a target on which this transition will animate changes. -->
+        <attr name="targetId" format="reference" />
+    </declare-styleable>
+
+    <!-- Use <code>set</code> as the root tag of the XML resource that
+         describes a {@link android.transition.TransitionSet
+         TransitionSet} transition. -->
+    <declare-styleable name="TransitionSet">
+        <attr name="transitionOrdering">
+            <!-- child transitions should be played together. -->
+            <enum name="together" value="0" />
+            <!-- child transitions should be played sequentially, in the same order
+            as the xml. -->
+            <enum name="sequential" value="1" />
+        </attr>
+    </declare-styleable>
+
+    <!-- Use <code>transitionManager</code> as the root tag of the XML resource that
+         describes a {@link android.transition.TransitionManager
+         TransitionManager}. -->
     <declare-styleable name="TransitionManager">
+        <!-- The id of a transition to be used in a particular scene change. -->
         <attr name="transition" format="reference" />
+        <!-- The originating scene in this scene change. -->
         <attr name="fromScene" format="reference" />
+        <!-- The destination scene in this scene change. -->
         <attr name="toScene" format="reference" />
     </declare-styleable>
 
@@ -5749,11 +5802,11 @@
          describes an injected "Location services" setting. Note that the status value (subtitle)
          for the setting is specified dynamically by a subclass of SettingInjectorService.
      -->
-    <declare-styleable name="InjectedLocationSetting">
-        <!-- The user-visible name (title) of the setting. -->
-        <attr name="label"/>
-        <!-- The icon for the apps covered by the setting. Typically a generic icon for the
-             developer. -->
+    <declare-styleable name="SettingInjectorService">
+        <!-- The title for the preference. -->
+        <attr name="title"/>
+        <!-- The icon for the preference, should refer to all apps covered by the setting. Typically
+             a generic icon for the developer. -->
         <attr name="icon"/>
         <!-- The activity to launch when the setting is clicked on. -->
         <attr name="settingsActivity"/>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d4a408d..dd233c5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -774,6 +774,9 @@
          re-validation -->
     <bool name="config_bluetooth_address_validation">false</bool>
 
+    <!-- Boolean indicating if current platform supports BLE peripheral mode -->
+    <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
+
     <!-- The default data-use polling period. -->
     <integer name="config_datause_polling_period_sec">600</integer>
 
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 21bae04..15df295 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -80,4 +80,5 @@
   <item type="id" name="overflow_menu_presenter" />
   <item type="id" name="popup_submenu_presenter" />
   <item type="id" name="action_bar_spinner" />
+  <item type="id" name="current_scene" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 696e782..6c3856e 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2059,10 +2059,13 @@
   <eat-comment />
 
   <public type="attr" name="keyset" />
-  <public type="attr" name="targetID" />
+  <public type="attr" name="targetId" />
   <public type="attr" name="fromScene" />
   <public type="attr" name="toScene" />
   <public type="attr" name="transition" />
+  <public type="attr" name="transitionOrdering" />
+  <public type="attr" name="fadingMode" />
+  <public type="attr" name="startDelay" />
   <public type="attr" name="ssp" />
   <public type="attr" name="sspPrefix" />
   <public type="attr" name="sspPattern" />
@@ -2074,5 +2077,7 @@
   <public type="attr" name="autoMirrored" />
   <public type="attr" name="supportsSwitchingToNextInputMethod" />
   <public type="attr" name="requireDeviceUnlock" />
+  <public type="attr" name="apduServiceBanner" />
+  <public type="attr" name="provideAssistData" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4b32e2b..aa04bf6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3970,11 +3970,6 @@
     <!-- Title for a dialog showing possible activities for sharing in ShareActionProvider [CHAR LIMIT=25] -->
     <string name="share_action_provider_share_with">Share with</string>
 
-    <!-- Status Bar icon descriptions -->
-
-    <!-- Description of for the status bar's icon that the device is locked for accessibility. [CHAR LIMIT=NONE] -->
-    <string name="status_bar_device_locked">Device locked.</string>
-
     <!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
     <string name="list_delimeter">", "</string>
 
@@ -4296,8 +4291,12 @@
     <!-- Print fail reason: unknown. [CHAR LIMIT=25] -->
     <string name="reason_unknown">unknown</string>
 
+    <!-- PIN entry dialog title for entering the administrator PIN [CHAR LIMIT=none] -->
+    <string name="restr_pin_enter_admin_pin">Enter administrator PIN</string>
     <!-- PIN entry dialog label/hint for PIN [CHAR LIMIT=none] -->
     <string name="restr_pin_enter_pin">Enter PIN</string>
+    <!-- PIN entry dialog label/hint for incorrect PIN entry [CHAR LIMIT=none] -->
+    <string name="restr_pin_incorrect">Incorrect</string>
     <!-- PIN entry dialog label/hint for old PIN [CHAR LIMIT=none] -->
     <string name="restr_pin_enter_old_pin">Current PIN</string>
     <!-- PIN entry dialog label for new PIN [CHAR LIMIT=none] -->
@@ -4313,9 +4312,11 @@
     <!-- PIN entry dialog countdown message for next chance to enter the PIN [CHAR LIMIT=none] -->
     <!-- Phrase describing a time duration using seconds [CHAR LIMIT=16] -->
     <plurals name="restr_pin_countdown">
-        <item quantity="one">Incorrect PIN. Try again in 1 second.</item>
-        <item quantity="other">Incorrect PIN. Try again in <xliff:g id="count">%d</xliff:g> seconds.</item>
+        <item quantity="one">Try again in 1 second</item>
+        <item quantity="other">Try again in <xliff:g id="count">%d</xliff:g> seconds</item>
     </plurals>
+    <!-- PIN entry dialog tells the user to not enter a PIN for a while. [CHAR LIMIT=none] -->
+    <string name="restr_pin_try_later">Try again later</string>
 
     <!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=35] -->
     <string name="transient_navigation_confirmation">Swipe edge of screen to reveal bar</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f008b10..fcd56eb2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -54,6 +54,7 @@
   <java-symbol type="id" name="characterPicker" />
   <java-symbol type="id" name="clearDefaultHint" />
   <java-symbol type="id" name="contentPanel" />
+  <java-symbol type="id" name="current_scene" />
   <java-symbol type="id" name="customPanel" />
   <java-symbol type="id" name="datePicker" />
   <java-symbol type="id" name="day" />
@@ -212,7 +213,8 @@
   <java-symbol type="id" name="sms_short_code_remember_undo_instruction" />
   <java-symbol type="id" name="breadcrumb_section" />
   <java-symbol type="id" name="action_bar_spinner" />
-  <java-symbol type="id" name="pin_message" />
+  <java-symbol type="id" name="pin_cancel_button" />
+  <java-symbol type="id" name="pin_ok_button" />
   <java-symbol type="id" name="pin_text" />
   <java-symbol type="id" name="pin_new_text" />
   <java-symbol type="id" name="pin_confirm_text" />
@@ -248,6 +250,7 @@
   <java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
   <java-symbol type="bool" name="config_bluetooth_address_validation" />
   <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
+  <java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
   <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
   <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
   <java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
@@ -870,7 +873,10 @@
   <java-symbol type="string" name="mediaSize_na_ledger" />
   <java-symbol type="string" name="mediaSize_na_tabloid" />
   <java-symbol type="string" name="reason_unknown" />
+  <java-symbol type="string" name="restr_pin_enter_admin_pin" />
   <java-symbol type="string" name="restr_pin_enter_pin" />
+  <java-symbol type="string" name="restr_pin_incorrect" />
+  <java-symbol type="string" name="restr_pin_try_later" />
   <java-symbol type="string" name="write_fail_reason_cancelled" />
   <java-symbol type="string" name="write_fail_reason_cannot_write" />
   <java-symbol type="string" name="transient_navigation_confirmation" />
@@ -1244,7 +1250,6 @@
   <java-symbol type="drawable" name="jog_tab_target_yellow" />
   <java-symbol type="drawable" name="magnified_region_frame" />
   <java-symbol type="drawable" name="menu_background" />
-  <java-symbol type="drawable" name="stat_sys_secure" />
   <java-symbol type="id" name="action_mode_bar_stub" />
   <java-symbol type="id" name="button0" />
   <java-symbol type="id" name="button4" />
@@ -1307,7 +1312,6 @@
   <java-symbol type="string" name="global_action_toggle_silent_mode" />
   <java-symbol type="string" name="invalidPuk" />
   <java-symbol type="string" name="lockscreen_carrier_default" />
-  <java-symbol type="string" name="status_bar_device_locked" />
   <java-symbol type="style" name="Animation.LockScreen" />
   <java-symbol type="style" name="Theme.Dialog.RecentApplications" />
   <java-symbol type="style" name="Theme.ExpandedMenu" />
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 1f38ddb..89d102d 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -126,7 +126,6 @@
          interact with the system. -->
 
     <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
-    <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
     <assign-permission name="android.permission.WAKE_LOCK" uid="media" />
     <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 16d760c..d11a3c7 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -126,6 +126,30 @@
     </family>
     <family>
         <fileset>
+            <file variant="elegant">NotoSansKhmer-Regular.ttf</file>
+            <file variant="elegant">NotoSansKhmer-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansKhmerUI-Regular.ttf</file>
+            <file variant="compact">NotoSansKhmerUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansLao-Regular.ttf</file>
+            <file variant="elegant">NotoSansLao-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansLaoUI-Regular.ttf</file>
+            <file variant="compact">NotoSansLaoUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
             <file>NanumGothic.ttf</file>
         </fileset>
     </family>
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index a66a884..898efe8 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -21,17 +21,21 @@
 # Validate all key maps.
 include $(CLEAR_VARS)
 
-validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
-files := \
-    $(foreach file,$(keylayouts),frameworks/base/data/keyboards/$(file)) \
-    $(foreach file,$(keycharmaps),frameworks/base/data/keyboards/$(file)) \
-    $(foreach file,$(keyconfigs),frameworks/base/data/keyboards/$(file))
-
 LOCAL_MODULE := validate_framework_keymaps
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := validatekeymaps
+intermediates := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE),,COMMON)
+LOCAL_BUILT_MODULE := $(intermediates)/stamp
 
-validate_framework_keymaps: $(files)
-	$(hide) $(validatekeymaps) $(files)
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
+$(LOCAL_BUILT_MODULE) : $(framework_keylayouts) $(framework_keycharmaps) $(framework_keyconfigs) | $(validatekeymaps)
+	$(hide) $(PRIVATE_VALIDATEKEYMAPS) $^
+	$(hide) mkdir -p $(dir $@) && touch $@
 
-include $(BUILD_PHONY_PACKAGE)
+# Run validatekeymaps uncondionally for platform build.
+droidcore all_modules : $(LOCAL_BUILT_MODULE)
+
+# Reset temp vars.
+validatekeymaps :=
+framework_keylayouts :=
+framework_keycharmaps :=
+framework_keyconfigs :=
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
index 87c2ef5..d75b691 100644
--- a/data/keyboards/common.mk
+++ b/data/keyboards/common.mk
@@ -15,8 +15,8 @@
 # This is the list of framework provided keylayouts and key character maps to include.
 # Used by Android.mk and keyboards.mk.
 
-keylayouts := $(notdir $(wildcard $(LOCAL_PATH)/*.kl))
+framework_keylayouts := $(wildcard $(LOCAL_PATH)/*.kl)
 
-keycharmaps := $(notdir $(wildcard $(LOCAL_PATH)/*.kcm))
+framework_keycharmaps := $(wildcard $(LOCAL_PATH)/*.kcm)
 
-keyconfigs := $(notdir $(wildcard $(LOCAL_PATH)/*.idc))
+framework_keyconfigs := $(wildcard $(LOCAL_PATH)/*.idc)
diff --git a/data/keyboards/keyboards.mk b/data/keyboards/keyboards.mk
index c964961..d545241 100644
--- a/data/keyboards/keyboards.mk
+++ b/data/keyboards/keyboards.mk
@@ -16,11 +16,11 @@
 
 include $(LOCAL_PATH)/common.mk
 
-PRODUCT_COPY_FILES := $(foreach file,$(keylayouts),\
-    frameworks/base/data/keyboards/$(file):system/usr/keylayout/$(file))
+PRODUCT_COPY_FILES := $(foreach file,$(framework_keylayouts),\
+    $(file):system/usr/keylayout/$(file))
 
-PRODUCT_COPY_FILES += $(foreach file,$(keycharmaps),\
-    frameworks/base/data/keyboards/$(file):system/usr/keychars/$(file))
+PRODUCT_COPY_FILES += $(foreach file,$(framework_keycharmaps),\
+    $(file):system/usr/keychars/$(file))
 
-PRODUCT_COPY_FILES += $(foreach file,$(keyconfigs),\
-    frameworks/base/data/keyboards/$(file):system/usr/idc/$(file))
+PRODUCT_COPY_FILES += $(foreach file,$(framework_keyconfigs),\
+    $(file):system/usr/idc/$(file))
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 6e4a03c..ff19476 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -30,16 +30,20 @@
 <p>This page provides information about the relative number of devices that share a certain
 characteristic, such as Android version or screen size. This information may
 help you prioritize efforts for <a
-href="{@docRoot}training/basics/supporting-devices/index.html">supporting different devices</a>.</p>
+href="{@docRoot}training/basics/supporting-devices/index.html">supporting different devices</a>
+by revealing which devices are active in the Android and Google Play ecosystem.</p>
 
-<p>Each snapshot of data represents all the devices that visited the Google Play Store in the
-prior 14 days.</p>
+<p>This data reflects devices running the latest Google Play Store app, which is compatible
+with Android 2.2 and higher. Each snapshot of data represents all the devices that visited the
+Google Play Store in the prior 7 days.</p>
 
-<p class="note"><strong>Note:</strong> Beginning in April, 2013, these charts are now built
-using data collected from each device when the user visits the Google Play Store. Previously, the
-data was collected when the device simply checked-in to Google servers. We believe the new
-data more accurately reflects those users who are most engaged in the Android and Google Play
-ecosystem.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Beginning in September, 2013, devices running versions older than Android
+2.2 do not appear in this data because those devices do not support the new Google Play Store
+app. Only the new app is able to measure the number of devices that actively visit Google Play Store
+and we believe this measurement best reflects your potential user-base.</p>
+</div>
 
 
 <h2 id="Platform">Platform Versions</h2>
@@ -57,10 +61,15 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2013.
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2013.
 <br/>Any versions with less than 0.1% distribution are not shown.</em>
 </p>
 
+<p class="note"><strong>Note:</strong> Because this data is gathered from the new Google Play
+Store app, which supports Android 2.2 and above, devices running older versions are not included.
+However, in August, 2013, versions older than Android 2.2 accounted for about 1% of devices that
+<em>checked in</em> to Google servers (not those that actually visited Google Play Store).
+</p>
 
 
 
@@ -83,7 +92,7 @@
 </div>
 
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2013
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2013
 <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
 
 
@@ -130,7 +139,7 @@
 
 
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2013</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2013</em></p>
 
 
 
@@ -148,32 +157,17 @@
 var VERSION_DATA =
 [
   {
-    "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chl=Eclair%7CFroyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean&chf=bg%2Cs%2C00000000&chd=t%3A1.3%2C2.5%2C33.1%2C0.1%2C22.5%2C40.5&chco=c4df9b%2C6fad0c",
+    "chart": "//chart.googleapis.com/chart?chs=500x250&cht=p&chco=c4df9b%2C6fad0c&chd=t%3A2.4%2C30.7%2C0.1%2C21.7%2C45.1&chf=bg%2Cs%2C00000000&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean",
     "data": [
       {
-        "api": 4,
-        "name": "Donut",
-        "perc": "0.1"
-      },
-      {
-        "api": 7,
-        "name": "Eclair",
-        "perc": "1.2"
-      },
-      {
         "api": 8,
         "name": "Froyo",
-        "perc": "2.5"
-      },
-      {
-        "api": 9,
-        "name": "Gingerbread",
-        "perc": "0.1"
+        "perc": "2.4"
       },
       {
         "api": 10,
         "name": "Gingerbread",
-        "perc": "33.0"
+        "perc": "30.7"
       },
       {
         "api": 13,
@@ -183,17 +177,17 @@
       {
         "api": 15,
         "name": "Ice Cream Sandwich",
-        "perc": "22.5"
+        "perc": "21.7"
       },
       {
         "api": 16,
         "name": "Jelly Bean",
-        "perc": "34.0"
+        "perc": "36.6"
       },
       {
         "api": 17,
         "name": "Jelly Bean",
-        "perc": "6.5"
+        "perc": "8.5"
       }
     ]
   }
@@ -209,30 +203,29 @@
     "data": {
       "Large": {
         "hdpi": "0.4",
-        "ldpi": "0.5",
-        "mdpi": "3.2",
-        "tvdpi": "1.1",
+        "ldpi": "0.6",
+        "mdpi": "3.4",
+        "tvdpi": "1.2",
         "xhdpi": "0.5"
       },
       "Normal": {
-        "hdpi": "34.5",
+        "hdpi": "33.6",
         "ldpi": "0.1",
-        "mdpi": "15.9",
-        "xhdpi": "23.9",
-        "xxhdpi": "5.7"
+        "mdpi": "15.7",
+        "xhdpi": "23.1",
+        "xxhdpi": "7.1"
       },
       "Small": {
-        "hdpi": "0.1",
-        "ldpi": "9.7"
+        "ldpi": "9.5"
       },
       "Xlarge": {
-        "hdpi": "0.2",
-        "mdpi": "4.1",
+        "hdpi": "0.3",
+        "mdpi": "4.4",
         "xhdpi": "0.1"
       }
     },
-    "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A10.3%2C23.2%2C1.1%2C35.2%2C24.5%2C5.7&chco=c4df9b%2C6fad0c",
-    "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A4.4%2C5.7%2C80.2%2C9.8&chco=c4df9b%2C6fad0c"
+    "densitychart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chco=c4df9b%2C6fad0c&chd=t%3A10.2%2C23.5%2C1.2%2C34.3%2C23.7%2C7.1&chf=bg%2Cs%2C00000000&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi",
+    "layoutchart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chco=c4df9b%2C6fad0c&chd=t%3A4.8%2C6.1%2C79.6%2C9.5&chf=bg%2Cs%2C00000000&chl=Xlarge%7CLarge%7CNormal%7CSmall"
   }
 ];
 
@@ -294,6 +287,11 @@
     "api":17,
     "link":"<a href='/about/versions/android-4.2.html'>4.2.x</a>",
     "codename":"Jelly Bean"
+  },
+  {
+    "api":18,
+    "link":"<a href='/about/versions/android-4.3.html'>4.3</a>",
+    "codename":"Jelly Bean"
   }
 ];
 
diff --git a/docs/html/about/versions/android-4.0.jd b/docs/html/about/versions/android-4.0.jd
index 2fa180c..c026534 100644
--- a/docs/html/about/versions/android-4.0.jd
+++ b/docs/html/about/versions/android-4.0.jd
@@ -62,7 +62,7 @@
       <li><a href="#Multimedia">Multimedia</a></li>
       <li><a href="#Camera">Camera</a></li>
       <li><a href="#AndroidBeam">Android Beam (NDEF Push with NFC)</a></li>
-      <li><a href="#WiFiDirect">Wi-Fi Direct</a></li>
+      <li><a href="#WiFiDirect">Wi-Fi P2P</a></li>
       <li><a href="#Bluetooth">Bluetooth Health Devices</a></li>
       <li><a href="#A11y">Accessibility</a></li>
       <li><a href="#SpellChecker">Spell Checker Services</a></li>
@@ -617,12 +617,13 @@
 
 
 
-<h3 id="WiFiDirect">Wi-Fi Direct</h3>
+<h3 id="WiFiDirect">Wi-Fi P2P</h3>
 
-<p>Android now supports Wi-Fi Direct for peer-to-peer (P2P) connections between Android-powered
-devices and other device types without a hotspot or Internet connection. The Android framework
+<p>Android now supports Wi-Fi peer-to-peer (P2P) connections between Android-powered
+devices and other device types (in compliance with the Wi-Fi
+Alliance's Wi-Fi Direct&trade; certification program) without a hotspot or Internet connection. The Android framework
 provides a set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each
-device supports Wi-Fi Direct, then communicate over a speedy connection across distances much longer
+device supports Wi-Fi P2P, then communicate over a speedy connection across distances much longer
 than a Bluetooth connection.</p>
 
 <p>A new package, {@link android.net.wifi.p2p}, contains all the APIs for performing peer-to-peer
@@ -669,7 +670,7 @@
 <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
 <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
 <li>{@link android.Manifest.permission#INTERNET} (although your app doesn’t technically connect
-to the Internet, communicating to Wi-Fi Direct peers with standard java sockets requires Internet
+to the Internet, communicating to Wi-Fi P2P peers with standard java sockets requires Internet
 permission).</li>
 </ul>
 
@@ -696,7 +697,7 @@
 </ul>
 
 <p>See the  {@link android.net.wifi.p2p.WifiP2pManager} documentation for more information. Also
-look at the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a>
+look at the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a>
 sample application.</p>
 
 
diff --git a/docs/html/about/versions/android-4.1.jd b/docs/html/about/versions/android-4.1.jd
index d4b9ebf..76b90ac 100644
--- a/docs/html/about/versions/android-4.1.jd
+++ b/docs/html/about/versions/android-4.1.jd
@@ -41,7 +41,7 @@
     <ol>
       <li><a href="#AndroidBeam">Android Beam</a></li>
       <li><a href="#LocalNsd">Network service discovery</a></li>
-      <li><a href="#WiFiNsd">Wi-Fi Direct service discovery</a></li>
+      <li><a href="#WiFiNsd">Wi-Fi P2P service discovery</a></li>
       <li><a href="#NetworkUsage">Network usage</a></li>
     </ol>
   </li>
@@ -506,11 +506,11 @@
 
 
 
-<h3 id="WiFiNsd">Wi-Fi Direct service discovery</h3>
+<h3 id="WiFiNsd">Wi-Fi P2P service discovery</h3>
 
-<p>The Wi-Fi Direct APIs are enhanced in Android 4.1 to support pre-association service discovery in
+<p>The Wi-Fi P2P APIs are enhanced in Android 4.1 to support pre-association service discovery in
 the {@link android.net.wifi.p2p.WifiP2pManager}. This allows you to discover and filter nearby
-devices by services using Wi-Fi Direct before connecting to one, while Network Service
+devices by services using Wi-Fi P2P before connecting to one, while Network Service
 Discovery allows you to discover a service on an existing connected network (such as a local Wi-Fi
 network).</p>
 
diff --git a/docs/html/distribute/googleplay/promote/brand.jd b/docs/html/distribute/googleplay/promote/brand.jd
index 265584f..0bda561 100644
--- a/docs/html/distribute/googleplay/promote/brand.jd
+++ b/docs/html/distribute/googleplay/promote/brand.jd
@@ -21,8 +21,8 @@
     <ul>
     <li>Android&trade; should have a trademark symbol the first time it appears in a creative.</li>
     <li>Android should always be capitalized and is never plural or possessive.</li>
-    <li>"Android" by itself cannot be used in the name of an application name or accessory product.
-Instead use "for Android."
+    <li>"Android" cannot be used in names of applications or accessory products,
+    including phones, tablets, TVs, speakers, headphones, watches, and other devices. Instead use "for Android".
       <ul>
         <li><span style="color:red">Incorrect</span>: "Android MediaPlayer"</li>
         <li><span style="color:green">Correct</span>: "MediaPlayer for Android"</li>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 2a31374..21d295a 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -408,7 +408,7 @@
         </ul>
       </li>
       <li><a href="<?cs var:toroot?>guide/topics/connectivity/wifip2p.html">
-            <span class="en">Wi-Fi Direct</span></a>
+            <span class="en">Wi-Fi P2P</span></a>
           </li>
       <li class="nav-section">
           <div class="nav-section-header"><a href="<?cs var:toroot?>guide/topics/connectivity/usb/index.html">
diff --git a/docs/html/guide/topics/connectivity/wifip2p.jd b/docs/html/guide/topics/connectivity/wifip2p.jd
index 2167a0f..7cadde1 100644
--- a/docs/html/guide/topics/connectivity/wifip2p.jd
+++ b/docs/html/guide/topics/connectivity/wifip2p.jd
@@ -1,5 +1,5 @@
-page.title=Wi-Fi Direct
-page.tags="wireless","WifiP2pManager"
+page.title=Wi-Fi Peer-to-Peer
+page.tags="wireless","WifiP2pManager","Wi-Fi Direct","WiFi Direct","P2P","Wi-Fi P2P","WiFi P2P"
 
 @jd:body
 
@@ -9,10 +9,10 @@
 
       <ol>
         <li><a href="#api">API Overview</a></li>
-        <li><a href="#creating-br">Creating a Broadcast Receiver for Wi-Fi Direct Intents</a></li>
+        <li><a href="#creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</a></li>
 
         <li>
-          <a href="#creating-app">Creating a Wi-Fi Direct Application</a>
+          <a href="#creating-app">Creating a Wi-Fi P2P Application</a>
 
           <ol>
             <li><a href="#setup">Initial setup</a></li>
@@ -25,21 +25,24 @@
           </ol>
         </li>
       </ol>
-      <h2>Related Samples</h2>
-      <ol>
-        <li><a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a></li>
-      </ol>
+    <h2>See also</h2>
+    <ul>
+      <li><a href="{@docRoot}training/connect-devices-wirelessly/wifi-direct.html">Creating
+        P2P Connections with Wi-Fi</a></li>
+    </ul>
     </div>
   </div>
 
-  <p>Wi-Fi Direct allows Android 4.0 (API level 14) or later devices with the appropriate hardware
-  to connect directly to each other via Wi-Fi without an intermediate access point.
-  Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi Direct,
-  then communicate over a speedy connection across distances much longer than a Bluetooth connection.
-  This is useful for applications that share data among users, such as a multiplayer game or
-  a photo sharing application.</p>
 
-  <p>The Wi-Fi Direct APIs consist of the following main parts:</p>
+<p>Wi-Fi peer-to-peer (P2P) allows Android 4.0 (API level 14) or later devices with the appropriate
+hardware to connect directly to each other via Wi-Fi without an intermediate access point (Android's
+Wi-Fi P2P framework complies with the Wi-Fi Alliance's Wi-Fi Direct&trade; certification program).
+Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi P2P,
+then communicate over a speedy connection across distances much longer than a Bluetooth connection.
+This is useful for applications that share data among users, such as a multiplayer game or
+a photo sharing application.</p>
+
+  <p>The Wi-Fi P2P APIs consist of the following main parts:</p>
 
   <ul>
     <li>Methods that allow you to discover, request, and connect to peers are defined
@@ -50,7 +53,7 @@
     android.net.wifi.p2p.WifiP2pManager} methods, each method can receive a specific listener
     passed in as a parameter.</li>
 
-    <li>Intents that notify you of specific events detected by the Wi-Fi Direct framework,
+    <li>Intents that notify you of specific events detected by the Wi-Fi P2P framework,
     such as a dropped connection or a newly discovered peer.</li>
   </ul>
 
@@ -70,7 +73,7 @@
   the Wi-Fi hardware on your device to do things like discover and connect to peers. The following actions
   are available:</p>
 
-<p class="table-caption"><strong>Table 1.</strong>Wi-Fi Direct Methods</p>
+<p class="table-caption"><strong>Table 1.</strong>Wi-Fi P2P Methods</p>
 
    <table>
         <tr>
@@ -80,7 +83,7 @@
 
 	<tr>
 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</td>
-	  <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi Direct method.</td>
+	  <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi P2P method.</td>
 	</tr>
 
 	<tr>
@@ -126,12 +129,12 @@
 
 
  <p>{@link android.net.wifi.p2p.WifiP2pManager} methods let you pass in a listener,
-  so that the Wi-Fi Direct framework can notify your
+  so that the Wi-Fi P2P framework can notify your
   activity of the status of a call. The available listener interfaces and the
   corresponding {@link android.net.wifi.p2p.WifiP2pManager} method calls that use the listeners
   are described in the following table:</p>
 
- <p class="table-caption"><strong>Table 2.</strong> Wi-Fi Direct Listeners</p>
+ <p class="table-caption"><strong>Table 2.</strong> Wi-Fi P2P Listeners</p>
  
  <table>
     <tr>
@@ -168,12 +171,12 @@
     </tr>
   </table>
 
-<p>The Wi-Fi Direct APIs define intents that are broadcast when certain Wi-Fi Direct events happen,
+<p>The Wi-Fi P2P APIs define intents that are broadcast when certain Wi-Fi P2P events happen,
   such as when a new peer is discovered or when a device's Wi-Fi state changes. You can register
   to receive these intents in your application by <a href="#creating-br">creating a broadcast
   receiver</a> that handles these intents:</p>
 
-<p class="table-caption"><strong>Table 3.</strong> Wi-Fi Direct Intents</p>
+<p class="table-caption"><strong>Table 3.</strong> Wi-Fi P2P Intents</p>
 
     <table>
     <tr>
@@ -194,7 +197,7 @@
       </tr>
       <tr>
         <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}</td>
-        <td>Broadcast when Wi-Fi Direct is enabled or disabled on the device.</td>
+        <td>Broadcast when Wi-Fi P2P is enabled or disabled on the device.</td>
       </tr>
       <tr>
         <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}</td>
@@ -204,11 +207,11 @@
 
 
 
-  <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi Direct Intents</h2>
+  <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</h2>
 
   <p>A broadcast receiver allows you to receive intents broadcast by the Android system,
   so that your application can respond to events that you are interested in. The basic steps
-  for creating a broadcast receiver to handle Wi-Fi Direct intents are as follows:</p>
+  for creating a broadcast receiver to handle Wi-Fi P2P intents are as follows:</p>
 
   <ol>
     <li>Create a class that extends the {@link android.content.BroadcastReceiver} class. For the
@@ -267,17 +270,17 @@
 }
 </pre>
 
-  <h2 id="creating-app">Creating a Wi-Fi Direct Application</h2>
+  <h2 id="creating-app">Creating a Wi-Fi P2P Application</h2>
 
-  <p>Creating a Wi-Fi Direct application involves creating and registering a
+  <p>Creating a Wi-Fi P2P application involves creating and registering a
   broadcast receiver for your application, discovering peers, connecting to a peer, and
   transferring data to a peer. The following sections describe how to do this.</p>
 
   <h3 id="setup">Initial setup</h3>
-  <p>Before using the Wi-Fi Direct APIs, you must ensure that your application can access
-  the hardware and that the device supports the Wi-Fi Direct protocol. If Wi-Fi Direct is supported,
+  <p>Before using the Wi-Fi P2P APIs, you must ensure that your application can access
+  the hardware and that the device supports the Wi-Fi P2P protocol. If Wi-Fi P2P is supported,
   you can obtain an instance of {@link android.net.wifi.p2p.WifiP2pManager}, create and register
-  your broadcast receiver, and begin using the Wi-Fi Direct APIs.</p>
+  your broadcast receiver, and begin using the Wi-Fi P2P APIs.</p>
   <ol>
     <li>
       <p>Request permission to use the Wi-Fi hardware on the device and also declare
@@ -292,10 +295,10 @@
 </pre>
     </li>
 
-    <li>Check to see if Wi-Fi Direct is on and supported. A good place to check this is in your
+    <li>Check to see if Wi-Fi P2P is on and supported. A good place to check this is in your
     broadcast receiver when it receives the {@link
     android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION} intent. Notify your
-    activity of the Wi-Fi Direct state and react accordingly:
+    activity of the Wi-Fi P2P state and react accordingly:
 <pre>
 &#064;Override
 public void onReceive(Context context, Intent intent) {
@@ -304,9 +307,9 @@
     if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
         int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
         if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
-            // Wifi Direct is enabled
+            // Wifi P2P is enabled
         } else {
-            // Wi-Fi Direct is not enabled
+            // Wi-Fi P2P is not enabled
         }
     }
     ...
@@ -315,10 +318,10 @@
     </li>
 
     <li>In your activity's {@link android.app.Activity#onCreate onCreate()} method, obtain an instance of {@link
-    android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi Direct
+    android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi P2P
     framework by calling {@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}. This
     method returns a {@link android.net.wifi.p2p.WifiP2pManager.Channel}, which is used to connect
-    your application to the Wi-Fi Direct framework. You should also create an instance of your
+    your application to the Wi-Fi P2P framework. You should also create an instance of your
     broadcast receiver with the {@link
     android.net.wifi.p2p.WifiP2pManager} and {@link android.net.wifi.p2p.WifiP2pManager.Channel}
     objects along with a reference to your activity. This allows your broadcast receiver to notify
@@ -376,11 +379,11 @@
 </pre>
 
       <p>When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and
-      set up a broadcast receiver, your application can make Wi-Fi Direct method calls and receive
-      Wi-Fi Direct intents.</p>
+      set up a broadcast receiver, your application can make Wi-Fi P2P method calls and receive
+      Wi-Fi P2P intents.</p>
     </li>
 
-    <p>You can now implement your application and use the Wi-Fi Direct features by calling the
+    <p>You can now implement your application and use the Wi-Fi P2P features by calling the
     methods in {@link android.net.wifi.p2p.WifiP2pManager}. The next sections describe how to do common actions
     such as discovering and connecting to peers.</p>
   </ol>
@@ -492,10 +495,10 @@
   </ol>
 
   <p>The following example, modified from the <a href=
-  "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample, shows you how
+  "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample, shows you how
   to create this client-server socket communication and transfer JPEG images from a client
   to a server with a service. For a complete working example, compile and run the <a href=
-  "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample.</p>
+  "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample.</p>
 <pre>
 public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
 
diff --git a/docs/html/training/connect-devices-wirelessly/index.jd b/docs/html/training/connect-devices-wirelessly/index.jd
index f27b9c3..db79abe 100644
--- a/docs/html/training/connect-devices-wirelessly/index.jd
+++ b/docs/html/training/connect-devices-wirelessly/index.jd
@@ -17,7 +17,7 @@
 
 <h2>You should also read</h2>
 <ul>
-  <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi Direct</a></li>
+  <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi P2P</a></li>
 </ul>
 
 
@@ -37,8 +37,8 @@
 <p>This class describes the key APIs for finding and
 connecting to other devices from your application.  Specifically, it
 describes the NSD API for discovering available services and the Wi-Fi
-Direct&trade; API for doing peer-to-peer wireless connections.  This class also
-shows you how to use NSD and Wi-Fi Direct in
+Peer-to-Peer (P2P) API for doing peer-to-peer wireless connections.  This class also
+shows you how to use NSD and Wi-Fi P2P in
 combination to detect the services offered by a device and connect to the
 device when neither device is connected to a network.
 </p>
@@ -49,13 +49,13 @@
   <dd>Learn how to broadcast services offered by your own application, discover
   services offered on the local network, and use NSD to determine the connection
   details for the service you wish to connect to.</dd>
-  <dt><strong><a href="wifi-direct.html">Connecting with Wi-Fi Direct</a></strong></dt>
+  <dt><strong><a href="wifi-direct.html">Creating P2P Connections with Wi-Fi</a></strong></dt>
   <dd>Learn how to fetch a list of nearby peer devices, create an access point
-  for legacy devices, and connect to other devices capable of Wi-Fi Direct
+  for legacy devices, and connect to other devices capable of Wi-Fi P2P
   connections.</dd>
-  <dt><strong><a href="nsd-wifi-direct.html">Using Wi-Fi Direct for Service
+  <dt><strong><a href="nsd-wifi-direct.html">Using Wi-Fi P2P for Service
       Discovery</a></strong></dt>
   <dd>Learn how to discover services published by nearby devices without being
-  on the same network, using Wi-Fi Direct.</dd>
+  on the same network, using Wi-Fi P2P.</dd>
 </dl>
 
diff --git a/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd b/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
index 5e276de..8dc5fd9 100644
--- a/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
+++ b/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
@@ -1,4 +1,4 @@
-page.title=Using Wi-Fi Direct for Service Discovery
+page.title=Using Wi-Fi P2P for Service Discovery
 parent.title=Connecting Devices Wirelessly
 parent.link=index.html
 
@@ -26,23 +26,23 @@
 <p>The first lesson in this class, <a href="nsd.html">Using Network Service
   Discovery</a>, showed you
 how to discover services that are connected to a local network. However, using
-Wi-Fi Direct&trad; Service Discovery allows you to discover the services of nearby devices directly,
-without being connected to a network.  You can also advertise the services
+Wi-Fi Peer-to-Peer (P2P) Service Discovery allows you to discover the services of nearby devices
+directly, without being connected to a network.  You can also advertise the services
 running on your device.  These capabilities help you communicate between apps,
 even when no local network or hotspot is available.</p>
 <p>While this set of APIs is similar in purpose to the Network Service Discovery
 APIs outlined in a previous lesson, implementing them in code is very different.
 This lesson shows you how to discover services available from other devices,
-using Wi-Fi Direct&trade;. The lesson assumes that you're already familiar with the
-<a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi Direct</a> API.</p>
+using Wi-Fi P2P. The lesson assumes that you're already familiar with the
+<a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi P2P</a> API.</p>
 
 
 <h2 id="manifest">Set Up the Manifest</h2>
-<p>In order to use Wi-Fi Direct, add the {@link
+<p>In order to use Wi-Fi P2P, add the {@link
 android.Manifest.permission#CHANGE_WIFI_STATE}, {@link
 android.Manifest.permission#ACCESS_WIFI_STATE},
 and {@link android.Manifest.permission#INTERNET}
-permissions to your manifest.  Even though Wi-Fi Direct doesn't require an
+permissions to your manifest.  Even though Wi-Fi P2P doesn't require an
 Internet connection, it uses standard Java sockets, and using these in Android
 requires the requested permissions.</p>
 
@@ -244,7 +244,7 @@
 and what they mean</p>
 <dl>
   <dt> {@link android.net.wifi.p2p.WifiP2pManager#P2P_UNSUPPORTED}</dt>
-  <dd> Wi-Fi Direct isn't supported on the device running the app.</dd>
+  <dd> Wi-Fi P2P isn't supported on the device running the app.</dd>
   <dt> {@link android.net.wifi.p2p.WifiP2pManager#BUSY}</dt>
   <dd> The system is to busy to process the request.</dd>
   <dt> {@link android.net.wifi.p2p.WifiP2pManager#ERROR}</dt>
diff --git a/docs/html/training/connect-devices-wirelessly/wifi-direct.jd b/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
index b8ed664..98435c6 100644
--- a/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
+++ b/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
@@ -1,12 +1,6 @@
-page.title=Connecting with Wi-Fi Direct
-parent.title=Connecting Devices Wirelessly
-parent.link=index.html
+page.title=Creating P2P Connections with Wi-Fi
 
 trainingnavtop=true
-previous.title=Using Network Service Discovery
-previous.link=nsd.html
-next.title=Service Discovery with Wi-Fi Direct
-next.link=nsd-wifi-direct.html
 
 @jd:body
 
@@ -21,25 +15,30 @@
       <li><a href="#fetch">Fetch the List of Peers</a></li>
       <li><a href="#connect">Connect to a Peer</a></li>
     </ol>
+    <h2>You should also read</h2>
+    <ul>
+      <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi Peer-to-Peer</a></li>
+    </ul>
   </div>
 </div>
 
-<p>The Wi-Fi Direct&trade; APIs allow applications to connect to nearby devices without
-needing to connect to a network or hotspot.  This allows your application to quickly
+<p>The Wi-Fi peer-to-peer (P2P) APIs allow applications to connect to nearby devices without
+needing to connect to a network or hotspot (Android's Wi-Fi P2P framework complies with the Wi-Fi
+Alliance's Wi-Fi Direct&trade; certification program).  Wi-Fi P2P allows your application to quickly
 find and interact with nearby devices, at a range beyond the capabilities of Bluetooth.
 </p>
 <p>
-This lesson shows you how to find and connect to nearby devices using Wi-Fi Direct.
+This lesson shows you how to find and connect to nearby devices using Wi-Fi P2P.
 </p>
 <h2 id="permissions">Set Up Application Permissions</h2>
-<p>In order to use Wi-Fi Direct, add the {@link
+<p>In order to use Wi-Fi P2P, add the {@link
 android.Manifest.permission#CHANGE_WIFI_STATE}, {@link
 android.Manifest.permission#ACCESS_WIFI_STATE},
 and {@link android.Manifest.permission#INTERNET}
-permissions to your manifest.   Wi-Fi Direct doesn't require an internet connection,
+permissions to your manifest.   Wi-Fi P2P doesn't require an internet connection,
 but it does use standard Java sockets, which require the {@link
 android.Manifest.permission#INTERNET} permission.
-So you need the following permissions to use Wi-Fi Direct.</p>
+So you need the following permissions to use Wi-Fi P2P.</p>
 
 <pre>
 &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
@@ -59,13 +58,13 @@
 </pre>
 
 <h2 id="receiver">Set Up a Broadcast Receiver and Peer-to-Peer Manager</h2>
-<p>To use Wi-Fi Direct, you need to listen for broadcast intents that tell your
+<p>To use Wi-Fi P2P, you need to listen for broadcast intents that tell your
 application when certain events have occurred.  In your application, instantiate
 an {@link
 android.content.IntentFilter} and set it to listen for the following:</p>
 <dl>
   <dt>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}</dt>
-  <dd>Indicates whether Wi-Fi Peer-To-Peer (P2P) is enabled</dd>
+  <dd>Indicates whether Wi-Fi P2P is enabled</dd>
   <dt>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}</dt>
   <dd>Indicates that the available peer list has changed.</dd>
   <dt>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}</dt>
@@ -80,7 +79,7 @@
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
 
-    //  Indicates a change in the Wi-Fi Peer-to-Peer status.
+    //  Indicates a change in the Wi-Fi P2P status.
     intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
 
     // Indicates a change in the list of available peers.
@@ -101,7 +100,7 @@
 android.net.wifi.p2p.WifiP2pManager#initialize(Context, Looper, WifiP2pManager.ChannelListener) initialize()}
 method.  This method returns a {@link
 android.net.wifi.p2p.WifiP2pManager.Channel} object, which you'll use later to
-connect your app to the Wi-Fi Direct Framework.</p>
+connect your app to the Wi-Fi P2P framework.</p>
 
 <pre>
 &#64;Override
@@ -126,7 +125,7 @@
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
         if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
-            // Determine if Wifi Direct mode is enabled or not, alert
+            // Determine if Wifi P2P mode is enabled or not, alert
             // the Activity.
             int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
             if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
@@ -177,7 +176,7 @@
 
 
 <h2 id="discover">Initiate Peer Discovery</h2>
-<p>To start searching for nearby devices with Wi-Fi Direct, call {@link
+<p>To start searching for nearby devices with Wi-Fi P2P, call {@link
 android.net.wifi.p2p.WifiP2pManager#discoverPeers(WifiP2pManager.Channel,
 WifiP2pManager.ActionListener) discoverPeers()}.  This method takes the
 following arguments:</p>
@@ -218,7 +217,7 @@
 <h2 id="fetch">Fetch the List of Peers</h2>
 <p>Now write the code that fetches and processes the list of peers.  First
 implement the {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener}
-interface, which provides information about the peers that Wi-Fi Direct has
+interface, which provides information about the peers that Wi-Fi P2P has
 detected.  The following code snippet illustrates this.</p>
 
 <pre>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index b884620..ebf553cc 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -405,7 +405,7 @@
           <a href="<?cs var:toroot ?>training/connect-devices-wirelessly/index.html"
              description=
              "How to find and connect to local devices using Network Service
-             Discovery and Wi-Fi Direct in order to create peer-to-peer connections."
+             Discovery and how to create peer-to-peer connections with Wi-Fi."
              >Connecting Devices Wirelessly</a>
         </div>
         <ul>
@@ -414,7 +414,7 @@
           </a>
           </li>
           <li><a href="<?cs var:toroot ?>training/connect-devices-wirelessly/wifi-direct.html">
-            Connecting with Wi-Fi Direct
+            Creating P2P Connections with Wi-Fi
           </a>
           </li>
           <li><a href="<?cs var:toroot ?>training/connect-devices-wirelessly/nsd-wifi-direct.html">
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index c971da5..495bbca 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -419,6 +419,10 @@
          * 
          * It is recommended to use {@link #ARGB_8888} instead of this
          * configuration.
+         *
+         * Note: as of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE},
+         * any bitmap created with this configuration will be created
+         * using {@link #ARGB_8888} instead.
          * 
          * @deprecated Because of the poor quality of this configuration,
          *             it is advised to use {@link #ARGB_8888} instead.
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 1721bee..8872de0 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -81,7 +81,7 @@
          * function to ensure that you are using the bitmap that was used as the
          * decode destination.</p>
          *
-         * @see Bitmap#reconfigure(int,int,Config)
+         * @see Bitmap#reconfigure(int,int, android.graphics.Bitmap.Config)
          */
         public Bitmap inBitmap;
 
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 54cdcab..4c88de3 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -102,8 +102,8 @@
         final LinearGradient copy;
         switch (mType) {
             case TYPE_COLORS_AND_POSITIONS:
-                copy = new LinearGradient(mX0, mY0, mX1, mY1, mColors.clone(), mPositions.clone(),
-                        mTileMode);
+                copy = new LinearGradient(mX0, mY0, mX1, mY1, mColors.clone(),
+                        mPositions != null ? mPositions.clone() : null, mTileMode);
                 break;
             case TYPE_COLOR_START_AND_COLOR_END:
                 copy = new LinearGradient(mX0, mY0, mX1, mY1, mColor0, mColor1, mTileMode);
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index 23244d8..f011e5c 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -103,8 +103,8 @@
         final RadialGradient copy;
         switch (mType) {
             case TYPE_COLORS_AND_POSITIONS:
-                copy = new RadialGradient(mX, mY, mRadius, mColors.clone(), mPositions.clone(),
-                        mTileMode);
+                copy = new RadialGradient(mX, mY, mRadius, mColors.clone(),
+                        mPositions != null ? mPositions.clone() : null, mTileMode);
                 break;
             case TYPE_COLOR_CENTER_AND_COLOR_EDGE:
                 copy = new RadialGradient(mX, mY, mRadius, mColor0, mColor1, mTileMode);
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index 3010927..e9cda39 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -92,7 +92,8 @@
         final SweepGradient copy;
         switch (mType) {
             case TYPE_COLORS_AND_POSITIONS:
-                copy = new SweepGradient(mCx, mCy, mColors.clone(), mPositions.clone());
+                copy = new SweepGradient(mCx, mCy, mColors.clone(),
+                        mPositions != null ? mPositions.clone() : null);
                 break;
             case TYPE_COLOR_START_AND_COLOR_END:
                 copy = new SweepGradient(mCx, mCy, mColor0, mColor1);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index e5f1cf5..14b812e 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -152,12 +152,24 @@
 
     /**
      * Broadcast intent action when the configured location providers
-     * change.
+     * change. If you're interacting with the
+     * {@link android.provider.Settings.Secure#LOCATION_MODE} API,
+     * use {@link #MODE_CHANGED_ACTION} instead.
      */
     public static final String PROVIDERS_CHANGED_ACTION =
         "android.location.PROVIDERS_CHANGED";
 
     /**
+     * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} changes.
+     * If you're interacting with provider-based APIs such as {@link #getProviders(boolean)}, you
+     * use {@link #PROVIDERS_CHANGED_ACTION} instead.
+     *
+     * In the future, there may be mode changes that do not result in
+     * {@link #PROVIDERS_CHANGED_ACTION} broadcasts.
+     */
+    public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
+
+    /**
      * Broadcast intent action indicating that the GPS has either started or
      * stopped receiving GPS fixes. An intent extra provides this state as a
      * boolean, where {@code true} means that the GPS is actively receiving fixes.
diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java
index 0b0f05d..8181f4e 100644
--- a/location/java/android/location/SettingInjectorService.java
+++ b/location/java/android/location/SettingInjectorService.java
@@ -22,12 +22,11 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.preference.Preference;
 import android.util.Log;
 
 /**
- * Dynamically specifies the summary (subtile) and enabled status of a preference injected into
- * the "Settings &gt; Location &gt; Location services" list.
+ * Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
+ * the list of location services displayed by the system settings app.
  *
  * The location services list is intended for use only by preferences that affect multiple apps from
  * the same developer. Location settings that apply only to one app should be shown within that app,
@@ -39,52 +38,47 @@
  * <pre>
  *     &lt;service android:name="com.example.android.injector.MyInjectorService" &gt;
  *         &lt;intent-filter&gt;
- *             &lt;action android:name="com.android.settings.InjectedLocationSetting" /&gt;
+ *             &lt;action android:name="android.location.SettingInjectorService" /&gt;
  *         &lt;/intent-filter&gt;
  *
  *         &lt;meta-data
- *             android:name="com.android.settings.InjectedLocationSetting"
+ *             android:name="android.location.SettingInjectorService"
  *             android:resource="@xml/my_injected_location_setting" /&gt;
  *     &lt;/service&gt;
  * </pre>
  * The resource file specifies the static data for the setting:
  * <pre>
  *     &lt;injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
- *         android:label="@string/injected_setting_label"
- *         android:icon="@drawable/ic_launcher"
+ *         android:title="@string/injected_setting_title"
+ *         android:icon="@drawable/ic_acme_corp"
  *         android:settingsActivity="com.example.android.injector.MySettingActivity"
  *     /&gt;
  * </pre>
  * Here:
  * <ul>
- *     <li>label: The {@link Preference#getTitle()} value. The title should make it clear which apps
- *     are affected by the setting, typically by including the name of the developer. For example,
- *     "Acme Corp. ads preferences." </li>
+ *     <li>title: The {@link android.preference.Preference#getTitle()} value. The title should make
+ *     it clear which apps are affected by the setting, typically by including the name of the
+ *     developer. For example, "Acme Corp. ads preferences." </li>
  *
- *     <li>icon: The {@link Preference#getIcon()} value. Typically this will be a generic icon for
- *     the developer rather than the icon for an individual app.</li>
+ *     <li>icon: The {@link android.preference.Preference#getIcon()} value. Typically this will be a
+ *     generic icon for the developer rather than the icon for an individual app.</li>
  *
  *     <li>settingsActivity: the activity which is launched to allow the user to modify the setting
- *     value  The activity must be in the same package as the subclass of
+ *     value.  The activity must be in the same package as the subclass of
  *     {@link SettingInjectorService}. The activity should use your own branding to help emphasize
  *     to the user that it is not part of the system settings.</li>
  * </ul>
  *
- * To ensure a good user experience, your {@link #onHandleIntent(Intent)} must complete within
- * 200 msec even if your app is not already running. This means that both
- * {@link android.app.Application#onCreate()} and {@link #getStatus()} must be fast. If you exceed
- * this time, then this can delay the retrieval of settings status for other apps as well.
- *
- * For consistency, the label and {@link #getStatus()} values should be provided in all of the
- * locales supported by the system settings app. The text should not contain offensive language.
+ * To ensure a good user experience, the average time from the start of
+ * {@link #startService(Intent)} to the end of {@link #onHandleIntent(Intent)} should be less
+ * than 300 msec even if your app is not already in memory. This means that both your
+ * {@link android.app.Application#onCreate()} and your {@link #getStatus()} must be fast. If
+ * either is slow, it can delay the display of settings values for other apps as well.
  *
  * For compactness, only one copy of a given setting should be injected. If each account has a
  * distinct value for the setting, then the {@link #getStatus()} value should represent a summary of
  * the state across all of the accounts and {@code settingsActivity} should display the value for
  * each account.
- *
- * Apps that violate these guidelines will be taken down from the Google Play Store and/or flagged
- * as malware.
  */
 // TODO: is there a public list of supported locales?
 // TODO: is there a public list of guidelines for settings text?
@@ -94,6 +88,30 @@
     private static final String TAG = "SettingInjectorService";
 
     /**
+     * Intent action that must be declared in the manifest for the subclass. Used to start the
+     * service to read the dynamic status for the setting.
+     */
+    public static final String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+
+    /**
+     * Name of the meta-data tag used to specify the resource file that includes the settings
+     * attributes.
+     */
+    public static final String META_DATA_NAME = "android.location.SettingInjectorService";
+
+    /**
+     * Name of the XML tag that includes the attributes for the setting.
+     */
+    public static final String ATTRIBUTES_NAME = "injected-location-setting";
+
+    /**
+     * Intent action a client should broadcast when the value of one of its injected settings has
+     * changed, so that the setting can be updated in the UI.
+     */
+    public static final String ACTION_INJECTED_SETTING_CHANGED =
+            "android.location.InjectedSettingChanged";
+
+    /**
      * Name of the bundle key for the string specifying the summary for the setting (e.g., "ON" or
      * "OFF").
      *
@@ -115,13 +133,6 @@
      */
     public static final String MESSENGER_KEY = "messenger";
 
-    /**
-     * Intent action a client should broadcast when the value of one of its injected settings has
-     * changed, so that the setting can be updated in the UI.
-     */
-    public static final String ACTION_INJECTED_SETTING_CHANGED =
-            "com.android.location.InjectedSettingChanged";
-
     private final String mName;
 
     /**
@@ -169,7 +180,10 @@
     }
 
     /**
-     * Reads the status of the setting.
+     * Reads the status of the setting. Should not perform unpredictably-long operations such as
+     * network access--see the running-time comments in the class-level javadoc.
+     *
+     * @return the status of the setting value
      */
     protected abstract Status getStatus();
 
@@ -179,12 +193,16 @@
     public static final class Status {
 
         /**
-         * The {@link Preference#getSummary()} value
+         * The {@link android.preference.Preference#getSummary()} value.
+         *
+         * @hide
          */
         public final String summary;
 
         /**
-         * The {@link Preference#isEnabled()} value
+         * The {@link android.preference.Preference#isEnabled()} value.
+         *
+         * @hide
          */
         public final boolean enabled;
 
@@ -193,9 +211,8 @@
          * <p/>
          * Note that to prevent churn in the settings list, there is no support for dynamically
          * choosing to hide a setting. Instead you should provide a {@code enabled} value of false,
-         * which will gray the setting out and disable the link from "Settings > Location"
-         * to your setting activity. One reason why you might choose to do this is if
-         * {@link android.provider.Settings.Secure#LOCATION_MODE}
+         * which will disable the setting and its link to your setting activity. One reason why you
+         * might choose to do this is if {@link android.provider.Settings.Secure#LOCATION_MODE}
          * is {@link android.provider.Settings.Secure#LOCATION_MODE_OFF}.
          *
          * It is possible that the user may click on the setting before you return a false value for
@@ -203,8 +220,9 @@
          * though the setting is disabled. The simplest approach may be to simply call
          * {@link android.app.Activity#finish()} when disabled.
          *
-         * @param summary the {@link Preference#getSummary()} value (allowed to be null or empty)
-         * @param enabled the {@link Preference#isEnabled()} value
+         * @param summary the {@link android.preference.Preference#getSummary()} value (allowed to
+         *                be null or empty)
+         * @param enabled the {@link android.preference.Preference#isEnabled()} value
          */
         public Status(String summary, boolean enabled) {
             this.summary = summary;
diff --git a/media/java/android/media/AudioTimestamp.java b/media/java/android/media/AudioTimestamp.java
new file mode 100644
index 0000000..437a0c6
--- /dev/null
+++ b/media/java/android/media/AudioTimestamp.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * Structure that groups a position in frame units relative to an assumed audio stream,
+ * together with the estimated time when that frame was presented or is committed to be
+ * presented.
+ * In the case of audio output, "present" means that audio produced on device
+ * is detectable by an external observer off device.
+ * The time is based on the implementation's best effort, using whatever knowledge
+ * is available to the system, but cannot account for any delay unknown to the implementation.
+ *
+ * @see AudioTrack#getTimestamp
+ * @see AudioTrack.TimestampListener
+ *
+ * @hide
+ */
+public final class AudioTimestamp
+{
+    /**
+     * Position in frames relative to start of an assumed audio stream.
+     * The low-order 32 bits of position is in wrapping frame units similar to
+     * {@link AudioTrack#getPlaybackHeadPosition}.
+     */
+    public long framePosition;
+
+    /**
+     * The estimated time when frame was presented or is committed to be presented,
+     * in the same units and timebase as {@link java.lang.System#nanoTime}.
+     */
+    public long nanoTime;
+}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d9227bd..88539f28 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -732,6 +732,51 @@
         return mSessionId;
     }
 
+   /**
+    * Poll for a timestamp on demand.
+    *
+    * Use if {@link TimestampListener} is not delivered often enough for your needs,
+    * or if you need to get the most recent timestamp outside of the event callback handler.
+    * Calling this method too often may be inefficient;
+    * if you need a high-resolution mapping between frame position and presentation time,
+    * consider implementing that at application level, based on low-resolution timestamps.
+    * The audio data at the returned position may either already have been
+    * presented, or may have not yet been presented but is committed to be presented.
+    * It is not possible to request the time corresponding to a particular position,
+    * or to request the (fractional) position corresponding to a particular time.
+    * If you need such features, consider implementing them at application level.
+    *
+    * @param timestamp a reference to a non-null AudioTimestamp instance allocated
+    *        and owned by caller, or null.
+    * @return that same instance if timestamp parameter is non-null and a timestamp is available,
+    *         or a reference to a new AudioTimestamp instance which is now owned by caller
+    *         if timestamp parameter is null and a timestamp is available,
+    *         or null if no timestamp is available.  In either successful case,
+    *         the AudioTimestamp instance is filled in with a position in frame units, together
+    *         with the estimated time when that frame was presented or is committed to
+    *         be presented.
+    *         In the case that no timestamp is available, any supplied instance is left unaltered.
+    *
+    * @hide
+    */
+    public AudioTimestamp getTimestamp(AudioTimestamp timestamp)
+    {
+        // It's unfortunate, but we have to either create garbage every time or use synchronized
+        long[] longArray = new long[2];
+        int ret = native_get_timestamp(longArray);
+        if (ret == SUCCESS) {
+            if (timestamp == null) {
+                timestamp = new AudioTimestamp();
+            }
+            timestamp.framePosition = longArray[0];
+            timestamp.nanoTime = longArray[1];
+        } else {
+            timestamp = null;
+        }
+        return timestamp;
+    }
+
+
     //--------------------------------------------------------------------------
     // Initialization / configuration
     //--------------------
@@ -1321,6 +1366,11 @@
 
     private native final int native_get_latency();
 
+    // longArray must be a non-null array of length >= 2
+    // [0] is assigned the frame position
+    // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
+    private native final int native_get_timestamp(long[] longArray);
+
     private native final int native_set_loop(int start, int end, int loopCount);
 
     static private native final int native_get_output_sample_rate(int streamType);
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 946dd71..d286be4 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -26,11 +26,13 @@
 import android.net.ProxyProperties;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.PowerManager;
 import android.util.Log;
 import android.view.Surface;
@@ -39,15 +41,22 @@
 import android.graphics.SurfaceTexture;
 import android.media.AudioManager;
 import android.media.MediaFormat;
+import android.media.MediaTimeProvider;
+import android.media.MediaTimeProvider.OnMediaTimeListener;
+import android.media.SubtitleController;
 import android.media.SubtitleData;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.lang.Runnable;
 import java.net.InetSocketAddress;
 import java.util.Map;
+import java.util.Scanner;
 import java.util.Set;
+import java.util.Vector;
 import java.lang.ref.WeakReference;
 
 /**
@@ -517,7 +526,7 @@
  * thread by default has a Looper running).
  *
  */
-public class MediaPlayer
+public class MediaPlayer implements SubtitleController.Listener
 {
     /**
        Constant to retrieve only the new metadata since the last
@@ -590,6 +599,11 @@
             mEventHandler = null;
         }
 
+        mTimeProvider = new TimeProvider(this);
+        mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>();
+        mOpenSubtitleSources = new Vector<InputStream>();
+        mInbandSubtitleTracks = new SubtitleTrack[0];
+
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
          */
@@ -1337,6 +1351,8 @@
         mOnInfoListener = null;
         mOnVideoSizeChangedListener = null;
         mOnTimedTextListener = null;
+        mTimeProvider.close();
+        mTimeProvider = null;
         mOnSubtitleDataListener = null;
         _release();
     }
@@ -1349,6 +1365,22 @@
      * data source and calling prepare().
      */
     public void reset() {
+        mSelectedSubtitleTrackIndex = -1;
+        synchronized(mOpenSubtitleSources) {
+            for (final InputStream is: mOpenSubtitleSources) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+            mOpenSubtitleSources.clear();
+        }
+        mOutOfBandSubtitleTracks.clear();
+        mInbandSubtitleTracks = new SubtitleTrack[0];
+        if (mSubtitleController != null) {
+            mSubtitleController.reset();
+        }
+
         stayAwake(false);
         _reset();
         // make sure none of the listeners get called anymore
@@ -1568,6 +1600,12 @@
             }
         }
 
+        /** @hide */
+        TrackInfo(int type, MediaFormat format) {
+            mTrackType = type;
+            mFormat = format;
+        }
+
         /**
          * {@inheritDoc}
          */
@@ -1612,6 +1650,19 @@
      * @throws IllegalStateException if it is called in an invalid state.
      */
     public TrackInfo[] getTrackInfo() throws IllegalStateException {
+        TrackInfo trackInfo[] = getInbandTrackInfo();
+        // add out-of-band tracks
+        TrackInfo allTrackInfo[] = new TrackInfo[trackInfo.length + mOutOfBandSubtitleTracks.size()];
+        System.arraycopy(trackInfo, 0, allTrackInfo, 0, trackInfo.length);
+        int i = trackInfo.length;
+        for (SubtitleTrack track: mOutOfBandSubtitleTracks) {
+            allTrackInfo[i] = new TrackInfo(TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE, track.getFormat());
+            ++i;
+        }
+        return allTrackInfo;
+    }
+
+    private TrackInfo[] getInbandTrackInfo() throws IllegalStateException {
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -1644,6 +1695,143 @@
         return false;
     }
 
+    private SubtitleController mSubtitleController;
+
+    /** @hide */
+    public void setSubtitleAnchor(
+            SubtitleController controller,
+            SubtitleController.Anchor anchor) {
+        // TODO: create SubtitleController in MediaPlayer
+        mSubtitleController = controller;
+        mSubtitleController.setAnchor(anchor);
+    }
+
+    private SubtitleTrack[] mInbandSubtitleTracks;
+    private int mSelectedSubtitleTrackIndex = -1;
+    private Vector<SubtitleTrack> mOutOfBandSubtitleTracks;
+    private Vector<InputStream> mOpenSubtitleSources;
+
+    private OnSubtitleDataListener mSubtitleDataListener = new OnSubtitleDataListener() {
+        @Override
+        public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+            int index = data.getTrackIndex();
+            if (index >= mInbandSubtitleTracks.length) {
+                return;
+            }
+            SubtitleTrack track = mInbandSubtitleTracks[index];
+            if (track != null) {
+                try {
+                    long runID = data.getStartTimeUs() + 1;
+                    // TODO: move conversion into track
+                    track.onData(new String(data.getData(), "UTF-8"), true /* eos */, runID);
+                    track.setRunDiscardTimeMs(
+                            runID,
+                            (data.getStartTimeUs() + data.getDurationUs()) / 1000);
+                } catch (java.io.UnsupportedEncodingException e) {
+                    Log.w(TAG, "subtitle data for track " + index + " is not UTF-8 encoded: " + e);
+                }
+            }
+        }
+    };
+
+    /** @hide */
+    @Override
+    public void onSubtitleTrackSelected(SubtitleTrack track) {
+        if (mSelectedSubtitleTrackIndex >= 0) {
+            deselectTrack(mSelectedSubtitleTrackIndex);
+        }
+        mSelectedSubtitleTrackIndex = -1;
+        setOnSubtitleDataListener(null);
+        for (int i = 0; i < mInbandSubtitleTracks.length; i++) {
+            if (mInbandSubtitleTracks[i] == track) {
+                Log.v(TAG, "Selecting subtitle track " + i);
+                selectTrack(i);
+                mSelectedSubtitleTrackIndex = i;
+                setOnSubtitleDataListener(mSubtitleDataListener);
+                break;
+            }
+        }
+        // no need to select out-of-band tracks
+    }
+
+    /** @hide */
+    public void addSubtitleSource(InputStream is, MediaFormat format)
+            throws IllegalStateException
+    {
+        final InputStream fIs = is;
+        final MediaFormat fFormat = format;
+
+        // Ensure all input streams are closed.  It is also a handy
+        // way to implement timeouts in the future.
+        synchronized(mOpenSubtitleSources) {
+            mOpenSubtitleSources.add(is);
+        }
+
+        // process each subtitle in its own thread
+        final HandlerThread thread = new HandlerThread("SubtitleReadThread",
+              Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
+        thread.start();
+        Handler handler = new Handler(thread.getLooper());
+        handler.post(new Runnable() {
+            private int addTrack() {
+                if (fIs == null || mSubtitleController == null) {
+                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+                }
+
+                SubtitleTrack track = mSubtitleController.addTrack(fFormat);
+                if (track == null) {
+                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+                }
+
+                // TODO: do the conversion in the subtitle track
+                Scanner scanner = new Scanner(fIs, "UTF-8");
+                String contents = scanner.useDelimiter("\\A").next();
+                synchronized(mOpenSubtitleSources) {
+                    mOpenSubtitleSources.remove(fIs);
+                }
+                scanner.close();
+                mOutOfBandSubtitleTracks.add(track);
+                track.onData(contents, true /* eos */, ~0 /* runID: keep forever */);
+                // update default track selection
+                mSubtitleController.selectDefaultTrack();
+                return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
+            }
+
+            public void run() {
+                int res = addTrack();
+                if (mEventHandler != null) {
+                    Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null);
+                    mEventHandler.sendMessage(m);
+                }
+                thread.getLooper().quitSafely();
+            }
+        });
+    }
+
+    private void scanInternalSubtitleTracks() {
+        if (mSubtitleController == null) {
+            Log.e(TAG, "Should have subtitle controller already set");
+            return;
+        }
+
+        TrackInfo[] tracks = getInbandTrackInfo();
+        SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
+        for (int i=0; i < tracks.length; i++) {
+            if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                if (i < mInbandSubtitleTracks.length) {
+                    inbandTracks[i] = mInbandSubtitleTracks[i];
+                } else {
+                    MediaFormat format = MediaFormat.createSubtitleFormat(
+                            "text/vtt", tracks[i].getLanguage());
+                    SubtitleTrack track = mSubtitleController.addTrack(format);
+                    inbandTracks[i] = track;
+                }
+            }
+        }
+        mInbandSubtitleTracks = inbandTracks;
+        mSubtitleController.selectDefaultTrack();
+    }
+
     /* TODO: Limit the total number of external timed text source to a reasonable number.
      */
     /**
@@ -1834,6 +2022,13 @@
 
     private void selectOrDeselectTrack(int index, boolean select)
             throws IllegalStateException {
+        // ignore out-of-band tracks
+        TrackInfo[] trackInfo = getInbandTrackInfo();
+        if (index >= trackInfo.length &&
+                index < trackInfo.length + mOutOfBandSubtitleTracks.size()) {
+            return;
+        }
+
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -1914,11 +2109,21 @@
     private static final int MEDIA_BUFFERING_UPDATE = 3;
     private static final int MEDIA_SEEK_COMPLETE = 4;
     private static final int MEDIA_SET_VIDEO_SIZE = 5;
+    private static final int MEDIA_STARTED = 6;
+    private static final int MEDIA_PAUSED = 7;
+    private static final int MEDIA_STOPPED = 8;
     private static final int MEDIA_TIMED_TEXT = 99;
     private static final int MEDIA_ERROR = 100;
     private static final int MEDIA_INFO = 200;
     private static final int MEDIA_SUBTITLE_DATA = 201;
 
+    private TimeProvider mTimeProvider;
+
+    /** @hide */
+    public MediaTimeProvider getMediaTimeProvider() {
+        return mTimeProvider;
+    }
+
     private class EventHandler extends Handler
     {
         private MediaPlayer mMediaPlayer;
@@ -1936,6 +2141,7 @@
             }
             switch(msg.what) {
             case MEDIA_PREPARED:
+                scanInternalSubtitleTracks();
                 if (mOnPreparedListener != null)
                     mOnPreparedListener.onPrepared(mMediaPlayer);
                 return;
@@ -1946,14 +2152,31 @@
                 stayAwake(false);
                 return;
 
+            case MEDIA_STOPPED:
+                if (mTimeProvider != null) {
+                    mTimeProvider.onStopped();
+                }
+                break;
+
+            case MEDIA_STARTED:
+            case MEDIA_PAUSED:
+                if (mTimeProvider != null) {
+                    mTimeProvider.onPaused(msg.what == MEDIA_PAUSED);
+                }
+                break;
+
             case MEDIA_BUFFERING_UPDATE:
                 if (mOnBufferingUpdateListener != null)
                     mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
                 return;
 
             case MEDIA_SEEK_COMPLETE:
-              if (mOnSeekCompleteListener != null)
+              if (mOnSeekCompleteListener != null) {
                   mOnSeekCompleteListener.onSeekComplete(mMediaPlayer);
+              }
+              if (mTimeProvider != null) {
+                  mTimeProvider.onSeekComplete(mMediaPlayer);
+              }
               return;
 
             case MEDIA_SET_VIDEO_SIZE:
@@ -1974,9 +2197,18 @@
                 return;
 
             case MEDIA_INFO:
-                if (msg.arg1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
+                switch (msg.arg1) {
+                case MEDIA_INFO_VIDEO_TRACK_LAGGING:
                     Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
+                    break;
+                case MEDIA_INFO_METADATA_UPDATE:
+                    scanInternalSubtitleTracks();
+                    break;
+                case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
+                    msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
+                    break;
                 }
+
                 if (mOnInfoListener != null) {
                     mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
                 }
@@ -2375,6 +2607,12 @@
      */
     public static final int MEDIA_INFO_METADATA_UPDATE = 802;
 
+    /** A new set of external-only metadata is available.  Used by
+     *  JAVA framework to avoid triggering track scanning.
+     * @hide
+     */
+    public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
+
     /** Failed to handle timed text track properly.
      * @see android.media.MediaPlayer.OnInfoListener
      *
@@ -2382,6 +2620,16 @@
      */
     public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
 
+    /** Subtitle track was not supported by the media framework.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
+
+    /** Reading the subtitle track takes too long.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
+
     /**
      * Interface definition of a callback to be invoked to communicate some
      * info and/or warning about the media or its playback.
@@ -2402,6 +2650,8 @@
          * <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
          * <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
          * <li>{@link #MEDIA_INFO_METADATA_UPDATE}
+         * <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
+         * <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
          * </ul>
          * @param extra an extra code, specific to the info. Typically
          * implementation dependent.
@@ -2484,4 +2734,351 @@
     }
 
     private native void updateProxyConfig(ProxyProperties props);
+
+    /** @hide */
+    static class TimeProvider implements MediaPlayer.OnSeekCompleteListener,
+            MediaTimeProvider {
+        private static final String TAG = "MTP";
+        private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L;
+        private static final long MAX_EARLY_CALLBACK_US = 1000;
+        private static final long TIME_ADJUSTMENT_RATE = 2;  /* meaning 1/2 */
+        private long mLastTimeUs = 0;
+        private MediaPlayer mPlayer;
+        private boolean mPaused = true;
+        private boolean mStopped = true;
+        private long mLastReportedTime;
+        private long mTimeAdjustment;
+        // since we are expecting only a handful listeners per stream, there is
+        // no need for log(N) search performance
+        private MediaTimeProvider.OnMediaTimeListener mListeners[];
+        private long mTimes[];
+        private long mLastNanoTime;
+        private Handler mEventHandler;
+        private boolean mRefresh = false;
+        private boolean mPausing = false;
+        private static final int NOTIFY = 1;
+        private static final int NOTIFY_TIME = 0;
+        private static final int REFRESH_AND_NOTIFY_TIME = 1;
+        private static final int NOTIFY_STOP = 2;
+        private static final int NOTIFY_SEEK = 3;
+
+        /** @hide */
+        public boolean DEBUG = false;
+
+        public TimeProvider(MediaPlayer mp) {
+            mPlayer = mp;
+            try {
+                getCurrentTimeUs(true, false);
+            } catch (IllegalStateException e) {
+                // we assume starting position
+                mRefresh = true;
+            }
+            mEventHandler = new EventHandler();
+            mListeners = new MediaTimeProvider.OnMediaTimeListener[0];
+            mTimes = new long[0];
+            mLastTimeUs = 0;
+            mTimeAdjustment = 0;
+        }
+
+        private void scheduleNotification(int type, long delayUs) {
+            if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
+            mEventHandler.removeMessages(NOTIFY);
+            Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0);
+            mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000));
+        }
+
+        /** @hide */
+        public void close() {
+            mEventHandler.removeMessages(NOTIFY);
+        }
+
+        /** @hide */
+        public void onPaused(boolean paused) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "onPaused: " + paused);
+                if (mStopped) { // handle as seek if we were stopped
+                    mStopped = false;
+                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                } else {
+                    mPausing = paused;  // special handling if player disappeared
+                    scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */);
+                }
+            }
+        }
+
+        /** @hide */
+        public void onStopped() {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "onStopped");
+                mPaused = true;
+                mStopped = true;
+                scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        @Override
+        public void onSeekComplete(MediaPlayer mp) {
+            synchronized(this) {
+                mStopped = false;
+                scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        public void onNewPlayer() {
+            if (mRefresh) {
+                synchronized(this) {
+                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                }
+            }
+        }
+
+        private synchronized void notifySeek() {
+            try {
+                long timeUs = getCurrentTimeUs(true, false);
+                if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs);
+
+                for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                    if (listener == null) {
+                        break;
+                    }
+                    listener.onSeek(timeUs);
+                }
+            } catch (IllegalStateException e) {
+                // we should not be there, but at least signal pause
+                if (DEBUG) Log.d(TAG, "onSeekComplete but no player");
+                mPausing = true;  // special handling if player disappeared
+                notifyTimedEvent(false /* refreshTime */);
+            }
+        }
+
+        private synchronized void notifyStop() {
+            for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                if (listener == null) {
+                    break;
+                }
+                listener.onStop();
+            }
+        }
+
+        private int registerListener(MediaTimeProvider.OnMediaTimeListener listener) {
+            int i = 0;
+            for (; i < mListeners.length; i++) {
+                if (mListeners[i] == listener || mListeners[i] == null) {
+                    break;
+                }
+            }
+
+            // new listener
+            if (i >= mListeners.length) {
+                MediaTimeProvider.OnMediaTimeListener[] newListeners =
+                    new MediaTimeProvider.OnMediaTimeListener[i + 1];
+                long[] newTimes = new long[i + 1];
+                System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length);
+                System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length);
+                mListeners = newListeners;
+                mTimes = newTimes;
+            }
+
+            if (mListeners[i] == null) {
+                mListeners[i] = listener;
+                mTimes[i] = MediaTimeProvider.NO_TIME;
+            }
+            return i;
+        }
+
+        public void notifyAt(
+                long timeUs, MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "notifyAt " + timeUs);
+                mTimes[registerListener(listener)] = timeUs;
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "scheduleUpdate");
+                int i = registerListener(listener);
+
+                if (mStopped) {
+                    scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+                } else {
+                    mTimes[i] = 0;
+                    scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+                }
+            }
+        }
+
+        public void cancelNotifications(
+                MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                int i = 0;
+                for (; i < mListeners.length; i++) {
+                    if (mListeners[i] == listener) {
+                        System.arraycopy(mListeners, i + 1,
+                                mListeners, i, mListeners.length - i - 1);
+                        System.arraycopy(mTimes, i + 1,
+                                mTimes, i, mTimes.length - i - 1);
+                        mListeners[mListeners.length - 1] = null;
+                        mTimes[mTimes.length - 1] = NO_TIME;
+                        break;
+                    } else if (mListeners[i] == null) {
+                        break;
+                    }
+                }
+
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        private synchronized void notifyTimedEvent(boolean refreshTime) {
+            // figure out next callback
+            long nowUs;
+            try {
+                nowUs = getCurrentTimeUs(refreshTime, true);
+            } catch (IllegalStateException e) {
+                // assume we paused until new player arrives
+                mRefresh = true;
+                mPausing = true; // this ensures that call succeeds
+                nowUs = getCurrentTimeUs(refreshTime, true);
+            }
+            long nextTimeUs = nowUs;
+
+            if (DEBUG) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ")
+                        .append(nowUs).append(") from {");
+                boolean first = true;
+                for (long time: mTimes) {
+                    if (time == NO_TIME) {
+                        continue;
+                    }
+                    if (!first) sb.append(", ");
+                    sb.append(time);
+                    first = false;
+                }
+                sb.append("}");
+                Log.d(TAG, sb.toString());
+            }
+
+            Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners =
+                new Vector<MediaTimeProvider.OnMediaTimeListener>();
+            for (int ix = 0; ix < mTimes.length; ix++) {
+                if (mListeners[ix] == null) {
+                    break;
+                }
+                if (mTimes[ix] <= NO_TIME) {
+                    // ignore, unless we were stopped
+                } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) {
+                    activatedListeners.add(mListeners[ix]);
+                    if (DEBUG) Log.d(TAG, "removed");
+                    mTimes[ix] = NO_TIME;
+                } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) {
+                    nextTimeUs = mTimes[ix];
+                }
+            }
+
+            if (nextTimeUs > nowUs && !mPaused) {
+                // schedule callback at nextTimeUs
+                if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
+                scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs);
+            } else {
+                mEventHandler.removeMessages(NOTIFY);
+                // no more callbacks
+            }
+
+            for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) {
+                listener.onTimedEvent(nowUs);
+            }
+        }
+
+        private long getEstimatedTime(long nanoTime, boolean monotonic) {
+            if (mPaused) {
+                mLastReportedTime = mLastTimeUs + mTimeAdjustment;
+            } else {
+                long timeSinceRead = (nanoTime - mLastNanoTime) / 1000;
+                mLastReportedTime = mLastTimeUs + timeSinceRead;
+                if (mTimeAdjustment > 0) {
+                    long adjustment =
+                        mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE;
+                    if (adjustment <= 0) {
+                        mTimeAdjustment = 0;
+                    } else {
+                        mLastReportedTime += adjustment;
+                    }
+                }
+            }
+            return mLastReportedTime;
+        }
+
+        public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
+                throws IllegalStateException {
+            synchronized (this) {
+                // we always refresh the time when the paused-state changes, because
+                // we expect to have received the pause-change event delayed.
+                if (mPaused && !refreshTime) {
+                    return mLastReportedTime;
+                }
+
+                long nanoTime = System.nanoTime();
+                if (refreshTime ||
+                        nanoTime >= mLastNanoTime + MAX_NS_WITHOUT_POSITION_CHECK) {
+                    try {
+                        mLastTimeUs = mPlayer.getCurrentPosition() * 1000;
+                        mPaused = !mPlayer.isPlaying();
+                        if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
+                    } catch (IllegalStateException e) {
+                        if (mPausing) {
+                            // if we were pausing, get last estimated timestamp
+                            mPausing = false;
+                            getEstimatedTime(nanoTime, monotonic);
+                            mPaused = true;
+                            if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
+                            return mLastReportedTime;
+                        }
+                        // TODO get time when prepared
+                        throw e;
+                    }
+                    mLastNanoTime = nanoTime;
+                    if (monotonic && mLastTimeUs < mLastReportedTime) {
+                        /* have to adjust time */
+                        mTimeAdjustment = mLastReportedTime - mLastTimeUs;
+                    } else {
+                        mTimeAdjustment = 0;
+                    }
+                }
+
+                return getEstimatedTime(nanoTime, monotonic);
+            }
+        }
+
+        private class EventHandler extends Handler {
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == NOTIFY) {
+                    switch (msg.arg1) {
+                    case NOTIFY_TIME:
+                        notifyTimedEvent(false /* refreshTime */);
+                        break;
+                    case REFRESH_AND_NOTIFY_TIME:
+                        notifyTimedEvent(true /* refreshTime */);
+                        break;
+                    case NOTIFY_STOP:
+                        notifyStop();
+                        break;
+                    case NOTIFY_SEEK:
+                        notifySeek();
+                        break;
+                    }
+                }
+            }
+        }
+
+        /** @hide */
+        public Handler getHandler() {
+            return mEventHandler;
+        }
+    }
 }
diff --git a/media/java/android/media/MediaTimeProvider.java b/media/java/android/media/MediaTimeProvider.java
new file mode 100644
index 0000000..fe37712
--- /dev/null
+++ b/media/java/android/media/MediaTimeProvider.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/** @hide */
+public interface MediaTimeProvider {
+    // we do not allow negative media time
+    /**
+     * Presentation time value if no timed event notification is requested.
+     */
+    public final static long NO_TIME = -1;
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If timeUs is
+     * not negative, it also registers the listener for a timed event
+     * notification when the presentation time reaches (becomes greater) than
+     * the value specified.  This happens immediately if the current media time
+     * is larger than or equal to timeUs.
+     *
+     * @param timeUs presentation time to get timed event callback at (or
+     *               {@link #NO_TIME})
+     */
+    public void notifyAt(long timeUs, OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If the media
+     * is stopped, the listener will immediately receive a stop notification.
+     * Otherwise, it will receive a timed event notificaton.
+     */
+    public void scheduleUpdate(OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.
+     */
+    public void cancelNotifications(OnMediaTimeListener listener);
+
+    /**
+     * Get the current presentation time.
+     *
+     * @param precise   Whether getting a precise time is important. This is
+     *                  more costly.
+     * @param monotonic Whether returned time should be monotonic: that is,
+     *                  greater than or equal to the last returned time.  Don't
+     *                  always set this to true.  E.g. this has undesired
+     *                  consequences if the media is seeked between calls.
+     * @throws IllegalStateException if the media is not initialized
+     */
+    public long getCurrentTimeUs(boolean precise, boolean monotonic)
+            throws IllegalStateException;
+
+    /** @hide */
+    public static interface OnMediaTimeListener {
+        /**
+         * Called when the registered time was reached naturally.
+         *
+         * @param timeUs current media time
+         */
+        void onTimedEvent(long timeUs);
+
+        /**
+         * Called when the media time changed due to seeking.
+         *
+         * @param timeUs current media time
+         */
+        void onSeek(long timeUs);
+
+        /**
+         * Called when the playback stopped.  This is not called on pause, only
+         * on full stop, at which point there is no further current media time.
+         */
+        void onStop();
+    }
+}
+
diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java
new file mode 100644
index 0000000..2cf1b2d
--- /dev/null
+++ b/media/java/android/media/SubtitleController.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import android.content.Context;
+import android.media.MediaPlayer.OnSubtitleDataListener;
+import android.view.View;
+import android.view.accessibility.CaptioningManager;
+
+/**
+ * The subtitle controller provides the architecture to display subtitles for a
+ * media source.  It allows specifying which tracks to display, on which anchor
+ * to display them, and also allows adding external, out-of-band subtitle tracks.
+ *
+ * @hide
+ */
+public class SubtitleController {
+    private Context mContext;
+    private MediaTimeProvider mTimeProvider;
+    private Vector<Renderer> mRenderers;
+    private Vector<SubtitleTrack> mTracks;
+    private SubtitleTrack mSelectedTrack;
+    private boolean mShowing;
+    private CaptioningManager mCaptioningManager;
+
+    /**
+     * Creates a subtitle controller for a media playback object that implements
+     * the MediaTimeProvider interface.
+     *
+     * @param timeProvider
+     */
+    public SubtitleController(
+            Context context,
+            MediaTimeProvider timeProvider,
+            Listener listener) {
+        mContext = context;
+        mTimeProvider = timeProvider;
+        mListener = listener;
+
+        mRenderers = new Vector<Renderer>();
+        mShowing = false;
+        mTracks = new Vector<SubtitleTrack>();
+        mCaptioningManager =
+            (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
+    }
+
+    /**
+     * @return the available subtitle tracks for this media. These include
+     * the tracks found by {@link MediaPlayer} as well as any tracks added
+     * manually via {@link #addTrack}.
+     */
+    public SubtitleTrack[] getTracks() {
+        SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
+        mTracks.toArray(tracks);
+        return tracks;
+    }
+
+    /**
+     * @return the currently selected subtitle track
+     */
+    public SubtitleTrack getSelectedTrack() {
+        return mSelectedTrack;
+    }
+
+    private View getSubtitleView() {
+        if (mSelectedTrack == null) {
+            return null;
+        }
+        return mSelectedTrack.getView();
+    }
+
+    /**
+     * Selects a subtitle track.  As a result, this track will receive
+     * in-band data from the {@link MediaPlayer}.  However, this does
+     * not change the subtitle visibility.
+     *
+     * @param track The subtitle track to select.  This must be one of the
+     *              tracks in {@link #getTracks}.
+     * @return true if the track was successfully selected.
+     */
+    public boolean selectTrack(SubtitleTrack track) {
+        if (track != null && !mTracks.contains(track)) {
+            return false;
+        }
+        mTrackIsExplicit = true;
+        if (mSelectedTrack == track) {
+            return true;
+        }
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+            mSelectedTrack.setTimeProvider(null);
+        }
+
+        mSelectedTrack = track;
+        mAnchor.setSubtitleView(getSubtitleView());
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.setTimeProvider(mTimeProvider);
+            mSelectedTrack.show();
+        }
+
+        if (mListener != null) {
+            mListener.onSubtitleTrackSelected(track);
+        }
+        return true;
+    }
+
+    /**
+     * @return the default subtitle track based on system preferences, or null,
+     * if no such track exists in this manager.
+     */
+    public SubtitleTrack getDefaultTrack() {
+        Locale locale = mCaptioningManager.getLocale();
+
+        for (SubtitleTrack track: mTracks) {
+            MediaFormat format = track.getFormat();
+            String language = format.getString(MediaFormat.KEY_LANGUAGE);
+            // TODO: select track with best renderer.  For now, we select first
+            // track with local's language or first track if locale has none
+            if (locale == null ||
+                locale.getLanguage().equals("") ||
+                locale.getISO3Language().equals(language) ||
+                locale.getLanguage().equals(language)) {
+                return track;
+            }
+        }
+        return null;
+    }
+
+    private boolean mTrackIsExplicit = false;
+    private boolean mVisibilityIsExplicit = false;
+
+    /** @hide */
+    public void selectDefaultTrack() {
+        if (mTrackIsExplicit) {
+            return;
+        }
+
+        SubtitleTrack track = getDefaultTrack();
+        if (track != null) {
+            selectTrack(track);
+            mTrackIsExplicit = false;
+            if (!mVisibilityIsExplicit) {
+                if (mCaptioningManager.isEnabled()) {
+                    show();
+                } else {
+                    hide();
+                }
+                mVisibilityIsExplicit = false;
+            }
+        }
+    }
+
+    /** @hide */
+    public void reset() {
+        hide();
+        selectTrack(null);
+        mTracks.clear();
+        mTrackIsExplicit = false;
+        mVisibilityIsExplicit = false;
+    }
+
+    /**
+     * Adds a new, external subtitle track to the manager.
+     *
+     * @param format the format of the track that will include at least
+     *               the MIME type {@link MediaFormat@KEY_MIME}.
+     * @return the created {@link SubtitleTrack} object
+     */
+    public SubtitleTrack addTrack(MediaFormat format) {
+        for (Renderer renderer: mRenderers) {
+            if (renderer.supports(format)) {
+                SubtitleTrack track = renderer.createTrack(format);
+                if (track != null) {
+                    mTracks.add(track);
+                    return track;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Show the selected (or default) subtitle track.
+     */
+    public void show() {
+        mShowing = true;
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.show();
+        }
+    }
+
+    /**
+     * Hide the selected (or default) subtitle track.
+     */
+    public void hide() {
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+        }
+        mShowing = false;
+    }
+
+    /**
+     * Interface for supporting a single or multiple subtitle types in {@link
+     * MediaPlayer}.
+     */
+    public abstract static class Renderer {
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
+         * subtitle track is detected, to see if it should use this object to
+         * parse and display this subtitle track.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         *
+         * @return true if and only if the track format is supported by this
+         * renderer
+         */
+        public abstract boolean supports(MediaFormat format);
+
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
+         * subtitle track that was detected and is supported by this object to
+         * create a {@link SubtitleTrack} object.  This object will be created
+         * for each track that was found.  If the track is selected for display,
+         * this object will be used to parse and display the track data.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         * @return a {@link SubtitleTrack} object that will be used to parse
+         * and render the subtitle track.
+         */
+        public abstract SubtitleTrack createTrack(MediaFormat format);
+    }
+
+    /**
+     * Add support for a subtitle format in {@link MediaPlayer}.
+     *
+     * @param renderer a {@link SubtitleController.Renderer} object that adds
+     *                 support for a subtitle format.
+     */
+    public void registerRenderer(Renderer renderer) {
+        // TODO how to get available renderers in the system
+        if (!mRenderers.contains(renderer)) {
+            // TODO should added renderers override existing ones (to allow replacing?)
+            mRenderers.add(renderer);
+        }
+    }
+
+    /**
+     * Subtitle anchor, an object that is able to display a subtitle view,
+     * e.g. a VideoView.
+     */
+    public interface Anchor {
+        /**
+         * Anchor should set the subtitle view to the supplied view,
+         * or none, if the supplied view is null.
+         *
+         * @param view subtitle view, or null
+         */
+        public void setSubtitleView(View view);
+    }
+
+    private Anchor mAnchor;
+
+    /** @hide */
+    public void setAnchor(Anchor anchor) {
+        if (mAnchor == anchor) {
+            return;
+        }
+
+        if (mAnchor != null) {
+            mAnchor.setSubtitleView(null);
+        }
+        mAnchor = anchor;
+        if (mAnchor != null) {
+            mAnchor.setSubtitleView(getSubtitleView());
+        }
+    }
+
+    public interface Listener {
+        /**
+         * Called when a subtitle track has been selected.
+         *
+         * @param track selected subtitle track or null
+         * @hide
+         */
+        public void onSubtitleTrackSelected(SubtitleTrack track);
+    }
+
+    private Listener mListener;
+}
diff --git a/media/java/android/media/SubtitleTrack.java b/media/java/android/media/SubtitleTrack.java
new file mode 100644
index 0000000..09fb3f2
--- /dev/null
+++ b/media/java/android/media/SubtitleTrack.java
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.os.Handler;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Pair;
+import android.view.View;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
+/**
+ * A subtitle track abstract base class that is responsible for parsing and displaying
+ * an instance of a particular type of subtitle.
+ *
+ * @hide
+ */
+public abstract class SubtitleTrack implements MediaTimeProvider.OnMediaTimeListener {
+    private static final String TAG = "SubtitleTrack";
+    private long mLastUpdateTimeMs;
+    private long mLastTimeMs;
+
+    private Runnable mRunnable;
+
+    /** @hide TODO private */
+    final protected LongSparseArray<Run> mRunsByEndTime = new LongSparseArray<Run>();
+    /** @hide TODO private */
+    final protected LongSparseArray<Run> mRunsByID = new LongSparseArray<Run>();
+
+    /** @hide TODO private */
+    protected CueList mCues;
+    /** @hide TODO private */
+    final protected Vector<Cue> mActiveCues = new Vector<Cue>();
+    /** @hide */
+    protected boolean mVisible;
+
+    /** @hide */
+    public boolean DEBUG = false;
+
+    /** @hide */
+    protected Handler mHandler = new Handler();
+
+    private MediaFormat mFormat;
+
+    public SubtitleTrack(MediaFormat format) {
+        mFormat = format;
+        mCues = new CueList();
+        clearActiveCues();
+        mLastTimeMs = -1;
+    }
+
+    /** @hide */
+    public MediaFormat getFormat() {
+        return mFormat;
+    }
+
+    private long mNextScheduledTimeMs = -1;
+
+    /**
+     * Called when there is input data for the subtitle track.  The
+     * complete subtitle for a track can include multiple whole units
+     * (runs).  Each of these units can have multiple sections.  The
+     * contents of a run are submitted in sequential order, with eos
+     * indicating the last section of the run.  Calls from different
+     * runs must not be intermixed.
+     *
+     * @param data
+     * @param eos true if this is the last section of the run.
+     * @param runID mostly-unique ID for this run of data.  Subtitle cues
+     *              with runID of 0 are discarded immediately after
+     *              display.  Cues with runID of ~0 are discarded
+     *              only at the deletion of the track object.  Cues
+     *              with other runID-s are discarded at the end of the
+     *              run, which defaults to the latest timestamp of
+     *              any of its cues (with this runID).
+     *
+     * TODO use ByteBuffer
+     */
+    public abstract void onData(String data, boolean eos, long runID);
+
+    /**
+     * Called when adding the subtitle rendering view to the view hierarchy, as
+     * well as when showing or hiding the subtitle track, or when the video
+     * surface position has changed.
+     *
+     * @return the view object that displays this subtitle track.  For most
+     * renderers there should be a single shared view instance that is used
+     * for all tracks supported by that renderer, as at most one subtitle
+     * track is visible at one time.
+     */
+    public abstract View getView();
+
+    /**
+     * Called when the active cues have changed, and the contents of the subtitle
+     * view should be updated.
+     *
+     * @hide
+     */
+    public abstract void updateView(Vector<Cue> activeCues);
+
+    /** @hide */
+    protected synchronized void updateActiveCues(boolean rebuild, long timeMs) {
+        // out-of-order times mean seeking or new active cues being added
+        // (during their own timespan)
+        if (rebuild || mLastUpdateTimeMs > timeMs) {
+            clearActiveCues();
+        }
+
+        for(Iterator<Pair<Long, Cue> > it =
+                mCues.entriesBetween(mLastUpdateTimeMs, timeMs).iterator(); it.hasNext(); ) {
+            Pair<Long, Cue> event = it.next();
+            Cue cue = event.second;
+
+            if (cue.mEndTimeMs == event.first) {
+                // remove past cues
+                if (DEBUG) Log.v(TAG, "Removing " + cue);
+                mActiveCues.remove(cue);
+                if (cue.mRunID == 0) {
+                    it.remove();
+                }
+            } else if (cue.mStartTimeMs == event.first) {
+                // add new cues
+                // TRICKY: this will happen in start order
+                if (DEBUG) Log.v(TAG, "Adding " + cue);
+                if (cue.mInnerTimesMs != null) {
+                    cue.onTime(timeMs);
+                }
+                mActiveCues.add(cue);
+            } else if (cue.mInnerTimesMs != null) {
+                // cue is modified
+                cue.onTime(timeMs);
+            }
+        }
+
+        /* complete any runs */
+        while (mRunsByEndTime.size() > 0 &&
+               mRunsByEndTime.keyAt(0) <= timeMs) {
+            removeRunsByEndTimeIndex(0); // removes element
+        }
+        mLastUpdateTimeMs = timeMs;
+    }
+
+    private void removeRunsByEndTimeIndex(int ix) {
+        Run run = mRunsByEndTime.valueAt(ix);
+        while (run != null) {
+            Cue cue = run.mFirstCue;
+            while (cue != null) {
+                mCues.remove(cue);
+                Cue nextCue = cue.mNextInRun;
+                cue.mNextInRun = null;
+                cue = nextCue;
+            }
+            mRunsByID.remove(run.mRunID);
+            Run nextRun = run.mNextRunAtEndTimeMs;
+            run.mPrevRunAtEndTimeMs = null;
+            run.mNextRunAtEndTimeMs = null;
+            run = nextRun;
+        }
+        mRunsByEndTime.removeAt(ix);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        /* remove all cues (untangle all cross-links) */
+        int size = mRunsByEndTime.size();
+        for(int ix = size - 1; ix >= 0; ix--) {
+            removeRunsByEndTimeIndex(ix);
+        }
+
+        super.finalize();
+    }
+
+    private synchronized void takeTime(long timeMs) {
+        mLastTimeMs = timeMs;
+    }
+
+    /** @hide */
+    protected synchronized void clearActiveCues() {
+        if (DEBUG) Log.v(TAG, "Clearing " + mActiveCues.size() + " active cues");
+        mActiveCues.clear();
+        mLastUpdateTimeMs = -1;
+    }
+
+    /** @hide */
+    public void scheduleTimedEvents() {
+        /* get times for the next event */
+        if (mTimeProvider != null) {
+            mNextScheduledTimeMs = mCues.nextTimeAfter(mLastTimeMs);
+            if (DEBUG) Log.d(TAG, "sched @" + mNextScheduledTimeMs + " after " + mLastTimeMs);
+            mTimeProvider.notifyAt(
+                    mNextScheduledTimeMs >= 0 ?
+                        (mNextScheduledTimeMs * 1000) : MediaTimeProvider.NO_TIME,
+                    this);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onTimedEvent(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onTimedEvent " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(false, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onSeek(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onSeek " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(true, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onStop() {
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "onStop");
+            clearActiveCues();
+            mLastTimeMs = -1;
+        }
+        updateView(mActiveCues);
+        mNextScheduledTimeMs = -1;
+        mTimeProvider.notifyAt(MediaTimeProvider.NO_TIME, this);
+    }
+
+    /** @hide */
+    protected MediaTimeProvider mTimeProvider;
+
+    /** @hide */
+    public void show() {
+        if (mVisible) {
+            return;
+        }
+
+        mVisible = true;
+        getView().setVisibility(View.VISIBLE);
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+    /** @hide */
+    public void hide() {
+        if (!mVisible) {
+            return;
+        }
+
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        getView().setVisibility(View.INVISIBLE);
+        mVisible = false;
+    }
+
+    /** @hide */
+    protected synchronized boolean addCue(Cue cue) {
+        mCues.add(cue);
+
+        if (cue.mRunID != 0) {
+            Run run = mRunsByID.get(cue.mRunID);
+            if (run == null) {
+                run = new Run();
+                mRunsByID.put(cue.mRunID, run);
+                run.mEndTimeMs = cue.mEndTimeMs;
+            } else if (run.mEndTimeMs < cue.mEndTimeMs) {
+                run.mEndTimeMs = cue.mEndTimeMs;
+            }
+
+            // link-up cues in the same run
+            cue.mNextInRun = run.mFirstCue;
+            run.mFirstCue = cue;
+        }
+
+        // if a cue is added that should be visible, need to refresh view
+        long nowMs = -1;
+        if (mTimeProvider != null) {
+            try {
+                nowMs = mTimeProvider.getCurrentTimeUs(
+                        false /* precise */, true /* monotonic */) / 1000;
+            } catch (IllegalStateException e) {
+                // handle as it we are not playing
+            }
+        }
+
+        if (DEBUG) Log.v(TAG, "mVisible=" + mVisible + ", " +
+                cue.mStartTimeMs + " <= " + nowMs + ", " +
+                cue.mEndTimeMs + " >= " + mLastTimeMs);
+
+        if (mVisible &&
+                cue.mStartTimeMs <= nowMs &&
+                // we don't trust nowMs, so check any cue since last callback
+                cue.mEndTimeMs >= mLastTimeMs) {
+            if (mRunnable != null) {
+                mHandler.removeCallbacks(mRunnable);
+            }
+            final SubtitleTrack track = this;
+            final long thenMs = nowMs;
+            mRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    // even with synchronized, it is possible that we are going
+                    // to do multiple updates as the runnable could be already
+                    // running.
+                    synchronized (track) {
+                        mRunnable = null;
+                        updateActiveCues(true, thenMs);
+                        updateView(mActiveCues);
+                    }
+                }
+            };
+            // delay update so we don't update view on every cue.  TODO why 10?
+            if (mHandler.postDelayed(mRunnable, 10 /* delay */)) {
+                if (DEBUG) Log.v(TAG, "scheduling update");
+            } else {
+                if (DEBUG) Log.w(TAG, "failed to schedule subtitle view update");
+            }
+            return true;
+        }
+
+        if (mVisible &&
+                cue.mEndTimeMs >= mLastTimeMs &&
+                (cue.mStartTimeMs < mNextScheduledTimeMs ||
+                 mNextScheduledTimeMs < 0)) {
+            scheduleTimedEvents();
+        }
+
+        return false;
+    }
+
+    /** @hide */
+    public void setTimeProvider(MediaTimeProvider timeProvider) {
+        if (mTimeProvider == timeProvider) {
+            return;
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        mTimeProvider = timeProvider;
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+
+    /** @hide */
+    static class CueList {
+        private static final String TAG = "CueList";
+        // simplistic, inefficient implementation
+        private SortedMap<Long, Vector<Cue> > mCues;
+        public boolean DEBUG = false;
+
+        private boolean addEvent(Cue cue, long timeMs) {
+            Vector<Cue> cues = mCues.get(timeMs);
+            if (cues == null) {
+                cues = new Vector<Cue>(2);
+                mCues.put(timeMs, cues);
+            } else if (cues.contains(cue)) {
+                // do not duplicate cues
+                return false;
+            }
+
+            cues.add(cue);
+            return true;
+        }
+
+        private void removeEvent(Cue cue, long timeMs) {
+            Vector<Cue> cues = mCues.get(timeMs);
+            if (cues != null) {
+                cues.remove(cue);
+                if (cues.size() == 0) {
+                    mCues.remove(timeMs);
+                }
+            }
+        }
+
+        public void add(Cue cue) {
+            // ignore non-positive-duration cues
+            if (cue.mStartTimeMs >= cue.mEndTimeMs)
+                return;
+
+            if (!addEvent(cue, cue.mStartTimeMs)) {
+                return;
+            }
+
+            long lastTimeMs = cue.mStartTimeMs;
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    if (timeMs > lastTimeMs && timeMs < cue.mEndTimeMs) {
+                        addEvent(cue, timeMs);
+                        lastTimeMs = timeMs;
+                    }
+                }
+            }
+
+            addEvent(cue, cue.mEndTimeMs);
+        }
+
+        public void remove(Cue cue) {
+            removeEvent(cue, cue.mStartTimeMs);
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    removeEvent(cue, timeMs);
+                }
+            }
+            removeEvent(cue, cue.mEndTimeMs);
+        }
+
+        public Iterable<Pair<Long, Cue>> entriesBetween(
+                final long lastTimeMs, final long timeMs) {
+            return new Iterable<Pair<Long, Cue> >() {
+                @Override
+                public Iterator<Pair<Long, Cue> > iterator() {
+                    if (DEBUG) Log.d(TAG, "slice (" + lastTimeMs + ", " + timeMs + "]=");
+                    try {
+                        return new EntryIterator(
+                                mCues.subMap(lastTimeMs + 1, timeMs + 1));
+                    } catch(IllegalArgumentException e) {
+                        return new EntryIterator(null);
+                    }
+                }
+            };
+        }
+
+        public long nextTimeAfter(long timeMs) {
+            SortedMap<Long, Vector<Cue>> tail = null;
+            try {
+                tail = mCues.tailMap(timeMs + 1);
+                if (tail != null) {
+                    return tail.firstKey();
+                } else {
+                    return -1;
+                }
+            } catch(IllegalArgumentException e) {
+                return -1;
+            } catch(NoSuchElementException e) {
+                return -1;
+            }
+        }
+
+        class EntryIterator implements Iterator<Pair<Long, Cue> > {
+            @Override
+            public boolean hasNext() {
+                return !mDone;
+            }
+
+            @Override
+            public Pair<Long, Cue> next() {
+                if (mDone) {
+                    throw new NoSuchElementException("");
+                }
+                mLastEntry = new Pair<Long, Cue>(
+                        mCurrentTimeMs, mListIterator.next());
+                mLastListIterator = mListIterator;
+                if (!mListIterator.hasNext()) {
+                    nextKey();
+                }
+                return mLastEntry;
+            }
+
+            @Override
+            public void remove() {
+                // only allow removing end tags
+                if (mLastListIterator == null ||
+                        mLastEntry.second.mEndTimeMs != mLastEntry.first) {
+                    throw new IllegalStateException("");
+                }
+
+                // remove end-cue
+                mLastListIterator.remove();
+                mLastListIterator = null;
+                if (mCues.get(mLastEntry.first).size() == 0) {
+                    mCues.remove(mLastEntry.first);
+                }
+
+                // remove rest of the cues
+                Cue cue = mLastEntry.second;
+                removeEvent(cue, cue.mStartTimeMs);
+                if (cue.mInnerTimesMs != null) {
+                    for (long timeMs: cue.mInnerTimesMs) {
+                        removeEvent(cue, timeMs);
+                    }
+                }
+            }
+
+            public EntryIterator(SortedMap<Long, Vector<Cue> > cues) {
+                if (DEBUG) Log.v(TAG, cues + "");
+                mRemainingCues = cues;
+                mLastListIterator = null;
+                nextKey();
+            }
+
+            private void nextKey() {
+                do {
+                    try {
+                        if (mRemainingCues == null) {
+                            throw new NoSuchElementException("");
+                        }
+                        mCurrentTimeMs = mRemainingCues.firstKey();
+                        mListIterator =
+                            mRemainingCues.get(mCurrentTimeMs).iterator();
+                        try {
+                            mRemainingCues =
+                                mRemainingCues.tailMap(mCurrentTimeMs + 1);
+                        } catch (IllegalArgumentException e) {
+                            mRemainingCues = null;
+                        }
+                        mDone = false;
+                    } catch (NoSuchElementException e) {
+                        mDone = true;
+                        mRemainingCues = null;
+                        mListIterator = null;
+                        return;
+                    }
+                } while (!mListIterator.hasNext());
+            }
+
+            private long mCurrentTimeMs;
+            private Iterator<Cue> mListIterator;
+            private boolean mDone;
+            private SortedMap<Long, Vector<Cue> > mRemainingCues;
+            private Iterator<Cue> mLastListIterator;
+            private Pair<Long,Cue> mLastEntry;
+        }
+
+        CueList() {
+            mCues = new TreeMap<Long, Vector<Cue>>();
+        }
+    }
+
+    /** @hide */
+    public static class Cue {
+        public long mStartTimeMs;
+        public long mEndTimeMs;
+        public long[] mInnerTimesMs;
+        public long mRunID;
+
+        /** @hide */
+        public Cue mNextInRun;
+
+        public void onTime(long timeMs) { }
+    }
+
+    /** @hide update mRunsByEndTime (with default end time) */
+    protected void finishedRun(long runID) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** @hide update mRunsByEndTime with given end time */
+    public void setRunDiscardTimeMs(long runID, long timeMs) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.mEndTimeMs = timeMs;
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** @hide */
+    private static class Run {
+        public Cue mFirstCue;
+        public Run mNextRunAtEndTimeMs;
+        public Run mPrevRunAtEndTimeMs;
+        public long mEndTimeMs = -1;
+        public long mRunID = 0;
+        private long mStoredEndTimeMs = -1;
+
+        public void storeByEndTimeMs(LongSparseArray<Run> runsByEndTime) {
+            // remove old value if any
+            int ix = runsByEndTime.indexOfKey(mStoredEndTimeMs);
+            if (ix >= 0) {
+                if (mPrevRunAtEndTimeMs == null) {
+                    assert(this == runsByEndTime.valueAt(ix));
+                    if (mNextRunAtEndTimeMs == null) {
+                        runsByEndTime.removeAt(ix);
+                    } else {
+                        runsByEndTime.setValueAt(ix, mNextRunAtEndTimeMs);
+                    }
+                }
+                removeAtEndTimeMs();
+            }
+
+            // add new value
+            if (mEndTimeMs >= 0) {
+                mPrevRunAtEndTimeMs = null;
+                mNextRunAtEndTimeMs = runsByEndTime.get(mEndTimeMs);
+                if (mNextRunAtEndTimeMs != null) {
+                    mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = this;
+                }
+                runsByEndTime.put(mEndTimeMs, this);
+                mStoredEndTimeMs = mEndTimeMs;
+            }
+        }
+
+        public void removeAtEndTimeMs() {
+            Run prev = mPrevRunAtEndTimeMs;
+
+            if (mPrevRunAtEndTimeMs != null) {
+                mPrevRunAtEndTimeMs.mNextRunAtEndTimeMs = mNextRunAtEndTimeMs;
+                mPrevRunAtEndTimeMs = null;
+            }
+            if (mNextRunAtEndTimeMs != null) {
+                mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = prev;
+                mNextRunAtEndTimeMs = null;
+            }
+        }
+    }
+}
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
new file mode 100644
index 0000000..527c57f
--- /dev/null
+++ b/media/java/android/media/WebVttRenderer.java
@@ -0,0 +1,1094 @@
+package android.media;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.TextView;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/** @hide */
+public class WebVttRenderer extends SubtitleController.Renderer {
+    private TextView mMyTextView;
+
+    public WebVttRenderer(Context context, AttributeSet attrs) {
+        mMyTextView = new WebVttView(context, attrs);
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            return format.getString(MediaFormat.KEY_MIME).equals("text/vtt");
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        return new WebVttTrack(format, mMyTextView);
+    }
+}
+
+/** @hide */
+class WebVttView extends TextView {
+    public WebVttView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setTextColor(0xffffff00);
+        setTextSize(46);
+        setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
+        setLayoutParams(new LayoutParams(
+                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
+    }
+}
+
+/** @hide */
+class TextTrackCueSpan {
+    long mTimestampMs;
+    boolean mEnabled;
+    String mText;
+    TextTrackCueSpan(String text, long timestamp) {
+        mTimestampMs = timestamp;
+        mText = text;
+        // spans with timestamp will be enabled by Cue.onTime
+        mEnabled = (mTimestampMs < 0);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TextTrackCueSpan)) {
+            return false;
+        }
+        TextTrackCueSpan span = (TextTrackCueSpan) o;
+        return mTimestampMs == span.mTimestampMs &&
+                mText.equals(span.mText);
+    }
+}
+
+/**
+ * @hide
+ *
+ * Extract all text without style, but with timestamp spans.
+ */
+class UnstyledTextExtractor implements Tokenizer.OnTokenListener {
+    StringBuilder mLine = new StringBuilder();
+    Vector<TextTrackCueSpan[]> mLines = new Vector<TextTrackCueSpan[]>();
+    Vector<TextTrackCueSpan> mCurrentLine = new Vector<TextTrackCueSpan>();
+    long mLastTimestamp;
+
+    UnstyledTextExtractor() {
+        init();
+    }
+
+    private void init() {
+        mLine.delete(0, mLine.length());
+        mLines.clear();
+        mCurrentLine.clear();
+        mLastTimestamp = -1;
+    }
+
+    @Override
+    public void onData(String s) {
+        mLine.append(s);
+    }
+
+    @Override
+    public void onStart(String tag, String[] classes, String annotation) { }
+
+    @Override
+    public void onEnd(String tag) { }
+
+    @Override
+    public void onTimeStamp(long timestampMs) {
+        // finish any prior span
+        if (mLine.length() > 0 && timestampMs != mLastTimestamp) {
+            mCurrentLine.add(
+                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+            mLine.delete(0, mLine.length());
+        }
+        mLastTimestamp = timestampMs;
+    }
+
+    @Override
+    public void onLineEnd() {
+        // finish any pending span
+        if (mLine.length() > 0) {
+            mCurrentLine.add(
+                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+            mLine.delete(0, mLine.length());
+        }
+
+        TextTrackCueSpan[] spans = new TextTrackCueSpan[mCurrentLine.size()];
+        mCurrentLine.toArray(spans);
+        mCurrentLine.clear();
+        mLines.add(spans);
+    }
+
+    public TextTrackCueSpan[][] getText() {
+        // for politeness, finish last cue-line if it ends abruptly
+        if (mLine.length() > 0 || mCurrentLine.size() > 0) {
+            onLineEnd();
+        }
+        TextTrackCueSpan[][] lines = new TextTrackCueSpan[mLines.size()][];
+        mLines.toArray(lines);
+        init();
+        return lines;
+    }
+}
+
+/**
+ * @hide
+ *
+ * Tokenizer tokenizes the WebVTT Cue Text into tags and data
+ */
+class Tokenizer {
+    private static final String TAG = "Tokenizer";
+    private TokenizerPhase mPhase;
+    private TokenizerPhase mDataTokenizer;
+    private TokenizerPhase mTagTokenizer;
+
+    private OnTokenListener mListener;
+    private String mLine;
+    private int mHandledLen;
+
+    interface TokenizerPhase {
+        TokenizerPhase start();
+        void tokenize();
+    }
+
+    class DataTokenizer implements TokenizerPhase {
+        // includes both WebVTT data && escape state
+        private StringBuilder mData;
+
+        public TokenizerPhase start() {
+            mData = new StringBuilder();
+            return this;
+        }
+
+        private boolean replaceEscape(String escape, String replacement, int pos) {
+            if (mLine.startsWith(escape, pos)) {
+                mData.append(mLine.substring(mHandledLen, pos));
+                mData.append(replacement);
+                mHandledLen = pos + escape.length();
+                pos = mHandledLen - 1;
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void tokenize() {
+            int end = mLine.length();
+            for (int pos = mHandledLen; pos < mLine.length(); pos++) {
+                if (mLine.charAt(pos) == '&') {
+                    if (replaceEscape("&amp;", "&", pos) ||
+                            replaceEscape("&lt;", "<", pos) ||
+                            replaceEscape("&gt;", ">", pos) ||
+                            replaceEscape("&lrm;", "\u200e", pos) ||
+                            replaceEscape("&rlm;", "\u200f", pos) ||
+                            replaceEscape("&nbsp;", "\u00a0", pos)) {
+                        continue;
+                    }
+                } else if (mLine.charAt(pos) == '<') {
+                    end = pos;
+                    mPhase = mTagTokenizer.start();
+                    break;
+                }
+            }
+            mData.append(mLine.substring(mHandledLen, end));
+            // yield mData
+            mListener.onData(mData.toString());
+            mData.delete(0, mData.length());
+            mHandledLen = end;
+        }
+    }
+
+    class TagTokenizer implements TokenizerPhase {
+        private boolean mAtAnnotation;
+        private String mName, mAnnotation;
+
+        public TokenizerPhase start() {
+            mName = mAnnotation = "";
+            mAtAnnotation = false;
+            return this;
+        }
+
+        @Override
+        public void tokenize() {
+            if (!mAtAnnotation)
+                mHandledLen++;
+            if (mHandledLen < mLine.length()) {
+                String[] parts;
+                /**
+                 * Collect annotations and end-tags to closing >.  Collect tag
+                 * name to closing bracket or next white-space.
+                 */
+                if (mAtAnnotation || mLine.charAt(mHandledLen) == '/') {
+                    parts = mLine.substring(mHandledLen).split(">");
+                } else {
+                    parts = mLine.substring(mHandledLen).split("[\t\f >]");
+                }
+                String part = mLine.substring(
+                            mHandledLen, mHandledLen + parts[0].length());
+                mHandledLen += parts[0].length();
+
+                if (mAtAnnotation) {
+                    mAnnotation += " " + part;
+                } else {
+                    mName = part;
+                }
+            }
+
+            mAtAnnotation = true;
+
+            if (mHandledLen < mLine.length() && mLine.charAt(mHandledLen) == '>') {
+                yield_tag();
+                mPhase = mDataTokenizer.start();
+                mHandledLen++;
+            }
+        }
+
+        private void yield_tag() {
+            if (mName.startsWith("/")) {
+                mListener.onEnd(mName.substring(1));
+            } else if (mName.length() > 0 && Character.isDigit(mName.charAt(0))) {
+                // timestamp
+                try {
+                    long timestampMs = WebVttParser.parseTimestampMs(mName);
+                    mListener.onTimeStamp(timestampMs);
+                } catch (NumberFormatException e) {
+                    Log.d(TAG, "invalid timestamp tag: <" + mName + ">");
+                }
+            } else {
+                mAnnotation = mAnnotation.replaceAll("\\s+", " ");
+                if (mAnnotation.startsWith(" ")) {
+                    mAnnotation = mAnnotation.substring(1);
+                }
+                if (mAnnotation.endsWith(" ")) {
+                    mAnnotation = mAnnotation.substring(0, mAnnotation.length() - 1);
+                }
+
+                String[] classes = null;
+                int dotAt = mName.indexOf('.');
+                if (dotAt >= 0) {
+                    classes = mName.substring(dotAt + 1).split("\\.");
+                    mName = mName.substring(0, dotAt);
+                }
+                mListener.onStart(mName, classes, mAnnotation);
+            }
+        }
+    }
+
+    Tokenizer(OnTokenListener listener) {
+        mDataTokenizer = new DataTokenizer();
+        mTagTokenizer = new TagTokenizer();
+        reset();
+        mListener = listener;
+    }
+
+    void reset() {
+        mPhase = mDataTokenizer.start();
+    }
+
+    void tokenize(String s) {
+        mHandledLen = 0;
+        mLine = s;
+        while (mHandledLen < mLine.length()) {
+            mPhase.tokenize();
+        }
+        /* we are finished with a line unless we are in the middle of a tag */
+        if (!(mPhase instanceof TagTokenizer)) {
+            // yield END-OF-LINE
+            mListener.onLineEnd();
+        }
+    }
+
+    interface OnTokenListener {
+        void onData(String s);
+        void onStart(String tag, String[] classes, String annotation);
+        void onEnd(String tag);
+        void onTimeStamp(long timestampMs);
+        void onLineEnd();
+    }
+}
+
+/** @hide */
+class TextTrackRegion {
+    final static int SCROLL_VALUE_NONE      = 300;
+    final static int SCROLL_VALUE_SCROLL_UP = 301;
+
+    String mId;
+    float mWidth;
+    int mLines;
+    float mAnchorPointX, mAnchorPointY;
+    float mViewportAnchorPointX, mViewportAnchorPointY;
+    int mScrollValue;
+
+    TextTrackRegion() {
+        mId = "";
+        mWidth = 100;
+        mLines = 3;
+        mAnchorPointX = mViewportAnchorPointX = 0.f;
+        mAnchorPointY = mViewportAnchorPointY = 100.f;
+        mScrollValue = SCROLL_VALUE_NONE;
+    }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder(" {id:\"").append(mId)
+            .append("\", width:").append(mWidth)
+            .append(", lines:").append(mLines)
+            .append(", anchorPoint:(").append(mAnchorPointX)
+            .append(", ").append(mAnchorPointY)
+            .append("), viewportAnchorPoints:").append(mViewportAnchorPointX)
+            .append(", ").append(mViewportAnchorPointY)
+            .append("), scrollValue:")
+            .append(mScrollValue == SCROLL_VALUE_NONE ? "none" :
+                    mScrollValue == SCROLL_VALUE_SCROLL_UP ? "scroll_up" :
+                    "INVALID")
+            .append("}");
+        return res.toString();
+    }
+}
+
+/** @hide */
+class TextTrackCue extends SubtitleTrack.Cue {
+    final static int WRITING_DIRECTION_HORIZONTAL  = 100;
+    final static int WRITING_DIRECTION_VERTICAL_RL = 101;
+    final static int WRITING_DIRECTION_VERTICAL_LR = 102;
+
+    final static int ALIGNMENT_MIDDLE = 200;
+    final static int ALIGNMENT_START  = 201;
+    final static int ALIGNMENT_END    = 202;
+    final static int ALIGNMENT_LEFT   = 203;
+    final static int ALIGNMENT_RIGHT  = 204;
+    private static final String TAG = "TTCue";
+
+    String  mId;
+    boolean mPauseOnExit;
+    int     mWritingDirection;
+    String  mRegionId;
+    boolean mSnapToLines;
+    Integer mLinePosition;  // null means AUTO
+    boolean mAutoLinePosition;
+    int     mTextPosition;
+    int     mSize;
+    int     mAlignment;
+    // Vector<String> mText;
+    String[] mStrings;
+    TextTrackCueSpan[][] mLines;
+    TextTrackRegion mRegion;
+
+    TextTrackCue() {
+        mId = "";
+        mPauseOnExit = false;
+        mWritingDirection = WRITING_DIRECTION_HORIZONTAL;
+        mRegionId = "";
+        mSnapToLines = true;
+        mLinePosition = null /* AUTO */;
+        mTextPosition = 50;
+        mSize = 100;
+        mAlignment = ALIGNMENT_MIDDLE;
+        mLines = null;
+        mRegion = null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TextTrackCue)) {
+            return false;
+        }
+        if (this == o) {
+            return true;
+        }
+
+        try {
+            TextTrackCue cue = (TextTrackCue) o;
+            boolean res = mId.equals(cue.mId) &&
+                    mPauseOnExit == cue.mPauseOnExit &&
+                    mWritingDirection == cue.mWritingDirection &&
+                    mRegionId.equals(cue.mRegionId) &&
+                    mSnapToLines == cue.mSnapToLines &&
+                    mAutoLinePosition == cue.mAutoLinePosition &&
+                    (mAutoLinePosition || mLinePosition == cue.mLinePosition) &&
+                    mTextPosition == cue.mTextPosition &&
+                    mSize == cue.mSize &&
+                    mAlignment == cue.mAlignment &&
+                    mLines.length == cue.mLines.length;
+            if (res == true) {
+                for (int line = 0; line < mLines.length; line++) {
+                    if (!Arrays.equals(mLines[line], cue.mLines[line])) {
+                        return false;
+                    }
+                }
+            }
+            return res;
+        } catch(IncompatibleClassChangeError e) {
+            return false;
+        }
+    }
+
+    public StringBuilder appendStringsToBuilder(StringBuilder builder) {
+        if (mStrings == null) {
+            builder.append("null");
+        } else {
+            builder.append("[");
+            boolean first = true;
+            for (String s: mStrings) {
+                if (!first) {
+                    builder.append(", ");
+                }
+                if (s == null) {
+                    builder.append("null");
+                } else {
+                    builder.append("\"");
+                    builder.append(s);
+                    builder.append("\"");
+                }
+                first = false;
+            }
+            builder.append("]");
+        }
+        return builder;
+    }
+
+    public StringBuilder appendLinesToBuilder(StringBuilder builder) {
+        if (mLines == null) {
+            builder.append("null");
+        } else {
+            builder.append("[");
+            boolean first = true;
+            for (TextTrackCueSpan[] spans: mLines) {
+                if (!first) {
+                    builder.append(", ");
+                }
+                if (spans == null) {
+                    builder.append("null");
+                } else {
+                    builder.append("\"");
+                    boolean innerFirst = true;
+                    long lastTimestamp = -1;
+                    for (TextTrackCueSpan span: spans) {
+                        if (!innerFirst) {
+                            builder.append(" ");
+                        }
+                        if (span.mTimestampMs != lastTimestamp) {
+                            builder.append("<")
+                                    .append(WebVttParser.timeToString(
+                                            span.mTimestampMs))
+                                    .append(">");
+                            lastTimestamp = span.mTimestampMs;
+                        }
+                        builder.append(span.mText);
+                        innerFirst = false;
+                    }
+                    builder.append("\"");
+                }
+                first = false;
+            }
+            builder.append("]");
+        }
+        return builder;
+    }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder();
+
+        res.append(WebVttParser.timeToString(mStartTimeMs))
+                .append(" --> ").append(WebVttParser.timeToString(mEndTimeMs))
+                .append(" {id:\"").append(mId)
+                .append("\", pauseOnExit:").append(mPauseOnExit)
+                .append(", direction:")
+                .append(mWritingDirection == WRITING_DIRECTION_HORIZONTAL ? "horizontal" :
+                        mWritingDirection == WRITING_DIRECTION_VERTICAL_LR ? "vertical_lr" :
+                        mWritingDirection == WRITING_DIRECTION_VERTICAL_RL ? "vertical_rl" :
+                        "INVALID")
+                .append(", regionId:\"").append(mRegionId)
+                .append("\", snapToLines:").append(mSnapToLines)
+                .append(", linePosition:").append(mAutoLinePosition ? "auto" :
+                                                  mLinePosition)
+                .append(", textPosition:").append(mTextPosition)
+                .append(", size:").append(mSize)
+                .append(", alignment:")
+                .append(mAlignment == ALIGNMENT_END ? "end" :
+                        mAlignment == ALIGNMENT_LEFT ? "left" :
+                        mAlignment == ALIGNMENT_MIDDLE ? "middle" :
+                        mAlignment == ALIGNMENT_RIGHT ? "right" :
+                        mAlignment == ALIGNMENT_START ? "start" : "INVALID")
+                .append(", text:");
+        appendStringsToBuilder(res).append("}");
+        return res.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public void onTime(long timeMs) {
+        for (TextTrackCueSpan[] line: mLines) {
+            for (TextTrackCueSpan span: line) {
+                span.mEnabled = timeMs >= span.mTimestampMs;
+            }
+        }
+    }
+}
+
+/** @hide */
+class WebVttParser {
+    private static final String TAG = "WebVttParser";
+    private Phase mPhase;
+    private TextTrackCue mCue;
+    private Vector<String> mCueTexts;
+    private WebVttCueListener mListener;
+    private String mBuffer;
+
+    WebVttParser(WebVttCueListener listener) {
+        mPhase = mParseStart;
+        mBuffer = "";   /* mBuffer contains up to 1 incomplete line */
+        mListener = listener;
+        mCueTexts = new Vector<String>();
+    }
+
+    /* parsePercentageString */
+    public static float parseFloatPercentage(String s)
+            throws NumberFormatException {
+        if (!s.endsWith("%")) {
+            throw new NumberFormatException("does not end in %");
+        }
+        s = s.substring(0, s.length() - 1);
+        // parseFloat allows an exponent or a sign
+        if (s.matches(".*[^0-9.].*")) {
+            throw new NumberFormatException("contains an invalid character");
+        }
+
+        try {
+            float value = Float.parseFloat(s);
+            if (value < 0.0f || value > 100.0f) {
+                throw new NumberFormatException("is out of range");
+            }
+            return value;
+        } catch (NumberFormatException e) {
+            throw new NumberFormatException("is not a number");
+        }
+    }
+
+    public static int parseIntPercentage(String s) throws NumberFormatException {
+        if (!s.endsWith("%")) {
+            throw new NumberFormatException("does not end in %");
+        }
+        s = s.substring(0, s.length() - 1);
+        // parseInt allows "-0" that returns 0, so check for non-digits
+        if (s.matches(".*[^0-9].*")) {
+            throw new NumberFormatException("contains an invalid character");
+        }
+
+        try {
+            int value = Integer.parseInt(s);
+            if (value < 0 || value > 100) {
+                throw new NumberFormatException("is out of range");
+            }
+            return value;
+        } catch (NumberFormatException e) {
+            throw new NumberFormatException("is not a number");
+        }
+    }
+
+    public static long parseTimestampMs(String s) throws NumberFormatException {
+        if (!s.matches("(\\d+:)?[0-5]\\d:[0-5]\\d\\.\\d{3}")) {
+            throw new NumberFormatException("has invalid format");
+        }
+
+        String[] parts = s.split("\\.", 2);
+        long value = 0;
+        for (String group: parts[0].split(":")) {
+            value = value * 60 + Long.parseLong(group);
+        }
+        return value * 1000 + Long.parseLong(parts[1]);
+    }
+
+    public static String timeToString(long timeMs) {
+        return String.format("%d:%02d:%02d.%03d",
+                timeMs / 3600000, (timeMs / 60000) % 60,
+                (timeMs / 1000) % 60, timeMs % 1000);
+    }
+
+    public void parse(String s) {
+        boolean trailingCR = false;
+        mBuffer = (mBuffer + s.replace("\0", "\ufffd")).replace("\r\n", "\n");
+
+        /* keep trailing '\r' in case matching '\n' arrives in next packet */
+        if (mBuffer.endsWith("\r")) {
+            trailingCR = true;
+            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+        }
+
+        String[] lines = mBuffer.split("[\r\n]");
+        for (int i = 0; i < lines.length - 1; i++) {
+            mPhase.parse(lines[i]);
+        }
+
+        mBuffer = lines[lines.length - 1];
+        if (trailingCR)
+            mBuffer += "\r";
+    }
+
+    public void eos() {
+        if (mBuffer.endsWith("\r")) {
+            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+        }
+
+        mPhase.parse(mBuffer);
+        mBuffer = "";
+
+        yieldCue();
+        mPhase = mParseStart;
+    }
+
+    public void yieldCue() {
+        if (mCue != null && mCueTexts.size() > 0) {
+            mCue.mStrings = new String[mCueTexts.size()];
+            mCueTexts.toArray(mCue.mStrings);
+            mCueTexts.clear();
+            mListener.onCueParsed(mCue);
+        }
+        mCue = null;
+    }
+
+    interface Phase {
+        void parse(String line);
+    }
+
+    final private Phase mSkipRest = new Phase() {
+        @Override
+        public void parse(String line) { }
+    };
+
+    final private Phase mParseStart = new Phase() { // 5-9
+        @Override
+        public void parse(String line) {
+            if (!line.equals("WEBVTT") &&
+                    !line.startsWith("WEBVTT ") &&
+                    !line.startsWith("WEBVTT\t")) {
+                log_warning("Not a WEBVTT header", line);
+                mPhase = mSkipRest;
+            } else {
+                mPhase = mParseHeader;
+            }
+        }
+    };
+
+    final private Phase mParseHeader = new Phase() { // 10-13
+        TextTrackRegion parseRegion(String s) {
+            TextTrackRegion region = new TextTrackRegion();
+            for (String setting: s.split(" +")) {
+                int equalAt = setting.indexOf('=');
+                if (equalAt <= 0 || equalAt == setting.length() - 1) {
+                    continue;
+                }
+
+                String name = setting.substring(0, equalAt);
+                String value = setting.substring(equalAt + 1);
+                if (name.equals("id")) {
+                    region.mId = value;
+                } else if (name.equals("width")) {
+                    try {
+                        region.mWidth = parseFloatPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid value", e.getMessage(), value);
+                    }
+                } else if (name.equals("lines")) {
+                    try {
+                        int lines = Integer.parseInt(value);
+                        if (lines >= 0) {
+                            region.mLines = lines;
+                        } else {
+                            log_warning("region setting", name, "is negative", value);
+                        }
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name, "is not numeric", value);
+                    }
+                } else if (name.equals("regionanchor") ||
+                           name.equals("viewportanchor")) {
+                    int commaAt = value.indexOf(",");
+                    if (commaAt < 0) {
+                        log_warning("region setting", name, "contains no comma", value);
+                        continue;
+                    }
+
+                    String anchorX = value.substring(0, commaAt);
+                    String anchorY = value.substring(commaAt + 1);
+                    float x, y;
+
+                    try {
+                        x = parseFloatPercentage(anchorX);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid x component", e.getMessage(), anchorX);
+                        continue;
+                    }
+                    try {
+                        y = parseFloatPercentage(anchorY);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid y component", e.getMessage(), anchorY);
+                        continue;
+                    }
+
+                    if (name.charAt(0) == 'r') {
+                        region.mAnchorPointX = x;
+                        region.mAnchorPointY = y;
+                    } else {
+                        region.mViewportAnchorPointX = x;
+                        region.mViewportAnchorPointY = y;
+                    }
+                } else if (name.equals("scroll")) {
+                    if (value.equals("up")) {
+                        region.mScrollValue =
+                            TextTrackRegion.SCROLL_VALUE_SCROLL_UP;
+                    } else {
+                        log_warning("region setting", name, "has invalid value", value);
+                    }
+                }
+            }
+            return region;
+        }
+
+        @Override
+        public void parse(String line)  {
+            if (line.length() == 0) {
+                mPhase = mParseCueId;
+            } else if (line.contains("-->")) {
+                mPhase = mParseCueTime;
+                mPhase.parse(line);
+            } else {
+                int colonAt = line.indexOf(':');
+                if (colonAt <= 0 || colonAt >= line.length() - 1) {
+                    log_warning("meta data header has invalid format", line);
+                }
+                String name = line.substring(0, colonAt);
+                String value = line.substring(colonAt + 1);
+
+                if (name.equals("Region")) {
+                    TextTrackRegion region = parseRegion(value);
+                    mListener.onRegionParsed(region);
+                }
+            }
+        }
+    };
+
+    final private Phase mParseCueId = new Phase() {
+        @Override
+        public void parse(String line) {
+            if (line.length() == 0) {
+                return;
+            }
+
+            assert(mCue == null);
+
+            if (line.equals("NOTE") || line.startsWith("NOTE ")) {
+                mPhase = mParseCueText;
+            }
+
+            mCue = new TextTrackCue();
+            mCueTexts.clear();
+
+            mPhase = mParseCueTime;
+            if (line.contains("-->")) {
+                mPhase.parse(line);
+            } else {
+                mCue.mId = line;
+            }
+        }
+    };
+
+    final private Phase mParseCueTime = new Phase() {
+        @Override
+        public void parse(String line) {
+            int arrowAt = line.indexOf("-->");
+            if (arrowAt < 0) {
+                mCue = null;
+                mPhase = mParseCueId;
+                return;
+            }
+
+            String start = line.substring(0, arrowAt).trim();
+            // convert only initial and first other white-space to space
+            String rest = line.substring(arrowAt + 3)
+                    .replaceFirst("^\\s+", "").replaceFirst("\\s+", " ");
+            int spaceAt = rest.indexOf(' ');
+            String end = spaceAt > 0 ? rest.substring(0, spaceAt) : rest;
+            rest = spaceAt > 0 ? rest.substring(spaceAt + 1) : "";
+
+            mCue.mStartTimeMs = parseTimestampMs(start);
+            mCue.mEndTimeMs = parseTimestampMs(end);
+            for (String setting: rest.split(" +")) {
+                int colonAt = setting.indexOf(':');
+                if (colonAt <= 0 || colonAt == setting.length() - 1) {
+                    continue;
+                }
+                String name = setting.substring(0, colonAt);
+                String value = setting.substring(colonAt + 1);
+
+                if (name.equals("region")) {
+                    mCue.mRegionId = value;
+                } else if (name.equals("vertical")) {
+                    if (value.equals("rl")) {
+                        mCue.mWritingDirection =
+                            TextTrackCue.WRITING_DIRECTION_VERTICAL_RL;
+                    } else if (value.equals("lr")) {
+                        mCue.mWritingDirection =
+                            TextTrackCue.WRITING_DIRECTION_VERTICAL_LR;
+                    } else {
+                        log_warning("cue setting", name, "has invalid value", value);
+                    }
+                } else if (name.equals("line")) {
+                    try {
+                        int linePosition;
+                        /* TRICKY: we know that there are no spaces in value */
+                        assert(value.indexOf(' ') < 0);
+                        if (value.endsWith("%")) {
+                            linePosition = Integer.parseInt(
+                                    value.substring(0, value.length() - 1));
+                            if (linePosition < 0 || linePosition > 100) {
+                                log_warning("cue setting", name, "is out of range", value);
+                                continue;
+                            }
+                            mCue.mSnapToLines = false;
+                            mCue.mLinePosition = linePosition;
+                        } else {
+                            mCue.mSnapToLines = true;
+                            mCue.mLinePosition = Integer.parseInt(value);
+                        }
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("position")) {
+                    try {
+                        mCue.mTextPosition = parseIntPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("size")) {
+                    try {
+                        mCue.mSize = parseIntPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("align")) {
+                    if (value.equals("start")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_START;
+                    } else if (value.equals("middle")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_MIDDLE;
+                    } else if (value.equals("end")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_END;
+                    } else if (value.equals("left")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_LEFT;
+                    } else if (value.equals("right")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_RIGHT;
+                    } else {
+                        log_warning("cue setting", name, "has invalid value", value);
+                        continue;
+                    }
+                }
+            }
+
+            if (mCue.mLinePosition != null ||
+                    mCue.mSize != 100 ||
+                    (mCue.mWritingDirection !=
+                        TextTrackCue.WRITING_DIRECTION_HORIZONTAL)) {
+                mCue.mRegionId = "";
+            }
+
+            mPhase = mParseCueText;
+        }
+    };
+
+    /* also used for notes */
+    final private Phase mParseCueText = new Phase() {
+        @Override
+        public void parse(String line) {
+            if (line.length() == 0) {
+                yieldCue();
+                mPhase = mParseCueId;
+                return;
+            } else if (mCue != null) {
+                mCueTexts.add(line);
+            }
+        }
+    };
+
+    private void log_warning(
+            String nameType, String name, String message,
+            String subMessage, String value) {
+        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+                message + " ('" + value + "' " + subMessage + ")");
+    }
+
+    private void log_warning(
+            String nameType, String name, String message, String value) {
+        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+                message + " ('" + value + "')");
+    }
+
+    private void log_warning(String message, String value) {
+        Log.w(this.getClass().getName(), message + " ('" + value + "')");
+    }
+}
+
+/** @hide */
+interface WebVttCueListener {
+    void onCueParsed(TextTrackCue cue);
+    void onRegionParsed(TextTrackRegion region);
+}
+
+/** @hide */
+class WebVttTrack extends SubtitleTrack implements WebVttCueListener {
+    private static final String TAG = "WebVttTrack";
+
+    private final TextView mTextView;
+
+    private final WebVttParser mParser = new WebVttParser(this);
+    private final UnstyledTextExtractor mExtractor =
+        new UnstyledTextExtractor();
+    private final Tokenizer mTokenizer = new Tokenizer(mExtractor);
+    private final Vector<Long> mTimestamps = new Vector<Long>();
+
+    private final Map<String, TextTrackRegion> mRegions =
+        new HashMap<String, TextTrackRegion>();
+    private Long mCurrentRunID;
+
+    WebVttTrack(MediaFormat format, TextView textView) {
+        super(format);
+        mTextView = textView;
+    }
+
+    @Override
+    public View getView() {
+        return mTextView;
+    }
+
+    @Override
+    public void onData(String data, boolean eos, long runID) {
+        // implement intermixing restriction for WebVTT only for now
+        synchronized(mParser) {
+            if (mCurrentRunID != null && runID != mCurrentRunID) {
+                throw new IllegalStateException(
+                        "Run #" + mCurrentRunID +
+                        " in progress.  Cannot process run #" + runID);
+            }
+            mCurrentRunID = runID;
+            mParser.parse(data);
+            if (eos) {
+                finishedRun(runID);
+                mParser.eos();
+                mRegions.clear();
+                mCurrentRunID = null;
+            }
+        }
+    }
+
+    @Override
+    public void onCueParsed(TextTrackCue cue) {
+        synchronized (mParser) {
+            // resolve region
+            if (cue.mRegionId.length() != 0) {
+                cue.mRegion = mRegions.get(cue.mRegionId);
+            }
+
+            if (DEBUG) Log.v(TAG, "adding cue " + cue);
+
+            // tokenize text track string-lines into lines of spans
+            mTokenizer.reset();
+            for (String s: cue.mStrings) {
+                mTokenizer.tokenize(s);
+            }
+            cue.mLines = mExtractor.getText();
+            if (DEBUG) Log.v(TAG, cue.appendLinesToBuilder(
+                    cue.appendStringsToBuilder(
+                        new StringBuilder()).append(" simplified to: "))
+                            .toString());
+
+            // extract inner timestamps
+            for (TextTrackCueSpan[] line: cue.mLines) {
+                for (TextTrackCueSpan span: line) {
+                    if (span.mTimestampMs > cue.mStartTimeMs &&
+                            span.mTimestampMs < cue.mEndTimeMs &&
+                            !mTimestamps.contains(span.mTimestampMs)) {
+                        mTimestamps.add(span.mTimestampMs);
+                    }
+                }
+            }
+
+            if (mTimestamps.size() > 0) {
+                cue.mInnerTimesMs = new long[mTimestamps.size()];
+                for (int ix=0; ix < mTimestamps.size(); ++ix) {
+                    cue.mInnerTimesMs[ix] = mTimestamps.get(ix);
+                }
+                mTimestamps.clear();
+            } else {
+                cue.mInnerTimesMs = null;
+            }
+
+            cue.mRunID = mCurrentRunID;
+        }
+
+        addCue(cue);
+    }
+
+    @Override
+    public void onRegionParsed(TextTrackRegion region) {
+        synchronized(mParser) {
+            mRegions.put(region.mId, region);
+        }
+    }
+
+    public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
+        if (!mVisible) {
+            // don't keep the state if we are not visible
+            return;
+        }
+
+        if (DEBUG && mTimeProvider != null) {
+            try {
+                Log.d(TAG, "at " +
+                        (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
+                        " ms the active cues are:");
+            } catch (IllegalStateException e) {
+                Log.d(TAG, "at (illegal state) the active cues are:");
+            }
+        }
+        StringBuilder text = new StringBuilder();
+        StringBuilder lineBuilder = new StringBuilder();
+        for (Cue o: activeCues) {
+            TextTrackCue cue = (TextTrackCue)o;
+            if (DEBUG) Log.d(TAG, cue.toString());
+            for (TextTrackCueSpan[] line: cue.mLines) {
+                for (TextTrackCueSpan span: line) {
+                    if (!span.mEnabled) {
+                        continue;
+                    }
+                    lineBuilder.append(span.mText);
+                }
+                if (lineBuilder.length() > 0) {
+                    text.append(lineBuilder.toString()).append("\n");
+                    lineBuilder.delete(0, lineBuilder.length());
+                }
+            }
+        }
+
+        if (mTextView != null) {
+            if (DEBUG) Log.d(TAG, "updating to " + text.toString());
+            mTextView.setText(text.toString());
+            mTextView.postInvalidate();
+        }
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
index 926719c..9621f92 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -50,12 +50,20 @@
         assertEquals(1, r.getNumerator());
         assertEquals(2, r.getDenominator());
 
-        // Dividing by zero is not allowed
-        try {
-            r = new Rational(1, 0);
-            fail("Expected Rational constructor to throw an IllegalArgumentException");
-        } catch(IllegalArgumentException e) {
-        }
+        // Infinity.
+        r = new Rational(1, 0);
+        assertEquals(0, r.getNumerator());
+        assertEquals(0, r.getDenominator());
+
+        // Negative infinity.
+        r = new Rational(-1, 0);
+        assertEquals(0, r.getNumerator());
+        assertEquals(0, r.getDenominator());
+
+        // NaN.
+        r = new Rational(0, 0);
+        assertEquals(0, r.getNumerator());
+        assertEquals(0, r.getDenominator());
     }
 
     @SmallTest
@@ -110,5 +118,34 @@
         assertEquals(moreComplicated, moreComplicated2);
         assertEquals(moreComplicated2, moreComplicated);
 
+        Rational nan = new Rational(0, 0);
+        Rational nan2 = new Rational(0, 0);
+        assertTrue(nan.equals(nan));
+        assertTrue(nan.equals(nan2));
+        assertTrue(nan2.equals(nan));
+        assertFalse(nan.equals(r));
+        assertFalse(r.equals(nan));
+
+        // Infinities of the same sign are equal.
+        Rational posInf = new Rational(1, 0);
+        Rational posInf2 = new Rational(2, 0);
+        Rational negInf = new Rational(-1, 0);
+        Rational negInf2 = new Rational(-2, 0);
+        assertEquals(posInf, posInf);
+        assertEquals(negInf, negInf);
+        assertEquals(posInf, posInf2);
+        assertEquals(negInf, negInf2);
+
+        // Infinities aren't equal to anything else.
+        assertFalse(posInf.equals(negInf));
+        assertFalse(negInf.equals(posInf));
+        assertFalse(negInf.equals(r));
+        assertFalse(posInf.equals(r));
+        assertFalse(r.equals(negInf));
+        assertFalse(r.equals(posInf));
+        assertFalse(posInf.equals(nan));
+        assertFalse(negInf.equals(nan));
+        assertFalse(nan.equals(posInf));
+        assertFalse(nan.equals(negInf));
     }
-}
\ No newline at end of file
+}
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_accept.png
new file mode 100644
index 0000000..234ca8a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_cab_remove_field_holo_light.png b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_remove_field_holo_light.png
new file mode 100644
index 0000000..c9fa5c6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_remove_field_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..e9bd010
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_dir.png b/packages/DocumentsUI/res/drawable-hdpi/ic_dir.png
index d02534f..aabeda6 100644
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_dir.png
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_dir.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_apk.png
new file mode 100644
index 0000000..5bda872
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_audio.png
new file mode 100644
index 0000000..38e315a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..c6e9582
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_codes.png
new file mode 100644
index 0000000..c5a748b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..a59bd23
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_contact.png
new file mode 100644
index 0000000..87799c6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_event.png
new file mode 100644
index 0000000..a3bbc0f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_font.png
new file mode 100644
index 0000000..56133d4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_image.png
new file mode 100644
index 0000000..e655d04
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..9ce032f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..53bfc52
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..5a49de8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_text.png
new file mode 100644
index 0000000..af79de9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_video.png
new file mode 100644
index 0000000..a0676d7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_create_dir.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_create_dir.png
deleted file mode 100644
index 6eb31f1..0000000
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_create_dir.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..4736da1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_edit_holo.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_edit_holo.png
new file mode 100644
index 0000000..50ac935
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_edit_holo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_grid.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_grid.png
deleted file mode 100644
index d1326e5..0000000
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_grid.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_list.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_list.png
deleted file mode 100644
index e03e345..0000000
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_list.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..00faf9d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_revert_holo_light.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_revert_holo_light.png
new file mode 100644
index 0000000..e9c0b01
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_revert_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_search.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_search_holo_light.png
similarity index 100%
rename from packages/DocumentsUI/res/drawable-hdpi/ic_menu_search.png
rename to packages/DocumentsUI/res/drawable-hdpi/ic_menu_search_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_share_holo_light_icononly.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_share_holo_light_icononly.png
new file mode 100644
index 0000000..527e43c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_share_holo_light_icononly.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sort.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sort.png
deleted file mode 100644
index 680d482..0000000
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sort.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sortby_holo_light.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sortby_holo_light.png
new file mode 100644
index 0000000..9421792
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sortby_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_trash_holo_light.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_trash_holo_light.png
new file mode 100644
index 0000000..f662f94
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_trash_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..2c59d60
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..0dbb075
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_perm_group_system_tools.png b/packages/DocumentsUI/res/drawable-hdpi/ic_perm_group_system_tools.png
new file mode 100644
index 0000000..3905d0e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_perm_group_system_tools.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_download.png
new file mode 100644
index 0000000..e927efa
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_recent.png
new file mode 100644
index 0000000..d23e617
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_usb.png
new file mode 100644
index 0000000..d8c51d7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/stat_notify_sdcard_light.png b/packages/DocumentsUI/res/drawable-hdpi/stat_notify_sdcard_light.png
new file mode 100644
index 0000000..9c9a7de
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/stat_notify_sdcard_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_accept.png
new file mode 100644
index 0000000..ad761e1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_cab_remove_field_holo_light.png b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_remove_field_holo_light.png
new file mode 100644
index 0000000..7c29b71
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_remove_field_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..dff246a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_apk.png
new file mode 100644
index 0000000..26212e9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_audio.png
new file mode 100644
index 0000000..db9fa8b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..87877fe
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_codes.png
new file mode 100644
index 0000000..d552234
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..75c304a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_contact.png
new file mode 100644
index 0000000..849d8e7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_event.png
new file mode 100644
index 0000000..4304489
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_font.png
new file mode 100644
index 0000000..e1ad89f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_image.png
new file mode 100644
index 0000000..914ed4b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..dfdeb26
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..0bcbca4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..9e00ea1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_text.png
new file mode 100644
index 0000000..e2caba7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_video.png
new file mode 100644
index 0000000..6393df6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..64e8592
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_edit_holo.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_edit_holo.png
new file mode 100644
index 0000000..8a2af67
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_edit_holo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..2b7e5ca
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_revert_holo_light.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_revert_holo_light.png
new file mode 100644
index 0000000..5d7e1a5
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_revert_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_search_holo_light.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_search_holo_light.png
new file mode 100644
index 0000000..0350a43
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_search_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_share_holo_light_icononly.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_share_holo_light_icononly.png
new file mode 100644
index 0000000..a15ef6a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_share_holo_light_icononly.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_sortby_holo_light.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_sortby_holo_light.png
new file mode 100644
index 0000000..9d724f4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_sortby_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_trash_holo_light.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_trash_holo_light.png
new file mode 100644
index 0000000..3cc00bb
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_trash_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..b6d1a9a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..714d5e8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_perm_group_system_tools.png b/packages/DocumentsUI/res/drawable-mdpi/ic_perm_group_system_tools.png
new file mode 100644
index 0000000..5d9d978
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_perm_group_system_tools.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_download.png
new file mode 100644
index 0000000..110d78d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_recent.png
new file mode 100644
index 0000000..47c4f29
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_usb.png
new file mode 100644
index 0000000..be47b98
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/stat_notify_sdcard_light.png b/packages/DocumentsUI/res/drawable-mdpi/stat_notify_sdcard_light.png
new file mode 100644
index 0000000..39dd0fa
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/stat_notify_sdcard_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_accept.png
new file mode 100644
index 0000000..47398d3
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_remove_field_holo_light.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_remove_field_holo_light.png
new file mode 100644
index 0000000..2959e5e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_remove_field_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..2b4891c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_apk.png
new file mode 100644
index 0000000..5abdd4c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_audio.png
new file mode 100644
index 0000000..7975acd
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..59a7305
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_codes.png
new file mode 100644
index 0000000..468431e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..4db47a6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_contact.png
new file mode 100644
index 0000000..ded1a00
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_event.png
new file mode 100644
index 0000000..4609463
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_font.png
new file mode 100644
index 0000000..dda7f06
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_image.png
new file mode 100644
index 0000000..44b40f7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..a59b102
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..062fe03
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..82bda58
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_text.png
new file mode 100644
index 0000000..6f15709
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_video.png
new file mode 100644
index 0000000..cdd8052
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..a96a0f8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_edit_holo.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_edit_holo.png
new file mode 100644
index 0000000..4652da6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_edit_holo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..449ae53
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_revert_holo_light.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_revert_holo_light.png
new file mode 100644
index 0000000..ca67f62
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_revert_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_search_holo_light.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_search_holo_light.png
new file mode 100644
index 0000000..6811782
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_search_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share_holo_light_icononly.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share_holo_light_icononly.png
new file mode 100644
index 0000000..939ea21
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share_holo_light_icononly.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_sortby_holo_light.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_sortby_holo_light.png
new file mode 100644
index 0000000..5241a30
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_sortby_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_trash_holo_light.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_trash_holo_light.png
new file mode 100644
index 0000000..c985a27
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_trash_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..b219d06
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..897740e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_perm_group_system_tools.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_perm_group_system_tools.png
new file mode 100644
index 0000000..5dc35da
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_perm_group_system_tools.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
new file mode 100644
index 0000000..2c30b7f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
new file mode 100644
index 0000000..a87ccb8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
new file mode 100644
index 0000000..116da46
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/stat_notify_sdcard_light.png b/packages/DocumentsUI/res/drawable-xhdpi/stat_notify_sdcard_light.png
new file mode 100644
index 0000000..671a204
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/stat_notify_sdcard_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_accept.png
new file mode 100644
index 0000000..ca5b1ac
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_remove_field_holo_light.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_remove_field_holo_light.png
new file mode 100644
index 0000000..953438d5
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_remove_field_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..8679156
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_apk.png
similarity index 70%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_apk.png
index 1480682..45bce08 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_audio.png
new file mode 100644
index 0000000..e232697
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..efcaa87
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_codes.png
similarity index 71%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_codes.png
index 1480682..edaf35e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..73f6a1b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_contact.png
similarity index 66%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_contact.png
index 1480682..7f93d76 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_event.png
new file mode 100644
index 0000000..55cb3ec
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_font.png
new file mode 100644
index 0000000..62b612a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_image.png
similarity index 78%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_image.png
index 1480682..1a5c481 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
similarity index 76%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
index 1480682..29d0b33 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..cec53f2
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..220bddb
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_text.png
similarity index 84%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_text.png
index 1480682..76a1bb5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_video.png
new file mode 100644
index 0000000..20e23c9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..aeace05
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_edit_holo.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_edit_holo.png
new file mode 100644
index 0000000..71bcdbf
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_edit_holo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..0737442
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_revert_holo_light.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_revert_holo_light.png
new file mode 100644
index 0000000..ced6032
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_revert_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_search_holo_light.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_search_holo_light.png
new file mode 100644
index 0000000..c69d526
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_search_holo_light.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share_holo_light_icononly.png
similarity index 67%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share_holo_light_icononly.png
index 1480682..a3f9a5c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share_holo_light_icononly.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_sortby_holo_light.png
similarity index 85%
rename from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
rename to packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_sortby_holo_light.png
index 1480682..9810a1e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_sortby_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_trash_holo_light.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_trash_holo_light.png
new file mode 100644
index 0000000..1811be8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_trash_holo_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..2c58b5e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..cf320cd
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_perm_group_system_tools.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_perm_group_system_tools.png
new file mode 100644
index 0000000..cee2b05
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_perm_group_system_tools.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
new file mode 100644
index 0000000..f9fe2be
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
new file mode 100644
index 0000000..d95ebb5
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
new file mode 100644
index 0000000..6fbc3c8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/DocumentsUI/res/drawable-xxhdpi/stat_notify_sdcard_light.png
similarity index 85%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/DocumentsUI/res/drawable-xxhdpi/stat_notify_sdcard_light.png
index 1480682..8b8b227 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/stat_notify_sdcard_light.png
Binary files differ
diff --git a/packages/DocumentsUI/res/layout/item_loading.xml b/packages/DocumentsUI/res/layout/item_loading.xml
new file mode 100644
index 0000000..7da71e3
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_loading.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <ProgressBar
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:indeterminate="true"
+        style="?android:attr/progressBarStyle" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_message_grid.xml b/packages/DocumentsUI/res/layout/item_message_grid.xml
new file mode 100644
index 0000000..941340e
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_message_grid.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="180dip"
+    android:paddingBottom="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/chip"
+        android:foreground="@drawable/item_background"
+        android:duplicateParentState="true">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingBottom="6dp"
+            android:orientation="vertical"
+            android:gravity="center">
+
+            <ImageView
+                android:id="@android:id/icon"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:contentDescription="@null" />
+
+            <TextView
+                android:id="@android:id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:paddingTop="6dp"
+                android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+                android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textAlignment="viewStart" />
+
+        </LinearLayout>
+
+    </FrameLayout>
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_message_list.xml b/packages/DocumentsUI/res/layout/item_message_list.xml
new file mode 100644
index 0000000..dda3c80
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_message_list.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/item_background"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@android:dimen/app_icon_size"
+        android:layout_height="@android:dimen/app_icon_size"
+        android:layout_marginEnd="8dip"
+        android:layout_gravity="center_vertical"
+        android:scaleType="centerInside"
+        android:contentDescription="@null" />
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textAlignment="viewStart" />
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_title.xml b/packages/DocumentsUI/res/layout/item_title.xml
index fe6c14d..eab3839 100644
--- a/packages/DocumentsUI/res/layout/item_title.xml
+++ b/packages/DocumentsUI/res/layout/item_title.xml
@@ -29,13 +29,4 @@
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textAlignment="viewStart" />
 
-    <TextView
-        android:id="@android:id/summary"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textAlignment="viewStart" />
-
 </LinearLayout>
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
index 575336c..4d3dc56 100644
--- a/packages/DocumentsUI/res/menu/activity.xml
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -18,27 +18,45 @@
     <item
         android:id="@+id/menu_create_dir"
         android:title="@string/menu_create_dir"
-        android:icon="@drawable/ic_menu_create_dir"
+        android:icon="@drawable/ic_menu_new_folder"
         android:showAsAction="ifRoom" />
     <item
         android:id="@+id/menu_search"
         android:title="@string/menu_search"
-        android:icon="@drawable/ic_menu_search"
+        android:icon="@drawable/ic_menu_search_holo_light"
         android:showAsAction="always|collapseActionView"
         android:actionViewClass="android.widget.SearchView"
         android:imeOptions="actionSearch" />
     <item
+        android:id="@+id/menu_sort"
+        android:title="@string/menu_sort"
+        android:icon="@drawable/ic_menu_sortby_holo_light"
+        android:showAsAction="always">
+        <menu>
+            <item
+                android:id="@+id/menu_sort_name"
+                android:title="@string/sort_name" />
+            <item
+                android:id="@+id/menu_sort_date"
+                android:title="@string/sort_date" />
+            <item
+                android:id="@+id/menu_sort_size"
+                android:title="@string/sort_size" />
+        </menu>
+    </item>
+    <item
         android:id="@+id/menu_grid"
         android:title="@string/menu_grid"
-        android:icon="@drawable/ic_menu_grid"
+        android:icon="@drawable/ic_menu_view_grid"
         android:showAsAction="ifRoom" />
     <item
         android:id="@+id/menu_list"
         android:title="@string/menu_list"
-        android:icon="@drawable/ic_menu_list"
+        android:icon="@drawable/ic_menu_view_list"
         android:showAsAction="ifRoom" />
     <item
         android:id="@+id/menu_settings"
         android:title="@string/menu_settings"
+        android:icon="@drawable/ic_perm_group_system_tools"
         android:showAsAction="never" />
 </menu>
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index d8166cc..ece6673 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Kan sommige dokumente nie uitvee nie"</string>
     <string name="more" msgid="7117420986529297171">"Nog"</string>
     <string name="loading" msgid="7933681260296021180">"Laai tans..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index 1550ddb..8761a27 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
     <string name="more" msgid="7117420986529297171">"ተጨማሪ"</string>
     <string name="loading" msgid="7933681260296021180">"በመጫን ላይ…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 19599b6..febc6dc 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"تعذر حذف بعض المستندات"</string>
     <string name="more" msgid="7117420986529297171">"المزيد"</string>
     <string name="loading" msgid="7933681260296021180">"جارٍ التحميل…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 806118b..a301b66 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Bəzi sənədləri silə bilmir"</string>
     <string name="more" msgid="7117420986529297171">"Daha çox"</string>
     <string name="loading" msgid="7933681260296021180">"Yüklənir…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-be/strings.xml b/packages/DocumentsUI/res/values-be/strings.xml
index da91d95..689a935 100644
--- a/packages/DocumentsUI/res/values-be/strings.xml
+++ b/packages/DocumentsUI/res/values-be/strings.xml
@@ -83,4 +83,6 @@
     <!-- no translation found for more (7117420986529297171) -->
     <skip />
     <string name="loading" msgid="7933681260296021180">"Загрузка..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index d04ec6c..bf399d2 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Някои документи не могат да бъдат изтрити"</string>
     <string name="more" msgid="7117420986529297171">"Още"</string>
     <string name="loading" msgid="7933681260296021180">"Зарежда се..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index f5009d1..22c12fc 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es poden suprimir alguns documents."</string>
     <string name="more" msgid="7117420986529297171">"Més"</string>
     <string name="loading" msgid="7933681260296021180">"S\'està carregant…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index 6a04e42..42a5a2b 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Některé dokumenty nelze smazat"</string>
     <string name="more" msgid="7117420986529297171">"Více"</string>
     <string name="loading" msgid="7933681260296021180">"Načítání..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index dced265..41b1aac 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nogle dokumenter kan ikke slettes"</string>
     <string name="more" msgid="7117420986529297171">"Mere"</string>
     <string name="loading" msgid="7933681260296021180">"Indlæser…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 2c7bff1..bd54545 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Einige Dokumente konnten nicht gelöscht werden."</string>
     <string name="more" msgid="7117420986529297171">"Mehr"</string>
     <string name="loading" msgid="7933681260296021180">"Wird geladen…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index e278fde..c15eb1f 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
     <string name="more" msgid="7117420986529297171">"Περισσότερα"</string>
     <string name="loading" msgid="7933681260296021180">"Φόρτωση…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index 913e6d7..b1693b0 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="more" msgid="7117420986529297171">"More"</string>
     <string name="loading" msgid="7933681260296021180">"Loading…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index 913e6d7..b1693b0 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="more" msgid="7117420986529297171">"More"</string>
     <string name="loading" msgid="7933681260296021180">"Loading…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 68c5ac1..d556667 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos."</string>
     <string name="more" msgid="7117420986529297171">"Más"</string>
     <string name="loading" msgid="7933681260296021180">"Cargando…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index b9695f1..723a0ec 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos"</string>
     <string name="more" msgid="7117420986529297171">"Más"</string>
     <string name="loading" msgid="7933681260296021180">"Cargando..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index 2f7e14a..7c298de 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Mõnda dokumenti ei õnnestu kustutada"</string>
     <string name="more" msgid="7117420986529297171">"Rohkem"</string>
     <string name="loading" msgid="7933681260296021180">"Laadimine ..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 852bea7..418a08f 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"برخی از اسناد حذف نمی‌شوند"</string>
     <string name="more" msgid="7117420986529297171">"بیشتر"</string>
     <string name="loading" msgid="7933681260296021180">"در حال بارگیری..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index c97159b..0d9d883 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
     <string name="more" msgid="7117420986529297171">"Lisää"</string>
     <string name="loading" msgid="7933681260296021180">"Ladataan…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index a9912c9..086b82c 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents"</string>
     <string name="more" msgid="7117420986529297171">"Plus"</string>
     <string name="loading" msgid="7933681260296021180">"Chargement en cours..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 6049df7..d70877a 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents."</string>
     <string name="more" msgid="7117420986529297171">"Plus"</string>
     <string name="loading" msgid="7933681260296021180">"Chargement…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index 2931df0..d45e9bb 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"कुछ दस्तावेज़ों को हटाने में अक्षम"</string>
     <string name="more" msgid="7117420986529297171">"अधिक"</string>
     <string name="loading" msgid="7933681260296021180">"लोड हो रहे हैं..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index f6775e0..01be538 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
     <string name="more" msgid="7117420986529297171">"Više"</string>
     <string name="loading" msgid="7933681260296021180">"Učitavanje…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 660f654..2648f82 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Néhány dokumentumot nem lehet törölni"</string>
     <string name="more" msgid="7117420986529297171">"Továbbiak"</string>
     <string name="loading" msgid="7933681260296021180">"Betöltés..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 357875d..ed026c2 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
     <string name="more" msgid="7117420986529297171">"Ավելին"</string>
     <string name="loading" msgid="7933681260296021180">"Բեռնում..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index 9bf1179..a1cefc2 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat menghapus beberapa dokumen"</string>
     <string name="more" msgid="7117420986529297171">"Lainnya"</string>
     <string name="loading" msgid="7933681260296021180">"Memuat..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index 5a185d9..6b1bb8b 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossibile eliminare alcuni documenti"</string>
     <string name="more" msgid="7117420986529297171">"Altro"</string>
     <string name="loading" msgid="7933681260296021180">"Caricamento..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 202eb10..98bfa87 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
     <string name="more" msgid="7117420986529297171">"עוד"</string>
     <string name="loading" msgid="7933681260296021180">"טוען..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 4a1bdc9..9a83c1f 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
     <string name="more" msgid="7117420986529297171">"その他"</string>
     <string name="loading" msgid="7933681260296021180">"読み込んでいます..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index 32ba350..2b9338d 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
     <string name="more" msgid="7117420986529297171">"მეტი"</string>
     <string name="loading" msgid="7933681260296021180">"ჩატვირთვა…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 253e9b2..7455ef4 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"មិន​អាច​លុប​ឯកសារ​មួយ​ចំនួន"</string>
     <string name="more" msgid="7117420986529297171">"ច្រើន​ទៀត"</string>
     <string name="loading" msgid="7933681260296021180">"កំពុង​ផ្ទុក..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index e23aed4..b96ae3b 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"일부 문서를 삭제할 수 없음"</string>
     <string name="more" msgid="7117420986529297171">"더보기"</string>
     <string name="loading" msgid="7933681260296021180">"로드 중.."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 8a1aea9..6f889ea 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
     <string name="more" msgid="7117420986529297171">"ເພີ່ມເຕີມ"</string>
     <string name="loading" msgid="7933681260296021180">"ກຳລັງໂຫລດ..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index 9af9617..6bbc2ce 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nepavyko ištrinti kai kurių dokumentų"</string>
     <string name="more" msgid="7117420986529297171">"Daugiau"</string>
     <string name="loading" msgid="7933681260296021180">"Įkeliama..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index 4d94b30..425c9a6 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nevar dzēst dažus dokumentus."</string>
     <string name="more" msgid="7117420986529297171">"Vēl"</string>
     <string name="loading" msgid="7933681260296021180">"Notiek ielāde..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index 66637b8..49b12c9 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
     <string name="more" msgid="7117420986529297171">"Цааш"</string>
     <string name="loading" msgid="7933681260296021180">"Ачааллаж байна..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index b23e37d..f013e7a 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat memadam beberapa dokumen"</string>
     <string name="more" msgid="7117420986529297171">"Lagi"</string>
     <string name="loading" msgid="7933681260296021180">"Memuatkan…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index b4d034d..fc5d0ce4f 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Enkelte dokumenter kunne ikke slettes"</string>
     <string name="more" msgid="7117420986529297171">"Mer"</string>
     <string name="loading" msgid="7933681260296021180">"Laster inn …"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index 39e7cd1..c7aac6b 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
     <string name="more" msgid="7117420986529297171">"थप"</string>
     <string name="loading" msgid="7933681260296021180">"लोड हुँदै..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index 03ecae4..60a61bf 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Kan bepaalde documenten niet verwijderen"</string>
     <string name="more" msgid="7117420986529297171">"Meer"</string>
     <string name="loading" msgid="7933681260296021180">"Laden..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 125d81f..923e7ac 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
     <string name="more" msgid="7117420986529297171">"Więcej"</string>
     <string name="loading" msgid="7933681260296021180">"Wczytywanie…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index d901eca..93b3ca9 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não é possível eliminar alguns documentos"</string>
     <string name="more" msgid="7117420986529297171">"Mais"</string>
     <string name="loading" msgid="7933681260296021180">"A carregar…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 1e72dca1..79dc36e 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
     <string name="more" msgid="7117420986529297171">"Mais"</string>
     <string name="loading" msgid="7933681260296021180">"Carregando…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 156283a..01fc980 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unele documente nu au putut fi șterse"</string>
     <string name="more" msgid="7117420986529297171">"Mai multe"</string>
     <string name="loading" msgid="7933681260296021180">"Se încarcă…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index f23c008..587a057 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
     <string name="more" msgid="7117420986529297171">"Ещё"</string>
     <string name="loading" msgid="7933681260296021180">"Загрузка…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index b7a1b49..fefa4dd 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"සමහර ලේඛන මැකීමට නොහැකි විය"</string>
     <string name="more" msgid="7117420986529297171">"තව"</string>
     <string name="loading" msgid="7933681260296021180">"පූරණය වෙමින්..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 3b8dabc..2b073db 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
     <string name="more" msgid="7117420986529297171">"Viac"</string>
     <string name="loading" msgid="7933681260296021180">"Prebieha načítavanie..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index c668951..b5ee908 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nekaterih dokumentov ni mogoče izbrisati"</string>
     <string name="more" msgid="7117420986529297171">"Več"</string>
     <string name="loading" msgid="7933681260296021180">"Nalaganje …"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index b5042e7..3310f3e 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
     <string name="more" msgid="7117420986529297171">"Још"</string>
     <string name="loading" msgid="7933681260296021180">"Учитавање…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 8737033..55f3f54 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Det gick inte att ta bort vissa dokument"</string>
     <string name="more" msgid="7117420986529297171">"Mer"</string>
     <string name="loading" msgid="7933681260296021180">"Läser in …"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index affed56..b6e128f 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Imeshindwa kufuta baadhi ya hati"</string>
     <string name="more" msgid="7117420986529297171">"Zaidi"</string>
     <string name="loading" msgid="7933681260296021180">"Inapakia…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index 7e786ba..08dc27b 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
     <string name="more" msgid="7117420986529297171">"เพิ่มเติม"</string>
     <string name="loading" msgid="7933681260296021180">"กำลังโหลด..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index ae1608b..57e6380 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Hindi matanggal ang ilang dokumento"</string>
     <string name="more" msgid="7117420986529297171">"Higit pa"</string>
     <string name="loading" msgid="7933681260296021180">"Naglo-load…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index bdd85cf..0c87107 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Bazı dokümanlar silinemiyor"</string>
     <string name="more" msgid="7117420986529297171">"Diğer"</string>
     <string name="loading" msgid="7933681260296021180">"Yükleniyor..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index f1a443d..bdaab59 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не вдалося видалити деякі документи"</string>
     <string name="more" msgid="7117420986529297171">"Більше"</string>
     <string name="loading" msgid="7933681260296021180">"Завантаження..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index d01c493..8257d9b 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Không thể xóa một số tài liệu"</string>
     <string name="more" msgid="7117420986529297171">"Thêm"</string>
     <string name="loading" msgid="7933681260296021180">"Đang tải…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index f172d29..882aee2 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
     <string name="more" msgid="7117420986529297171">"更多"</string>
     <string name="loading" msgid="7933681260296021180">"正在加载..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 7d2af3a..773b8b3 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
     <string name="more" msgid="7117420986529297171">"更多"</string>
     <string name="loading" msgid="7933681260296021180">"正在載入..."</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index 2246bd7..0852a1b 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
     <string name="more" msgid="7117420986529297171">"更多"</string>
     <string name="loading" msgid="7933681260296021180">"載入中…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index 6a630d7..d4ad405 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -50,4 +50,6 @@
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
     <string name="more" msgid="7117420986529297171">"Okuningi"</string>
     <string name="loading" msgid="7933681260296021180">"Iyalayisha…"</string>
+    <!-- no translation found for share_via (8966594246261344259) -->
+    <skip />
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 5b23ca5..ba47037 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -397,13 +397,8 @@
                 continue;
             }
 
-            try {
-                if (resolver.delete(doc.uri, null, null) != 1) {
-                    Log.w(TAG, "Failed to delete " + doc);
-                    hadTrouble = true;
-                }
-            } catch (Exception e) {
-                Log.w(TAG, "Failed to delete " + doc + ": " + e);
+            if (!DocumentsContract.deleteDocument(resolver, doc.uri)) {
+                Log.w(TAG, "Failed to delete " + doc);
                 hadTrouble = true;
             }
         }
@@ -417,11 +412,83 @@
         return ((DocumentsActivity) fragment.getActivity()).getDisplayState();
     }
 
+    private interface Footer {
+        public View getView(View convertView, ViewGroup parent);
+    }
+
+    private static class LoadingFooter implements Footer {
+        @Override
+        public View getView(View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                convertView = inflater.inflate(R.layout.item_loading, parent, false);
+            }
+            return convertView;
+        }
+    }
+
+    private class MessageFooter implements Footer {
+        private final int mIcon;
+        private final String mMessage;
+
+        public MessageFooter(int icon, String message) {
+            mIcon = icon;
+            mMessage = message;
+        }
+
+        @Override
+        public View getView(View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final State state = getDisplayState(DirectoryFragment.this);
+
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                if (state.mode == MODE_LIST) {
+                    convertView = inflater.inflate(R.layout.item_message_list, parent, false);
+                } else if (state.mode == MODE_GRID) {
+                    convertView = inflater.inflate(R.layout.item_message_grid, parent, false);
+                } else {
+                    throw new IllegalStateException();
+                }
+            }
+
+            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            icon.setImageResource(mIcon);
+            title.setText(mMessage);
+            return convertView;
+        }
+    }
+
     private class DocumentsAdapter extends BaseAdapter {
         private Cursor mCursor;
+        private int mCursorCount;
+
+        private List<Footer> mFooters = Lists.newArrayList();
 
         public void swapCursor(Cursor cursor) {
             mCursor = cursor;
+            mCursorCount = cursor != null ? cursor.getCount() : 0;
+
+            mFooters.clear();
+
+            final Bundle extras = cursor != null ? cursor.getExtras() : null;
+            if (extras != null) {
+                final String info = extras.getString(DocumentsContract.EXTRA_INFO);
+                if (info != null) {
+                    mFooters.add(new MessageFooter(
+                            com.android.internal.R.drawable.ic_menu_info_details, info));
+                }
+                final String error = extras.getString(DocumentsContract.EXTRA_ERROR);
+                if (error != null) {
+                    mFooters.add(new MessageFooter(
+                            com.android.internal.R.drawable.ic_dialog_alert, error));
+                }
+                if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) {
+                    mFooters.add(new LoadingFooter());
+                }
+            }
 
             if (isEmpty()) {
                 mEmptyView.setVisibility(View.VISIBLE);
@@ -434,6 +501,15 @@
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
+            if (position < mCursorCount) {
+                return getDocumentView(position, convertView, parent);
+            } else {
+                position -= mCursorCount;
+                return mFooters.get(position).getView(convertView, parent);
+            }
+        }
+
+        private View getDocumentView(int position, View convertView, ViewGroup parent) {
             final Context context = parent.getContext();
             final State state = getDisplayState(DirectoryFragment.this);
 
@@ -490,9 +566,9 @@
                     task.execute(uri);
                 }
             } else if (docIcon != 0) {
-                icon.setImageDrawable(DocumentInfo.loadIcon(context, docAuthority, docIcon));
+                icon.setImageDrawable(IconUtils.loadPackageIcon(context, docAuthority, docIcon));
             } else {
-                icon.setImageDrawable(RootsCache.resolveDocumentIcon(context, docMimeType));
+                icon.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType));
             }
 
             title.setText(docDisplayName);
@@ -540,21 +616,42 @@
 
         @Override
         public int getCount() {
-            return mCursor != null ? mCursor.getCount() : 0;
+            return mCursorCount + mFooters.size();
         }
 
         @Override
         public Cursor getItem(int position) {
-            if (mCursor != null) {
+            if (position < mCursorCount) {
                 mCursor.moveToPosition(position);
+                return mCursor;
+            } else {
+                return null;
             }
-            return mCursor;
         }
 
         @Override
         public long getItemId(int position) {
             return position;
         }
+
+        @Override
+        public int getItemViewType(int position) {
+            if (position < mCursorCount) {
+                return 0;
+            } else {
+                return IGNORE_ITEM_VIEW_TYPE;
+            }
+        }
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return false;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return position < mCursorCount;
+        }
     }
 
     private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index 3f016b5..6ea57d7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -77,11 +77,12 @@
                     .getContentResolver().acquireUnstableContentProviderClient(authority);
             final Cursor cursor = result.client.query(
                     mUri, null, null, null, getQuerySortOrder(mSortOrder), mSignal);
+            cursor.registerContentObserver(mObserver);
+
             final Cursor withRoot = new RootCursorWrapper(mUri.getAuthority(), mRootId, cursor, -1);
             final Cursor sorted = new SortingCursorWrapper(withRoot, mSortOrder);
 
             result.cursor = sorted;
-            result.cursor.registerContentObserver(mObserver);
         } catch (Exception e) {
             result.exception = e;
             ContentProviderClient.closeQuietly(result.client);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index f569f5a..4da6567 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -32,7 +32,6 @@
 import android.content.ActivityNotFoundException;
 import android.content.ClipData;
 import android.content.ComponentName;
-import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Intent;
@@ -65,6 +64,8 @@
 import com.android.documentsui.model.DurableUtils;
 import com.android.documentsui.model.RootInfo;
 
+import libcore.io.IoUtils;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
@@ -81,6 +82,8 @@
 
     private static final String EXTRA_STATE = "state";
 
+    private boolean mIgnoreNextNavigation;
+
     private RootsCache mRoots;
     private State mState;
 
@@ -192,10 +195,20 @@
             } catch (IOException e) {
                 Log.w(TAG, "Failed to resume", e);
             } finally {
-                cursor.close();
+                IoUtils.closeQuietly(cursor);
             }
 
-            mDrawerLayout.openDrawer(mRootsContainer);
+            // If restored root isn't valid, fall back to recents
+            final RootInfo root = getCurrentRoot();
+            final List<RootInfo> matchingRoots = mRoots.getMatchingRoots(mState);
+            if (!matchingRoots.contains(root)) {
+                mState.stack.clear();
+            }
+
+            // Only open drawer when showing recents
+            if (mState.stack.isRecents()) {
+                mDrawerLayout.openDrawer(mRootsContainer);
+            }
         }
     }
 
@@ -245,6 +258,14 @@
 
         actionBar.setDisplayShowHomeEnabled(true);
 
+        if (mState.action == ACTION_MANAGE) {
+            actionBar.setDisplayHomeAsUpEnabled(false);
+            mDrawerToggle.setDrawerIndicatorEnabled(false);
+        } else {
+            actionBar.setDisplayHomeAsUpEnabled(true);
+            mDrawerToggle.setDrawerIndicatorEnabled(true);
+        }
+
         if (mDrawerLayout.isDrawerOpen(mRootsContainer)) {
             actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
             actionBar.setIcon(new ColorDrawable());
@@ -254,33 +275,19 @@
             } else if (mState.action == ACTION_CREATE) {
                 actionBar.setTitle(R.string.title_save);
             }
-
-            actionBar.setDisplayHomeAsUpEnabled(true);
-            mDrawerToggle.setDrawerIndicatorEnabled(true);
-
         } else {
             final RootInfo root = getCurrentRoot();
             actionBar.setIcon(root != null ? root.loadIcon(this) : null);
 
-            if (mRoots.isRecentsRoot(root)) {
+            if (mState.stack.size() <= 1) {
                 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
                 actionBar.setTitle(root.title);
             } else {
+                mIgnoreNextNavigation = true;
                 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
                 actionBar.setTitle(null);
-                actionBar.setListNavigationCallbacks(mSortAdapter, mSortListener);
-                actionBar.setSelectedNavigationItem(mState.sortOrder);
-            }
-
-            if (mState.stack.size() > 1) {
-                actionBar.setDisplayHomeAsUpEnabled(true);
-                mDrawerToggle.setDrawerIndicatorEnabled(false);
-            } else if (mState.action == ACTION_MANAGE) {
-                actionBar.setDisplayHomeAsUpEnabled(false);
-                mDrawerToggle.setDrawerIndicatorEnabled(false);
-            } else {
-                actionBar.setDisplayHomeAsUpEnabled(true);
-                mDrawerToggle.setDrawerIndicatorEnabled(true);
+                actionBar.setListNavigationCallbacks(mStackAdapter, mStackListener);
+                actionBar.setSelectedNavigationItem(mStackAdapter.getCount() - 1);
             }
         }
     }
@@ -328,13 +335,20 @@
 
         final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
         final MenuItem search = menu.findItem(R.id.menu_search);
-        final MenuItem grid =  menu.findItem(R.id.menu_grid);
+        final MenuItem sort = menu.findItem(R.id.menu_sort);
+        final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
+        final MenuItem grid = menu.findItem(R.id.menu_grid);
         final MenuItem list = menu.findItem(R.id.menu_list);
         final MenuItem settings = menu.findItem(R.id.menu_settings);
 
         grid.setVisible(mState.mode != MODE_GRID);
         list.setVisible(mState.mode != MODE_LIST);
 
+        // No sorting in recents
+        sort.setVisible(cwd != null);
+        // Only sort by size when visible
+        sortSize.setVisible(mState.showSize);
+
         final boolean searchVisible;
         if (mState.action == ACTION_CREATE) {
             createDir.setVisible(cwd != null && cwd.isCreateSupported());
@@ -375,6 +389,18 @@
             return true;
         } else if (id == R.id.menu_search) {
             return false;
+        } else if (id == R.id.menu_sort_name) {
+            mState.sortOrder = State.SORT_ORDER_DISPLAY_NAME;
+            updateDisplayState();
+            return true;
+        } else if (id == R.id.menu_sort_date) {
+            mState.sortOrder = State.SORT_ORDER_LAST_MODIFIED;
+            updateDisplayState();
+            return true;
+        } else if (id == R.id.menu_sort_size) {
+            mState.sortOrder = State.SORT_ORDER_SIZE;
+            updateDisplayState();
+            return true;
         } else if (id == R.id.menu_grid) {
             // TODO: persist explicit user mode for cwd
             mState.mode = MODE_GRID;
@@ -421,25 +447,15 @@
         updateActionBar();
     }
 
-    // TODO: support additional sort orders
-    private BaseAdapter mSortAdapter = new BaseAdapter() {
+    private BaseAdapter mStackAdapter = new BaseAdapter() {
         @Override
         public int getCount() {
-            return mState.showSize ? 3 : 2;
+            return mState.stack.size();
         }
 
         @Override
-        public Object getItem(int position) {
-            switch (position) {
-                case 0:
-                    return getText(R.string.sort_name);
-                case 1:
-                    return getText(R.string.sort_date);
-                case 2:
-                    return getText(R.string.sort_size);
-                default:
-                    return null;
-            }
+        public DocumentInfo getItem(int position) {
+            return mState.stack.get(mState.stack.size() - position - 1);
         }
 
         @Override
@@ -455,17 +471,15 @@
             }
 
             final TextView title = (TextView) convertView.findViewById(android.R.id.title);
-            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+            final DocumentInfo doc = getItem(position);
 
-            if (mState.stack.size() > 0) {
-                title.setText(mState.stack.getTitle(mRoots));
+            if (position == 0) {
+                final RootInfo root = getCurrentRoot();
+                title.setText(root.title);
             } else {
-                // No directory means recents
-                title.setText(R.string.root_recent);
+                title.setText(doc.displayName);
             }
 
-            summary.setText((String) getItem(position));
-
             return convertView;
         }
 
@@ -477,17 +491,31 @@
             }
 
             final TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
-            text1.setText((String) getItem(position));
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = getCurrentRoot();
+                text1.setText(root.title);
+            } else {
+                text1.setText(doc.displayName);
+            }
 
             return convertView;
         }
     };
 
-    private OnNavigationListener mSortListener = new OnNavigationListener() {
+    private OnNavigationListener mStackListener = new OnNavigationListener() {
         @Override
         public boolean onNavigationItemSelected(int itemPosition, long itemId) {
-            mState.sortOrder = itemPosition;
-            updateDisplayState();
+            if (mIgnoreNextNavigation) {
+                mIgnoreNextNavigation = false;
+                return false;
+            }
+
+            while (mState.stack.size() > itemPosition + 1) {
+                mState.stack.pop();
+            }
+            onCurrentDirectoryChanged();
             return true;
         }
     };
@@ -629,16 +657,12 @@
         final DocumentInfo cwd = getCurrentDirectory();
         final String authority = cwd.uri.getAuthority();
 
-        final ContentProviderClient client = getContentResolver()
-                .acquireUnstableContentProviderClient(authority);
-        try {
-            final Uri childUri = DocumentsContract.createDocument(
-                    getContentResolver(), cwd.uri, mimeType, displayName);
+        final Uri childUri = DocumentsContract.createDocument(
+                getContentResolver(), cwd.uri, mimeType, displayName);
+        if (childUri != null) {
             onFinished(childUri);
-        } catch (Exception e) {
+        } else {
             Toast.makeText(this, R.string.save_error, Toast.LENGTH_SHORT).show();
-        } finally {
-            ContentProviderClient.closeQuietly(client);
         }
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
new file mode 100644
index 0000000..b5b1033
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.provider.DocumentsContract.Document;
+
+import com.google.android.collect.Maps;
+
+import java.util.HashMap;
+
+public class IconUtils {
+
+    private static HashMap<String, Integer> sMimeIcons = Maps.newHashMap();
+
+    private static void add(String mimeType, int resId) {
+        if (sMimeIcons.put(mimeType, resId) != null) {
+            throw new RuntimeException(mimeType + " already registered!");
+        }
+    }
+
+    static {
+        int icon;
+
+        // Package
+        icon = R.drawable.ic_doc_apk;
+        add("application/vnd.android.package-archive", icon);
+
+        // Audio
+        icon = R.drawable.ic_doc_audio;
+        add("application/ogg", icon);
+        add("application/x-flac", icon);
+
+        // Certificate
+        icon = R.drawable.ic_doc_certificate;
+        add("application/pgp-keys", icon);
+        add("application/pgp-signature", icon);
+        add("application/x-pkcs12", icon);
+        add("application/x-pkcs7-certreqresp", icon);
+        add("application/x-pkcs7-crl", icon);
+        add("application/x-x509-ca-cert", icon);
+        add("application/x-x509-user-cert", icon);
+        add("application/x-pkcs7-certificates", icon);
+        add("application/x-pkcs7-mime", icon);
+        add("application/x-pkcs7-signature", icon);
+
+        // Source code
+        icon = R.drawable.ic_doc_codes;
+        add("application/rdf+xml", icon);
+        add("application/rss+xml", icon);
+        add("application/x-object", icon);
+        add("application/xhtml+xml", icon);
+        add("text/css", icon);
+        add("text/html", icon);
+        add("text/xml", icon);
+        add("text/x-c++hdr", icon);
+        add("text/x-c++src", icon);
+        add("text/x-chdr", icon);
+        add("text/x-csrc", icon);
+        add("text/x-dsrc", icon);
+        add("text/x-csh", icon);
+        add("text/x-haskell", icon);
+        add("text/x-java", icon);
+        add("text/x-literate-haskell", icon);
+        add("text/x-pascal", icon);
+        add("text/x-tcl", icon);
+        add("text/x-tex", icon);
+        add("application/x-latex", icon);
+        add("application/x-texinfo", icon);
+        add("application/atom+xml", icon);
+        add("application/ecmascript", icon);
+        add("application/json", icon);
+        add("application/javascript", icon);
+        add("application/xml", icon);
+        add("text/javascript", icon);
+        add("application/x-javascript", icon);
+
+        // Compressed
+        icon = R.drawable.ic_doc_compressed;
+        add("application/mac-binhex40", icon);
+        add("application/rar", icon);
+        add("application/zip", icon);
+        add("application/x-apple-diskimage", icon);
+        add("application/x-debian-package", icon);
+        add("application/x-gtar", icon);
+        add("application/x-iso9660-image", icon);
+        add("application/x-lha", icon);
+        add("application/x-lzh", icon);
+        add("application/x-lzx", icon);
+        add("application/x-stuffit", icon);
+        add("application/x-tar", icon);
+        add("application/x-webarchive", icon);
+        add("application/x-webarchive-xml", icon);
+        add("application/gzip", icon);
+        add("application/x-7z-compressed", icon);
+        add("application/x-deb", icon);
+        add("application/x-rar-compressed", icon);
+
+        // Contact
+        icon = R.drawable.ic_doc_contact;
+        add("text/x-vcard", icon);
+        add("text/vcard", icon);
+
+        // Event
+        icon = R.drawable.ic_doc_event;
+        add("text/calendar", icon);
+        add("text/x-vcalendar", icon);
+
+        // Font
+        icon = R.drawable.ic_doc_font;
+        add("application/x-font", icon);
+        add("application/font-woff", icon);
+        add("application/x-font-woff", icon);
+        add("application/x-font-ttf", icon);
+
+        // Image
+        icon = R.drawable.ic_doc_image;
+        add("application/vnd.oasis.opendocument.graphics", icon);
+        add("application/vnd.oasis.opendocument.graphics-template", icon);
+        add("application/vnd.oasis.opendocument.image", icon);
+        add("application/vnd.stardivision.draw", icon);
+        add("application/vnd.sun.xml.draw", icon);
+        add("application/vnd.sun.xml.draw.template", icon);
+
+        // PDF
+        icon = R.drawable.ic_doc_pdf;
+        add("application/pdf", icon);
+
+        // Presentation
+        icon = R.drawable.ic_doc_presentation;
+        add("application/vnd.ms-powerpoint", icon);
+        add("application/vnd.openxmlformats-officedocument.presentationml.presentation", icon);
+        add("application/vnd.openxmlformats-officedocument.presentationml.template", icon);
+        add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", icon);
+        add("application/vnd.stardivision.impress", icon);
+        add("application/vnd.sun.xml.impress", icon);
+        add("application/vnd.sun.xml.impress.template", icon);
+        add("application/x-kpresenter", icon);
+        add("application/vnd.oasis.opendocument.presentation", icon);
+
+        // Spreadsheet
+        icon = R.drawable.ic_doc_spreadsheet;
+        add("application/vnd.oasis.opendocument.spreadsheet", icon);
+        add("application/vnd.oasis.opendocument.spreadsheet-template", icon);
+        add("application/vnd.ms-excel", icon);
+        add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", icon);
+        add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", icon);
+        add("application/vnd.stardivision.calc", icon);
+        add("application/vnd.sun.xml.calc", icon);
+        add("application/vnd.sun.xml.calc.template", icon);
+        add("application/x-kspread", icon);
+
+        // Text
+        icon = R.drawable.ic_doc_text;
+        add("application/vnd.oasis.opendocument.text", icon);
+        add("application/vnd.oasis.opendocument.text-master", icon);
+        add("application/vnd.oasis.opendocument.text-template", icon);
+        add("application/vnd.oasis.opendocument.text-web", icon);
+        add("application/msword", icon);
+        add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", icon);
+        add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", icon);
+        add("application/vnd.stardivision.writer", icon);
+        add("application/vnd.stardivision.writer-global", icon);
+        add("application/vnd.sun.xml.writer", icon);
+        add("application/vnd.sun.xml.writer.global", icon);
+        add("application/vnd.sun.xml.writer.template", icon);
+        add("application/x-abiword", icon);
+        add("application/x-kword", icon);
+
+        // Video
+        icon = R.drawable.ic_doc_video;
+        add("application/x-quicktimeplayer", icon);
+        add("application/x-shockwave-flash", icon);
+    }
+
+    public static Drawable loadPackageIcon(Context context, String authority, int icon) {
+        if (icon != 0) {
+            if (authority != null) {
+                final PackageManager pm = context.getPackageManager();
+                final ProviderInfo info = pm.resolveContentProvider(authority, 0);
+                if (info != null) {
+                    return pm.getDrawable(info.packageName, icon, info.applicationInfo);
+                }
+            } else {
+                return context.getResources().getDrawable(icon);
+            }
+        }
+        return null;
+    }
+
+    public static Drawable loadMimeIcon(Context context, String mimeType) {
+        final Resources res = context.getResources();
+
+        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+            return res.getDrawable(R.drawable.ic_dir);
+        }
+
+        // Look for exact match first
+        Integer resId = sMimeIcons.get(mimeType);
+        if (resId != null) {
+            return res.getDrawable(resId);
+        }
+
+        if (mimeType == null) {
+            // TODO: generic icon?
+            return null;
+        }
+
+        // Otherwise look for partial match
+        final String typeOnly = mimeType.split("/")[0];
+        if ("audio".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_audio);
+        } else if ("image".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_image);
+        } else if ("text".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_text);
+        } else if ("video".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_video);
+        } else {
+            // TODO: generic icon?
+            return null;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
index d0e5ff6..0b58218 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
@@ -18,6 +18,7 @@
 
 import android.database.AbstractCursor;
 import android.database.Cursor;
+import android.os.Bundle;
 
 /**
  * Cursor wrapper that adds columns to identify which root a document came from.
@@ -63,6 +64,11 @@
     }
 
     @Override
+    public Bundle getExtras() {
+        return mCursor.getExtras();
+    }
+
+    @Override
     public void close() {
         super.close();
         mCursor.close();
@@ -128,5 +134,4 @@
     public boolean isNull(int column) {
         return mCursor.isNull(column);
     }
-
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index 0b10f19..0625011 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -206,23 +206,4 @@
         }
         return matching;
     }
-
-    @GuardedBy("ActivityThread")
-    public static Drawable resolveDocumentIcon(Context context, String mimeType) {
-        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-            return context.getResources().getDrawable(R.drawable.ic_dir);
-        } else {
-            final PackageManager pm = context.getPackageManager();
-            final Intent intent = new Intent(Intent.ACTION_VIEW);
-            intent.setType(mimeType);
-
-            final ResolveInfo activityInfo = pm.resolveActivity(
-                    intent, PackageManager.MATCH_DEFAULT_ONLY);
-            if (activityInfo != null) {
-                return activityInfo.loadIcon(pm);
-            } else {
-                return null;
-            }
-        }
-    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
index 8b0a974..dc5b64a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -74,7 +74,7 @@
 
         final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
         icon.setImageDrawable(
-                RootsCache.resolveDocumentIcon(context, getArguments().getString(EXTRA_MIME_TYPE)));
+                IconUtils.loadMimeIcon(context, getArguments().getString(EXTRA_MIME_TYPE)));
 
         mDisplayName = (EditText) view.findViewById(android.R.id.title);
         mDisplayName.addTextChangedListener(mDisplayNameWatcher);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
index b434a35..19ad2e2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
@@ -22,6 +22,7 @@
 
 import android.database.AbstractCursor;
 import android.database.Cursor;
+import android.os.Bundle;
 import android.provider.DocumentsContract.Document;
 
 /**
@@ -96,6 +97,11 @@
     }
 
     @Override
+    public Bundle getExtras() {
+        return mCursor.getExtras();
+    }
+
+    @Override
     public void close() {
         super.close();
         mCursor.close();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java b/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
index 2405cb5..7b7c3d5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
@@ -33,10 +33,14 @@
 import libcore.io.Streams;
 
 import java.io.InputStream;
+import java.io.OutputStream;
 
 public class TestActivity extends Activity {
     private static final String TAG = "TestActivity";
 
+    private static final int CODE_READ = 42;
+    private static final int CODE_WRITE = 43;
+
     private TextView mResult;
 
     @Override
@@ -49,10 +53,10 @@
         view.setOrientation(LinearLayout.VERTICAL);
 
         final CheckBox multiple = new CheckBox(context);
-        multiple.setText("\nALLOW_MULTIPLE\n");
+        multiple.setText("ALLOW_MULTIPLE");
         view.addView(multiple);
         final CheckBox localOnly = new CheckBox(context);
-        localOnly.setText("\nLOCAL_ONLY\n");
+        localOnly.setText("LOCAL_ONLY");
         view.addView(localOnly);
 
         Button button;
@@ -70,7 +74,7 @@
                 if (localOnly.isChecked()) {
                     intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                 }
-                startActivityForResult(intent, 42);
+                startActivityForResult(intent, CODE_READ);
             }
         });
         view.addView(button);
@@ -89,7 +93,7 @@
                 if (localOnly.isChecked()) {
                     intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                 }
-                startActivityForResult(intent, 42);
+                startActivityForResult(intent, CODE_READ);
             }
         });
         view.addView(button);
@@ -108,7 +112,7 @@
                 if (localOnly.isChecked()) {
                     intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                 }
-                startActivityForResult(intent, 42);
+                startActivityForResult(intent, CODE_READ);
             }
         });
         view.addView(button);
@@ -129,7 +133,7 @@
                 if (localOnly.isChecked()) {
                     intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                 }
-                startActivityForResult(intent, 42);
+                startActivityForResult(intent, CODE_READ);
             }
         });
         view.addView(button);
@@ -146,7 +150,7 @@
                 if (localOnly.isChecked()) {
                     intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                 }
-                startActivityForResult(intent, 42);
+                startActivityForResult(intent, CODE_WRITE);
             }
         });
         view.addView(button);
@@ -165,7 +169,7 @@
                 if (localOnly.isChecked()) {
                     intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                 }
-                startActivityForResult(Intent.createChooser(intent, "Kittens!"), 42);
+                startActivityForResult(Intent.createChooser(intent, "Kittens!"), CODE_READ);
             }
         });
         view.addView(button);
@@ -178,20 +182,45 @@
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        mResult.setText("resultCode=" + resultCode + ", data=" + String.valueOf(data));
+        mResult.setText(null);
+        String result = "resultCode=" + resultCode + ", data=" + String.valueOf(data);
 
-        final Uri uri = data != null ? data.getData() : null;
-        if (uri != null) {
-            InputStream is = null;
-            try {
-                is = getContentResolver().openInputStream(uri);
-                final int length = Streams.readFullyNoClose(is).length;
-                Log.d(TAG, "read length=" + length);
-            } catch (Exception e) {
-                Log.w(TAG, "Failed to read " + uri, e);
-            } finally {
-                IoUtils.closeQuietly(is);
+        if (requestCode == CODE_READ) {
+            final Uri uri = data != null ? data.getData() : null;
+            if (uri != null) {
+                InputStream is = null;
+                try {
+                    is = getContentResolver().openInputStream(uri);
+                    final int length = Streams.readFullyNoClose(is).length;
+                    result += "; read length=" + length;
+                } catch (Exception e) {
+                    result += "; ERROR";
+                    Log.w(TAG, "Failed to read " + uri, e);
+                } finally {
+                    IoUtils.closeQuietly(is);
+                }
+            } else {
+                result += "no uri?";
+            }
+        } else if (requestCode == CODE_WRITE) {
+            final Uri uri = data != null ? data.getData() : null;
+            if (uri != null) {
+                OutputStream os = null;
+                try {
+                    os = getContentResolver().openOutputStream(uri);
+                    os.write("THE COMPLETE WORKS OF SHAKESPEARE".getBytes());
+                } catch (Exception e) {
+                    result += "; ERROR";
+                    Log.w(TAG, "Failed to write " + uri, e);
+                } finally {
+                    IoUtils.closeQuietly(os);
+                }
+            } else {
+                result += "no uri?";
             }
         }
+
+        Log.d(TAG, result);
+        mResult.setText(result);
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 7721bcc..a1489a5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -16,17 +16,13 @@
 
 package com.android.documentsui.model;
 
+import android.content.ContentProviderClient;
 import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
 import android.database.Cursor;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 
-import com.android.documentsui.RecentsProvider;
 import com.android.documentsui.RootCursorWrapper;
 
 import libcore.io.IoUtils;
@@ -117,41 +113,12 @@
         return doc;
     }
 
-    @Deprecated
-    public static DocumentInfo fromRecentOpenCursor(ContentResolver resolver, Cursor recentCursor)
-            throws FileNotFoundException {
-        final Uri uri = Uri.parse(getCursorString(recentCursor, RecentsProvider.COL_URI));
-        final long lastModified = getCursorLong(recentCursor, RecentsProvider.COL_TIMESTAMP);
-
-        Cursor cursor = null;
-        try {
-            cursor = resolver.query(uri, null, null, null, null);
-            if (!cursor.moveToFirst()) {
-                throw new FileNotFoundException("Missing details for " + uri);
-            }
-
-            final DocumentInfo doc = new DocumentInfo();
-            doc.uri = uri;
-            doc.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
-            doc.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
-            doc.lastModified = lastModified;
-            doc.flags = getCursorInt(cursor, Document.COLUMN_FLAGS)
-                    & Document.FLAG_SUPPORTS_THUMBNAIL;
-            doc.summary = getCursorString(cursor, Document.COLUMN_SUMMARY);
-            doc.size = getCursorLong(cursor, Document.COLUMN_SIZE);
-            doc.icon = getCursorInt(cursor, Document.COLUMN_ICON);
-            return doc;
-        } catch (Throwable t) {
-            throw asFileNotFoundException(t);
-        } finally {
-            IoUtils.closeQuietly(cursor);
-        }
-    }
-
     public static DocumentInfo fromUri(ContentResolver resolver, Uri uri) throws FileNotFoundException {
+        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                uri.getAuthority());
         Cursor cursor = null;
         try {
-            cursor = resolver.query(uri, null, null, null, null);
+            cursor = client.query(uri, null, null, null, null);
             if (!cursor.moveToFirst()) {
                 throw new FileNotFoundException("Missing details for " + uri);
             }
@@ -169,6 +136,7 @@
             throw asFileNotFoundException(t);
         } finally {
             IoUtils.closeQuietly(cursor);
+            ContentProviderClient.closeQuietly(client);
         }
     }
 
@@ -201,25 +169,6 @@
         return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
     }
 
-    public Drawable loadIcon(Context context) {
-        return loadIcon(context, uri.getAuthority(), icon);
-    }
-
-    public static Drawable loadIcon(Context context, String authority, int icon) {
-        if (icon != 0) {
-            if (authority != null) {
-                final PackageManager pm = context.getPackageManager();
-                final ProviderInfo info = pm.resolveContentProvider(authority, 0);
-                if (info != null) {
-                    return pm.getDrawable(info.packageName, icon, info.applicationInfo);
-                }
-            } else {
-                return context.getResources().getDrawable(icon);
-            }
-        }
-        return null;
-    }
-
     public static String getCursorString(Cursor cursor, String columnName) {
         final int index = cursor.getColumnIndex(columnName);
         return (index != -1) ? cursor.getString(index) : null;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
index 64631ab..33a1376 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
@@ -45,6 +45,10 @@
         }
     }
 
+    public boolean isRecents() {
+        return size() == 0;
+    }
+
     @Override
     public void reset() {
         clear();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 189284b..c3698a0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -25,6 +25,8 @@
 import android.graphics.drawable.Drawable;
 import android.provider.DocumentsContract.Root;
 
+import com.android.documentsui.IconUtils;
+
 import java.util.Objects;
 
 /**
@@ -52,11 +54,18 @@
         root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
         root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
         root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
+
+        // TODO: remove this hack
+        if ("com.google.android.apps.docs.storage".equals(root.authority)) {
+            root.flags &= ~(Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_IMAGES
+                    | Root.FLAG_PROVIDES_VIDEO);
+        }
+
         return root;
     }
 
     public Drawable loadIcon(Context context) {
-        return DocumentInfo.loadIcon(context, authority, icon);
+        return IconUtils.loadPackageIcon(context, authority, icon);
     }
 
     @Override
diff --git a/packages/ExternalStorageProvider/AndroidManifest.xml b/packages/ExternalStorageProvider/AndroidManifest.xml
index 5272166..7094efc 100644
--- a/packages/ExternalStorageProvider/AndroidManifest.xml
+++ b/packages/ExternalStorageProvider/AndroidManifest.xml
@@ -13,7 +13,20 @@
             android:permission="android.permission.MANAGE_DOCUMENTS">
             <meta-data
                 android:name="android.content.DOCUMENT_PROVIDER"
-                android:resource="@xml/document_provider" />
+                android:value="true" />
+        </provider>
+
+        <!-- TODO: find a better place for tests to live -->
+        <provider
+            android:name=".TestDocumentsProvider"
+            android:authorities="com.example.documents"
+            android:grantUriPermissions="true"
+            android:exported="true"
+            android:permission="android.permission.MANAGE_DOCUMENTS"
+            android:enabled="false">
+            <meta-data
+                android:name="android.content.DOCUMENT_PROVIDER"
+                android:value="true" />
         </provider>
     </application>
 </manifest>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java
new file mode 100644
index 0000000..872974f
--- /dev/null
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.externalstorage;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.MatrixCursor.RowBuilder;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsProvider;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+import java.lang.ref.WeakReference;
+
+public class TestDocumentsProvider extends DocumentsProvider {
+    private static final String TAG = "TestDocuments";
+
+    private static final boolean CRASH_ROOTS = false;
+    private static final boolean CRASH_DOCUMENT = false;
+
+    private static final String MY_ROOT_ID = "myRoot";
+    private static final String MY_DOC_ID = "myDoc";
+    private static final String MY_DOC_NULL = "myNull";
+
+    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
+            Root.COLUMN_ROOT_ID, Root.COLUMN_ROOT_TYPE, Root.COLUMN_FLAGS, Root.COLUMN_ICON,
+            Root.COLUMN_TITLE, Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID,
+            Root.COLUMN_AVAILABLE_BYTES,
+    };
+
+    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
+            Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME,
+            Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
+    };
+
+    private static String[] resolveRootProjection(String[] projection) {
+        return projection != null ? projection : DEFAULT_ROOT_PROJECTION;
+    }
+
+    private static String[] resolveDocumentProjection(String[] projection) {
+        return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
+    }
+
+    @Override
+    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+        if (CRASH_ROOTS) System.exit(12);
+
+        final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
+        final RowBuilder row = result.newRow();
+        row.offer(Root.COLUMN_ROOT_ID, MY_ROOT_ID);
+        row.offer(Root.COLUMN_ROOT_TYPE, Root.ROOT_TYPE_SERVICE);
+        row.offer(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_RECENTS);
+        row.offer(Root.COLUMN_TITLE, "_Test title which is really long");
+        row.offer(Root.COLUMN_SUMMARY, "_Summary which is also super long text");
+        row.offer(Root.COLUMN_DOCUMENT_ID, MY_DOC_ID);
+        row.offer(Root.COLUMN_AVAILABLE_BYTES, 1024);
+        return result;
+    }
+
+    @Override
+    public Cursor queryDocument(String documentId, String[] projection)
+            throws FileNotFoundException {
+        if (CRASH_DOCUMENT) System.exit(12);
+
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        includeFile(result, documentId);
+        return result;
+    }
+
+    /**
+     * Holds any outstanding or finished "network" fetching.
+     */
+    private WeakReference<CloudTask> mTask;
+
+    private static class CloudTask implements Runnable {
+
+        private final ContentResolver mResolver;
+        private final Uri mNotifyUri;
+
+        private volatile boolean mFinished;
+
+        public CloudTask(ContentResolver resolver, Uri notifyUri) {
+            mResolver = resolver;
+            mNotifyUri = notifyUri;
+        }
+
+        @Override
+        public void run() {
+            // Pretend to do some network
+            Log.d(TAG, hashCode() + ": pretending to do some network!");
+            SystemClock.sleep(2000);
+            Log.d(TAG, hashCode() + ": network done!");
+
+            mFinished = true;
+
+            // Tell anyone remotely they should requery
+            mResolver.notifyChange(mNotifyUri, null, false);
+        }
+
+        public boolean includeIfFinished(MatrixCursor result) {
+            Log.d(TAG, hashCode() + ": includeIfFinished() found " + mFinished);
+            if (mFinished) {
+                includeFile(result, "_networkfile1");
+                includeFile(result, "_networkfile2");
+                includeFile(result, "_networkfile3");
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private static class CloudCursor extends MatrixCursor {
+        public Object keepAlive;
+        public final Bundle extras = new Bundle();
+
+        public CloudCursor(String[] columnNames) {
+            super(columnNames);
+        }
+
+        @Override
+        public Bundle getExtras() {
+            return extras;
+        }
+    }
+
+    @Override
+    public Cursor queryChildDocuments(
+            String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException {
+
+        final ContentResolver resolver = getContext().getContentResolver();
+        final Uri notifyUri = DocumentsContract.buildDocumentUri(
+                "com.example.documents", parentDocumentId);
+
+        CloudCursor result = new CloudCursor(resolveDocumentProjection(projection));
+        result.setNotificationUri(resolver, notifyUri);
+
+        // Always include local results
+        includeFile(result, MY_DOC_NULL);
+        includeFile(result, "localfile1");
+        includeFile(result, "localfile2");
+
+        synchronized (this) {
+            // Try picking up an existing network fetch
+            CloudTask task = mTask != null ? mTask.get() : null;
+            if (task == null) {
+                Log.d(TAG, "No network task found; starting!");
+                task = new CloudTask(resolver, notifyUri);
+                mTask = new WeakReference<CloudTask>(task);
+                new Thread(task).start();
+
+                // Aggressively try freeing weak reference above
+                new Thread() {
+                    @Override
+                    public void run() {
+                        while (mTask.get() != null) {
+                            SystemClock.sleep(200);
+                            System.gc();
+                            System.runFinalization();
+                        }
+                        Log.d(TAG, "AHA! THE CLOUD TASK WAS GC'ED!");
+                    }
+                }.start();
+            }
+
+            // Blend in cloud results if ready
+            if (task.includeIfFinished(result)) {
+                result.extras.putString(DocumentsContract.EXTRA_INFO,
+                        "Everything Went Better Than Expected and this message is quite "
+                                + "long and verbose and maybe even too long");
+                result.extras.putString(DocumentsContract.EXTRA_ERROR,
+                        "But then again, maybe our server ran into an error, which means "
+                                + "we're going to have a bad time");
+            } else {
+                result.extras.putBoolean(DocumentsContract.EXTRA_LOADING, true);
+            }
+
+            // Tie the network fetch to the cursor GC lifetime
+            result.keepAlive = task;
+
+            return result;
+        }
+    }
+
+    @Override
+    public Cursor queryRecentDocuments(String rootId, String[] projection)
+            throws FileNotFoundException {
+        // Pretend to take a super long time to respond
+        SystemClock.sleep(3000);
+
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        includeFile(result, "It was /worth/ the_wait for?the file:with the&incredibly long name");
+        return result;
+    }
+
+    @Override
+    public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        throw new FileNotFoundException();
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    private static void includeFile(MatrixCursor result, String docId) {
+        final RowBuilder row = result.newRow();
+        row.offer(Document.COLUMN_DOCUMENT_ID, docId);
+        row.offer(Document.COLUMN_DISPLAY_NAME, docId);
+        row.offer(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
+
+        if (MY_DOC_ID.equals(docId)) {
+            row.offer(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
+        } else if (MY_DOC_NULL.equals(docId)) {
+            // No MIME type
+        } else {
+            row.offer(Document.COLUMN_MIME_TYPE, "application/octet-stream");
+        }
+    }
+}
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
index 095655c..f537022 100644
--- a/packages/InputDevices/Android.mk
+++ b/packages/InputDevices/Android.mk
@@ -30,14 +30,20 @@
 # Validate all key maps.
 include $(CLEAR_VARS)
 
-validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
-files := frameworks/base/packages/InputDevices/res/raw/*.kcm
-
 LOCAL_MODULE := validate_input_devices_keymaps
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := validatekeymaps
+intermediates := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE),,COMMON)
+LOCAL_BUILT_MODULE := $(intermediates)/stamp
 
-validate_input_devices_keymaps: $(files)
-	$(hide) $(validatekeymaps) $(files)
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+input_devices_keymaps := $(wildcard $(LOCAL_PATH)/res/raw/*.kcm)
+$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
+$(LOCAL_BUILT_MODULE) : $(input_devices_keymaps) | $(validatekeymaps)
+	$(hide) $(PRIVATE_VALIDATEKEYMAPS) $^
+	$(hide) mkdir -p $(dir $@) && touch $@
 
-include $(BUILD_PHONY_PACKAGE)
+# Run validatekeymaps unconditionally for platform build.
+droidcore all_modules : $(LOCAL_BUILT_MODULE)
+
+# Reset temp vars.
+validatekeymaps :=
+input_devices_keymaps :=
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index eedb7d0..00124b0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -24,6 +24,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.AlertDialog;
+import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.admin.DevicePolicyManager;
 import android.appwidget.AppWidgetHost;
@@ -40,6 +41,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.media.RemoteControlClient;
+import android.os.Bundle;
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -47,6 +49,9 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.speech.hotword.HotwordRecognitionListener;
+import android.speech.hotword.HotwordRecognizer;
+import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
@@ -63,6 +68,11 @@
 
 public class KeyguardHostView extends KeyguardViewBase {
     private static final String TAG = "KeyguardHostView";
+    // Don't enable hotword on limited-memory devices.
+    private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic();
+    // Indicates if hotword is enabled, should it also be available on secure keyguard(s).
+    private static final boolean ENABLE_HOTWORD_SECURE = false;
+
     // Transport control states.
     static final int TRANSPORT_GONE = 0;
     static final int TRANSPORT_INVISIBLE = 1;
@@ -77,6 +87,13 @@
     // Found in KeyguardAppWidgetPickActivity.java
     static final int APPWIDGET_HOST_ID = 0x4B455947;
 
+    // TODO: Fix this to be non-static.
+    // We need to be careful here to make stopRecognition calls on the same instance
+    // that started it. Since KeyguardHostView is a view, it keeps getting
+    // recreated every now and then, and unless we figure out a better way,
+    // this needs to be a static field.
+    private static HotwordRecognizer sHotwordClient;
+
     private final int MAX_WIDGETS = 5;
 
     private AppWidgetHost mAppWidgetHost;
@@ -117,6 +134,8 @@
 
     private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
 
+    private boolean mIsScreenOn;
+
     protected int mClientGeneration;
 
     protected boolean mShowSecurityWhenReturn;
@@ -198,6 +217,11 @@
         if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
             Log.v(TAG, "Keyguard secure camera disabled by DPM");
         }
+
+        // Create Hotword recognizer, for the first time.
+        if (ENABLE_HOTWORD && sHotwordClient == null) {
+            sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext());
+        }
     }
 
     private void getInitialTransportState() {
@@ -295,6 +319,21 @@
                 }
             }
         }
+        @Override
+        public void onPhoneStateChanged(int phoneState) {
+            // We need to stop hotword detection when a call state is not idle anymore.
+            if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)
+                    && TelephonyManager.CALL_STATE_IDLE != phoneState) {
+                if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle");
+                maybeStopHotwordDetector();
+            }
+        }
+        @Override
+        public void onUserSwitching(int userId) {
+            if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+                maybeStopHotwordDetector();
+            }
+        }
     };
 
     private static final boolean isMusicPlaying(int playbackState) {
@@ -778,6 +817,9 @@
             // If the alternate unlock was suppressed, it can now be safely
             // enabled because the user has left keyguard.
             KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+            if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)){
+                maybeStopHotwordDetector();
+            }
 
             // If there's a pending runnable because the user interacted with a widget
             // and we're leaving keyguard, then run it.
@@ -942,6 +984,9 @@
 
         // Emulate Activity life cycle
         if (oldView != null) {
+            if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+                maybeStopHotwordDetector();
+            }
             oldView.onPause();
             oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
         }
@@ -982,6 +1027,7 @@
     @Override
     public void onScreenTurnedOn() {
         if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+        mIsScreenOn = true;
         showPrimarySecurityScreen(false);
         getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
 
@@ -993,6 +1039,12 @@
         if (mViewStateManager != null) {
             mViewStateManager.showUsabilityHints();
         }
+
+        // Start hotword detection on insecure Keyguard.
+        if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+            maybeStartHotwordDetector();
+        }
+
         requestFocus();
     }
 
@@ -1000,6 +1052,7 @@
     public void onScreenTurnedOff() {
         if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
                 Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+        mIsScreenOn = false;
         // Once the screen turns off, we no longer consider this to be first boot and we want the
         // biometric unlock to start next time keyguard is shown.
         KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
@@ -1013,6 +1066,12 @@
         if (cameraPage != null) {
             cameraPage.onScreenTurnedOff();
         }
+
+        // Stop hotword detection on insecure Keyguard.
+        if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+            maybeStopHotwordDetector();
+        }
+
         clearFocus();
     }
 
@@ -1097,6 +1156,9 @@
         new CameraWidgetFrame.Callbacks() {
             @Override
             public void onLaunchingCamera() {
+                if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+                    maybeStopHotwordDetector();
+                }
                 setSliderHandleAlpha(0);
             }
 
@@ -1626,6 +1688,9 @@
     }
 
     public void showAssistant() {
+        if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+            maybeStopHotwordDetector();
+        }
         final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
           .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
 
@@ -1640,4 +1705,130 @@
         mActivityLauncher.launchActivityWithAnimation(
                 intent, false, opts.toBundle(), null, null);
     }
+
+
+    /**
+     * Start the hotword detector if:
+     * <li> ENABLE_HOTWORD is true and
+     * <li> Hotword detection is not already running and
+     * <li> TelephonyManager is in CALL_STATE_IDLE
+     * <li> and Screen is turned on.
+     */
+    private void maybeStartHotwordDetector() {
+        if (!ENABLE_HOTWORD) return;
+
+        if (sHotwordClient != null) {
+            if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()");
+            // Don't start hotword detection if the screen is off.
+            if (!mIsScreenOn) {
+                if (DEBUG) Log.d(TAG, "screen was off, not starting");
+                return;
+            }
+
+            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
+            if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) {
+                if (DEBUG) Log.d(TAG, "Call underway, not starting");
+                return;
+            }
+
+            try {
+                sHotwordClient.startRecognition(mHotwordCallback);
+            } catch(Exception ex) {
+                // Don't allow hotword errors to make the keyguard unusable
+                Log.e(TAG, "Failed to start hotword recognition", ex);
+                sHotwordClient = null;
+            }
+        }
+    }
+
+    /**
+     * Stop hotword detector if:
+     * <li> ENABLE_HOTWORD is true
+     * <li> and hotword is running.
+     */
+    private void maybeStopHotwordDetector() {
+        if (!ENABLE_HOTWORD) return;
+
+        if (sHotwordClient != null) {
+            if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()");
+            try {
+                sHotwordClient.stopRecognition();
+            } catch(Exception ex) {
+                // Don't allow hotword errors to make the keyguard unusable
+                Log.e(TAG, "Failed to start hotword recognition", ex);
+            } finally {
+                sHotwordClient = null;
+            }
+        }
+    }
+
+    private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() {
+        private static final String TAG = "HotwordRecognitionListener";
+
+        public void onHotwordRecognitionStarted() {
+            if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()");
+        }
+
+        public void onHotwordRecognitionStopped() {
+            if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()");
+        }
+
+        public void onHotwordEvent(int eventType, Bundle eventBundle) {
+            if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType);
+            if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) {
+                if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) {
+                    new KeyguardMessageArea.Helper(
+                            (View) getSecurityView(mCurrentSecuritySelection))
+                        .setMessage(eventBundle.getString(HotwordRecognizer.PROMPT_TEXT),true);
+                }
+            }
+        }
+
+        public void onHotwordRecognized(final PendingIntent intent) {
+            if (DEBUG) Log.d(TAG, "onHotwordRecognized");
+            maybeStopHotwordDetector();
+            if (SecurityMode.None == mCurrentSecuritySelection) {
+                if (intent != null) {
+                    try {
+                        intent.send();
+                    } catch (PendingIntent.CanceledException e) {
+                        Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException");
+                    }
+                }
+                mCallback.userActivity(0);
+                mCallback.dismiss(false);
+            } else if (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()) {
+                setOnDismissAction(new OnDismissAction() {
+                    @Override
+                    public boolean onDismiss() {
+                        if (intent != null) {
+                            try {
+                                intent.send();
+                            } catch (PendingIntent.CanceledException e) {
+                                Log.w(TAG, "Failed to launch PendingIntent."
+                                        + "Encountered CanceledException");
+                            }
+                        }
+                        return false;
+                    }
+                });
+                getSecurityView(mCurrentSecuritySelection).showBouncer(0);
+            }
+        }
+
+        public void onHotwordError(int errorCode) {
+            if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode);
+            // TODO: Inspect the error code and handle the errors appropriately
+            // instead of blindly failing.
+            maybeStopHotwordDetector();
+        }
+    };
+
+    private boolean shouldRunHotwordInSecurityMode(SecurityMode mode) {
+        // Enable hotoword for insecure keyguard,
+        // and for pattern unlock if ENABLE_HOTWORD_SECURE is true.
+        return ENABLE_HOTWORD
+                && ((SecurityMode.None == mode)
+                        || (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()));
+    }
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
index 40d55cf..63be102 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -28,8 +28,6 @@
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.speech.hotword.HotwordRecognitionListener;
-import android.speech.hotword.HotwordRecognizer;
 import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -48,12 +46,6 @@
     private static final String ASSIST_ICON_METADATA_NAME =
         "com.android.systemui.action_assist_icon";
 
-    // Don't enable hotword on limited-memory devices.
-    private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic();
-
-    // TODO: Fix this to be non-static.
-    private static HotwordRecognizer sHotwordClient;
-
     private KeyguardSecurityCallback mCallback;
     private GlowPadView mGlowPadView;
     private ObjectAnimator mAnim;
@@ -69,7 +61,6 @@
 
         public void onTrigger(View v, int target) {
             final int resId = mGlowPadView.getResourceIdForTarget(target);
-            maybeStopHotwordDetector();
 
             switch (resId) {
                 case R.drawable.ic_action_assist_generic:
@@ -129,22 +120,6 @@
         public void onSimStateChanged(State simState) {
             updateTargets();
         }
-
-        @Override
-        public void onPhoneStateChanged(int phoneState) {
-            if (ENABLE_HOTWORD) {
-                // We need to stop hotword detection when a call state is not idle anymore.
-                if (phoneState != TelephonyManager.CALL_STATE_IDLE) {
-                    if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle");
-                    maybeStopHotwordDetector();
-                }
-            }
-        }
-
-        @Override
-        public void onUserSwitching(int userId) {
-            maybeStopHotwordDetector();
-        }
     };
 
     private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
@@ -183,9 +158,6 @@
         mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
         View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
         mBouncerFrame = bouncerFrameView.getBackground();
-        if (ENABLE_HOTWORD && sHotwordClient == null) {
-            sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext());
-        }
     }
 
     public void setCarrierArea(View carrierArea) {
@@ -289,20 +261,11 @@
     @Override
     public void onPause() {
         KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback);
-        maybeStopHotwordDetector();
     }
 
     @Override
     public void onResume(int reason) {
         KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback);
-        // TODO: Figure out if there's a better way to do it.
-        // onResume gets called multiple times, however we are interested in
-        // the reason to figure out when to start/stop hotword detection.
-        if (reason == SCREEN_ON) {
-            if (!KeyguardUpdateMonitor.getInstance(getContext()).isSwitchingUser()) {
-                maybeStartHotwordDetector();
-            }
-        }
     }
 
     @Override
@@ -323,100 +286,4 @@
         KeyguardSecurityViewHelper.
                 hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
     }
-
-    /**
-     * Start the hotword detector if:
-     * <li> FLAG_HOTWORD is true and
-     * <li> Hotword detection is not already running and
-     * <li> TelephonyManager is in CALL_STATE_IDLE
-     *
-     * If this method is called when the screen is off,
-     * it attempts to stop hotword detection if it's running.
-     */
-    private void maybeStartHotwordDetector() {
-        if (ENABLE_HOTWORD && sHotwordClient != null) {
-            if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()");
-            // Don't start it if the screen is off or not showing
-            PowerManager powerManager = (PowerManager) getContext().getSystemService(
-                    Context.POWER_SERVICE);
-            if (!powerManager.isScreenOn()) {
-                if (DEBUG) Log.d(TAG, "screen was off, not starting");
-                return;
-            }
-
-            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
-            if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) {
-                if (DEBUG) Log.d(TAG, "Call underway, not starting");
-                return;
-            }
-
-            try {
-                sHotwordClient.startRecognition(mHotwordCallback);
-            } catch(Exception ex) {
-                // Don't allow hotword errors to make the keyguard unusable
-                Log.e(TAG, "Failed to start hotword recognition", ex);
-                sHotwordClient = null;
-            }
-        }
-    }
-
-    /**
-     * Stop hotword detector if HOTWORDING_ENABLED is true.
-     */
-    private void maybeStopHotwordDetector() {
-        if (ENABLE_HOTWORD && sHotwordClient != null) {
-            if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()");
-            try {
-                sHotwordClient.stopRecognition();
-            } catch(Exception ex) {
-                // Don't allow hotword errors to make the keyguard unusable
-                Log.e(TAG, "Failed to start hotword recognition", ex);
-            } finally {
-                sHotwordClient = null;
-            }
-        }
-    }
-
-    private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() {
-        private static final String TAG = "HotwordRecognitionListener";
-
-        public void onHotwordRecognitionStarted() {
-            if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()");
-        }
-
-        public void onHotwordRecognitionStopped() {
-            if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()");
-        }
-
-        public void onHotwordEvent(int eventType, Bundle eventBundle) {
-            if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType);
-            if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) {
-                if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) {
-                    mSecurityMessageDisplay.setMessage(
-                            eventBundle.getString(HotwordRecognizer.PROMPT_TEXT), true);
-                }
-            }
-        }
-
-        public void onHotwordRecognized(PendingIntent intent) {
-            if (DEBUG) Log.d(TAG, "onHotwordRecognized");
-            maybeStopHotwordDetector();
-            if (intent != null) {
-                try {
-                    intent.send();
-                } catch (PendingIntent.CanceledException e) {
-                    Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException");
-                }
-            }
-            mCallback.userActivity(0);
-            mCallback.dismiss(false);
-        }
-
-        public void onHotwordError(int errorCode) {
-            if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode);
-            // TODO: Inspect the error code and handle the errors appropriately
-            // instead of blindly failing.
-            maybeStopHotwordDetector();
-        }
-    };
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index 597fb3b..e746f72 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -153,8 +153,6 @@
     private AlarmManager mAlarmManager;
     private AudioManager mAudioManager;
     private StatusBarManager mStatusBarManager;
-    private boolean mShowLockIcon;
-    private boolean mShowingLockIcon;
     private boolean mSwitchingUser;
 
     private boolean mSystemReady;
@@ -494,7 +492,6 @@
                 mLockPatternUtils);
 
         final ContentResolver cr = mContext.getContentResolver();
-        mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1);
 
         mScreenOn = mPM.isScreenOn();
 
@@ -1227,25 +1224,6 @@
         if (mStatusBarManager == null) {
             Log.w(TAG, "Could not get status bar manager");
         } else {
-            if (mShowLockIcon) {
-                // Give feedback to user when secure keyguard is active and engaged
-                if (mShowing && isSecure()) {
-                    if (!mShowingLockIcon) {
-                        String contentDescription = mContext.getString(
-                                com.android.internal.R.string.status_bar_device_locked);
-                        mStatusBarManager.setIcon("secure",
-                                com.android.internal.R.drawable.stat_sys_secure, 0,
-                                contentDescription);
-                        mShowingLockIcon = true;
-                    }
-                } else {
-                    if (mShowingLockIcon) {
-                        mStatusBarManager.removeIcon("secure");
-                        mShowingLockIcon = false;
-                    }
-                }
-            }
-
             // Disable aspects of the system/status/navigation bars that must not be re-enabled by
             // windows that appear on top, ever
             int flags = StatusBarManager.DISABLE_NONE;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 6753922..a5dab33 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -33,6 +33,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
 import android.content.res.AssetFileDescriptor;
 import android.database.AbstractCursor;
 import android.database.Cursor;
@@ -477,6 +478,13 @@
         try {
             final String value = c.moveToNext() ? c.getString(0) : null;
             if (value == null) {
+                // sanity-check the user before touching the db
+                final UserInfo user = mUserManager.getUserInfo(userHandle);
+                if (user == null) {
+                    // can happen due to races when deleting users; treat as benign
+                    return false;
+                }
+
                 final SecureRandom random = new SecureRandom();
                 final String newAndroidIdValue = Long.toHexString(random.nextLong());
                 final ContentValues values = new ContentValues();
@@ -490,7 +498,7 @@
                 Slog.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue
                         + "] for user " + userHandle);
                 // Write a dropbox entry if it's a restricted profile
-                if (mUserManager.getUserInfo(userHandle).isRestricted()) {
+                if (user.isRestricted()) {
                     DropBoxManager dbm = (DropBoxManager)
                             getContext().getSystemService(Context.DROPBOX_SERVICE);
                     if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png
index 7056abeb..c561446 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png
index b55b441..7570610 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png
index a2863642..0df2411 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png
index 7494147..8b6ecc2 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
index 2bb9fd6..432b166 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
index 594e5e2..aa071c77 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
index 7dce473..194698a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
index d005e04..0b4b368 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
index 7a7e4b6..8887f2e0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
index c5b1c78..87c3244 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
index 40b20ae..8206cd8 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
index f0553cd..293f88c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
index 8712938..cb9c8ac 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
index 8442a51..88eafcb 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
deleted file mode 100644
index f3756ab..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 7fbdd59..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
deleted file mode 100644
index 7520e2d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_sync_error.png
deleted file mode 100644
index 70f839f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
deleted file mode 100644
index 108972d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index bd40687..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
deleted file mode 100644
index 7ecf801..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
index a2bb4d6..13f6b7f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
index a528b94..ecdb240 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png
index 6872ec8..f3e9da2 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png
index 98520d3..a90aef9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png
index 44d1afb..5171333 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_in.png
deleted file mode 100644
index 4f97e34..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 2a3bb84..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_out.png
deleted file mode 100644
index e14818b..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
index 8f6f7b5..c98911c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
index 8d2f5a2..bb99022 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png
index 66b4741..b05bf78 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png
index f8abf25..2f782cf 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png
index 9070357..1b45762 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_in.png
deleted file mode 100644
index e275f6a..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 1ab14f4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_out.png
deleted file mode 100644
index c8fccba..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
index aa87849..d9d8b13 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
index 634a0115..09e0a3c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png
index 629b5f8..8299301 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png
index 8e3e8b4..e171d53 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png
index 9ede64c..fcbfac1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_in.png
deleted file mode 100644
index 79a4bf9..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 442a6c0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_out.png
deleted file mode 100644
index 8c5cd8f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
index 60579f9..c0855b5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
index abb9b18..e3fb992 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_silent.png
similarity index 66%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_silent.png
index 1480682..1c847da2 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_vibrate.png
similarity index 64%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_vibrate.png
index 1480682..d0ab910 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_flightmode.png
similarity index 69%
copy from packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
copy to packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_flightmode.png
index 1480682..4555731 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_inout.png
deleted file mode 100644
index e90b0a7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_out.png
deleted file mode 100644
index bf61435..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png
index 273acd2..e285bba 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png
index 60849b8..7c73ace 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png
index 9b09e13..c6f41d2 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png
index 5875419..021ae6d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png
index 71862ff..e5a8f95 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png
index a30bea6..c1c2b5c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png
index 0791dd2..421eee8 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png
index 988a3ab..bfd2494 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png
index 3fab095..b1af6786 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png
index 179bd5c..9ad245b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png
index 6c5e397..69a1a97 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
index 5232f82..d865673 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
index fd7c4b5..6bd3189 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png
index 52f89dd..f7f0e93 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
index 876d9ee..cb38896 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
deleted file mode 100644
index e6d1e90..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
deleted file mode 100644
index c1e8095..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
deleted file mode 100644
index 9726124..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_sync_error.png
deleted file mode 100644
index 6db607d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
deleted file mode 100644
index be00a90..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index 0fc02ae..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
deleted file mode 100644
index 5c80022..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png
index 35a27da..a52dc8d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_off.png
new file mode 100644
index 0000000..466470c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_on.png
new file mode 100644
index 0000000..77c3ec0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png
index 2c44011..e888ac2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png
index ecbe583..f64d582 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png
index ddd955e..31f5b90 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png
index 0d2eafe..881d5e8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png
index 72bbbd5..2d80c4d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png
index 285ded6..ad85c83 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png
index 6533b5e..bde43c6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png
index 5d4b982..914ac49 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
index 8b3c4a6..c83e9fe 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
index da99575..48bca90 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png
index 0c15847..15514340 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png
index fbec7c3..f0c2f05 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
deleted file mode 100644
index 429fcbe..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
deleted file mode 100644
index dc5e5b6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
deleted file mode 100644
index cdc2fd9..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync_error.png
deleted file mode 100644
index 6276f47..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png
index d28972f..8c48af4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
deleted file mode 100644
index 0a30a19..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index 4b6f647..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
deleted file mode 100644
index 1bd4154..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png
index 79dbdbf..3175636 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_off.png
new file mode 100644
index 0000000..920407d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_on.png
new file mode 100644
index 0000000..3175636
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png
index 4cf6794..d1a72be 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png
index 77ec7e4..21daf5c 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png
index b1d4eb0..3397570 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png
index 537725e..87039c5 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png
index 041e5d7..a21f3c4 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png
index b98f4e50..65b323f 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png
index 196c23d..c5c3550 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png
index a3d07bb..801cb3c 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
index c93de67..149d227 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
index c487d61..6edb37a 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png
index 6f96ba3..2b01e9b 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png
index 9de3e9f..1c544c4 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_in.png
deleted file mode 100644
index ab3a4c8..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 1c84c2d..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_out.png
deleted file mode 100644
index 09f21f7..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_sync_error.png
deleted file mode 100644
index 2f6a4c0..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_tty_mode.png
new file mode 100644
index 0000000..075208a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_in.png
deleted file mode 100644
index 0f5b5ef..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index 3121176..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_out.png
deleted file mode 100644
index 27863686..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 66b06ef..2b9cef91 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -39,12 +39,6 @@
             android:layout_centerVertical="true"
             android:scaleType="center"
             />
-        <ImageView
-            android:id="@+id/wifi_inout"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_gravity="center|bottom"
-            />
     </FrameLayout>
     <View
         android:layout_height="6dp"
@@ -66,12 +60,6 @@
             android:layout_centerVertical="true"
             android:scaleType="center"
             />
-        <ImageView
-            android:id="@+id/wimax_inout"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_gravity="center|bottom"
-            />
     </FrameLayout>
     -->
     <FrameLayout
@@ -98,12 +86,6 @@
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 />
-            <ImageView
-                android:id="@+id/mobile_inout"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_gravity="end|bottom"
-                />
         </FrameLayout>
     </FrameLayout>
     <ImageView
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 6835151..28128da 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Draadlose aansig"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Kennisgewings verskyn hier"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Verkry enige tyd toegang tot hulle deur af te sleep.\nSleep weer af vir stelselkontroles."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan dalk gemonitor word"</string>
     <string name="done_button" msgid="1759387181766603361">"Klaar"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Netwerkmonitering"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 47d36b0..40479b5 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ገመድ አልባ ማሳያ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ብሩህነት"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ራስ-ሰር"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"ማሳወቂያዎች እዚህ ላይ ይታያሉ"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"ወደ ታች በማንሸራተት በማንኛውም ጊዜ ይድረሱባቸው።\nSwipe የስርዓት መቆጣጠሪያዎችን ለማምጣት እንደገና ወደ ታች ያንሸራትቱ።"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"አውታረ መረብ በክትትል ውስጥ ሊሆን ይችላል"</string>
     <string name="done_button" msgid="1759387181766603361">"ተከናውኗል"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"የአውታረ መረብ ክትትል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index fcc4696..93a9164 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"عرض شاشة لاسلكي"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"السطوع"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"تلقائي"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"تظهر الإشعارات هنا"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"يمكنك الدخول إليها في أي وقت بالتمرير السريع إلى أسفل.\nيمكنك التمرير السريع إلى أسفل مرة أخرى للوصول إلى عناصر تحكم النظام."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"قد تكون الشبكة مراقبة"</string>
     <string name="done_button" msgid="1759387181766603361">"تم"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"مراقبة الشبكات"</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index cb48aa0..9565eee 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Simsiz Ekran"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaqlıq"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AVTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Bildirişlər burada görünür"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Aşağı sürüşdürməklə istənilən vaxt onları əldə edin.\nSistemi nəzarəti üçün yenə də aşağı sürüşdürün."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Şəbəkə monitor edilə bilər"</string>
     <string name="done_button" msgid="1759387181766603361">"Hazırdır"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Şəbəkə Monitorinqi"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 29eed4e..eb455c1 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -202,8 +202,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Бесправадны дысплей"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркасць"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АЎТА"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Апавяшчэнні з\'яўляюцца тут"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Атрымлівайце доступ да іх у любы час, праводзячы пальцам уніз.\nПравядзіце пальцам уніз яшчэ раз, каб атрымаць доступ да сродкаў кіравання сістэмай."</string>
     <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
     <skip />
     <!-- no translation found for done_button (1759387181766603361) -->
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index dbb12a5..e839143 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Безжичен дисплей"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркост"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТ."</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Известията се показват тук"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Осъществявайте достъп до тях по всяко време, като прекарате пръст надолу.\nНаправете го отново за системните контроли."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежата може да се наблюдава"</string>
     <string name="done_button" msgid="1759387181766603361">"Готово"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Наблюдение на мрежата"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d9a5731..f3b7714 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla sense fil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillantor"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Les notificacions apareixen aquí"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accedeix-hi en qualsevol moment: només has de fer lliscar el dit cap avall.\nTorna a fer lliscar el dit cap avall per fer que es mostrin els controls del sistema."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Pot ser que la xarxa se supervisi."</string>
     <string name="done_button" msgid="1759387181766603361">"Fet"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Supervisió de xarxes"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c8793c6..5977c35 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrátový displej"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Zde se zobrazují oznámení"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Můžete je kdykoli zobrazit tím, že přejedete prstem dolů.\nPřejedete-li prstem dolů ještě jednou, zobrazí se ovládací prvky systému."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Síť může být monitorována"</string>
     <string name="done_button" msgid="1759387181766603361">"Hotovo"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitorování sítě"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index a656783..08c42d0 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådløs skærm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Underretninger vises her"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Få adgang til dem når som helst ved at stryge ned.\nStryg ned igen for at komme til systemindstillingerne."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netværket kan være overvåget"</string>
     <string name="done_button" msgid="1759387181766603361">"Udfør"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Overvågning af netværk"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index df0913b..8b52a11 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kabellose Übertragung (WiDi)"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helligkeit"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Benachrichtigungen erscheinen hier"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Greifen Sie jederzeit auf sie zu, indem Sie nach unten wischen.\nWischen Sie für Systemeinstellungen erneut nach unten."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Das Netzwerk wird möglicherweise überwacht."</string>
     <string name="done_button" msgid="1759387181766603361">"Fertig"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Netzwerküberwachung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c109924..c437eb6 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ασύρματη οθόνη"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Φωτεινότητα"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Οι ειδοποιήσεις εμφανίζονται εδώ"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Μεταβείτε σε αυτές ανά πάσα στιγμή σύροντας προς τα κάτω.\nΣύρετε ξανά προς τα κάτω για τα στοιχεία ελέγχου συστήματος."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
     <string name="done_button" msgid="1759387181766603361">"Τέλος"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Παρακολούθηση δικτύου"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 5fc3760..5255c44 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Notifications appear here"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Access them any time by swiping down.\nSwipe down again for system controls."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
     <string name="done_button" msgid="1759387181766603361">"Finished"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Network Monitoring"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 5fc3760..5255c44 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Notifications appear here"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Access them any time by swiping down.\nSwipe down again for system controls."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
     <string name="done_button" msgid="1759387181766603361">"Finished"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Network Monitoring"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 91da585..f5b2df7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí."</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido.\nVuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada."</string>
     <string name="done_button" msgid="1759387181766603361">"Listo"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Supervisión de red"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 9019b82..b81b487 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido.\nVuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada"</string>
     <string name="done_button" msgid="1759387181766603361">"Listo"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Supervisión de red"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index cde1240..69da334 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Juhtmeta ekraaniühendus"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Heledus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Märguanded ilmuvad siia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Juurdepääs igal ajal sõrmega alla pühkides.\nSüsteemi juhtnuppude jaoks pühkige uuesti alla."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Võrku võidakse jälgida"</string>
     <string name="done_button" msgid="1759387181766603361">"Valmis"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Võrgu jälgimine"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 50733be..412e749 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"نمایش بدون سیم"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"روشنایی"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"اعلان‌ها در اینجا نمایش داده می‌شوند"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"با کشیدن انگشت به طرف پایین به آنها دسترسی پیدا کنید.\nبرای کنترل‌های سیستم دوباره انگشت خود را به سمت پایین بکشید."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ممکن است شبکه نظارت شده باشد"</string>
     <string name="done_button" msgid="1759387181766603361">"انجام شد"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"پایش شبکه"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 915ba23..dbd228e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Langaton näyttö"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kirkkaus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Ilmoitukset näkyvät tässä"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Näet ilmoitukset liu\'uttamalla sormea alas ruudulla.\nVoit palauttaa järjestelmän ohjaimet näkyviin liu\'uttamalla sormea alas uudelleen."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Verkkoa saatetaan valvoa"</string>
     <string name="done_button" msgid="1759387181766603361">"Valmis"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Verkon valvonta"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 584e8b2..6071659 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Affichage sans fil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Les notifications s’affichent ici"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accédez-y à tout moment en faisant glisser le doigt vers le bas.\nRépétez l\'opération pour accéder aux commandes du système."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Le réseau peut être surveillé"</string>
     <string name="done_button" msgid="1759387181766603361">"Terminé"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Surveillance réseau"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a96ea07..4982ed3 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Affichage sans fil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Les notifications s’affichent ici"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accédez-y à tout moment en faisant glisser le doigt vers le bas.\nRépétez l\'opération pour accéder aux commandes du système."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Il est possible que le réseau soit surveillé."</string>
     <string name="done_button" msgid="1759387181766603361">"OK"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Surveillance du réseau"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 0003133..91d4a96 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -169,7 +169,7 @@
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"स्‍क्रीन लैंडस्केप अभिविन्यास में लॉक है."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"स्‍क्रीन पोर्ट्रेट अभिविन्‍यास में लॉक है."</string>
     <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
-    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"दिवास्वप्न"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ईथरनेट"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"हवाई जहाज़ मोड"</string>
     <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"चार्ज हो रही है, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"वायरलेस डिस्प्ले"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"चमक"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वत:"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"सूचनाएं यहां दिखाई देती हैं"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"नीचे स्वाइप करके उन तक कभी भी पहुंचें.\nसिस्टम नियंत्रणों के लिए पुन: नीचे स्वाइप करें."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
     <string name="done_button" msgid="1759387181766603361">"पूर्ण"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"नेटवर्क मॉनिटरिंग"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b9a5e1b..92e1b21 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bežični prikaz"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svjetlina"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKI"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Obavijesti se prikazuju ovdje"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Pristupite im u bilo kojem trenutku tako da prstom trznete prema dolje. \nPonovo prstom trznite prema dolje za kontrole sustava."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mreža se možda nadzire"</string>
     <string name="done_button" msgid="1759387181766603361">"Završeno"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Nadzor mreže"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 32d3abe..ad9c7b7 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Vezeték nélküli kijelző"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Fényerő"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Az értesítések itt jelennek meg."</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Bármikor elérheti őket, ha lefelé húzza az ujját.\nHúzza le az ujját még egyszer a rendszerbeállítások eléréséhez."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Lehet, hogy a hálózat felügyelt"</string>
     <string name="done_button" msgid="1759387181766603361">"Kész"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Hálózatfelügyelet"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 25af411..06b897a 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Անլար էկրան"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Պայծառություն"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Ինքնաշխատ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Ծանուցումները հայտնվում են այստեղ"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Դրանք մատչեք ցանկացած պահի` սահահարվածելով:\nԿրկին սահահարվածեք ներքև` համակարգային կառավարման համար:"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ցանցը կարող է վերահսկվել"</string>
     <string name="done_button" msgid="1759387181766603361">"Պատրաստ է"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Ցանցի մշտադիտարկում"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index fdbcbcc..3af3a34 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Layar Nirkabel"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATIS"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan muncul di sini"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Akses kapan saja dengan menggesek ke bawah.\nGesek ke bawah sekali lagi untuk kontrol sistem."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Jaringan mungkin dipantau"</string>
     <string name="done_button" msgid="1759387181766603361">"Selesai"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Pemantauan Jaringan"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 37ef6c2..d936e5f 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Visualizzazione wireless"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosità"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Le notifiche vengono visualizzate qui"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Puoi accedervi in qualsiasi momento scorrendo verso il basso.\nFai scorrere di nuovo verso il basso per visualizzare i controlli del sistema."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"La rete potrebbe essere monitorata"</string>
     <string name="done_button" msgid="1759387181766603361">"Fine"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitoraggio rete"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 6b87d92..3b5080e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"תצוגת Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"בהירות"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"הודעות מופיעות כאן"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"גש אליהם בכל עת על ידי החלקה למטה.\nהחלק למטה שוב למעבר למרכז הבקרה של המערכת."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ייתכן שהרשת מנוטרת"</string>
     <string name="done_button" msgid="1759387181766603361">"בוצע"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ניטור רשתות"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 1c0093c..f42dd16 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ワイヤレスディスプレイ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"画面の明るさ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"ここに通知が表示されます"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"下にスワイプすると、いつでも通知を表示できます。\nシステムを管理するにはもう一度下にスワイプしてください。"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ネットワークが監視される場合があります"</string>
     <string name="done_button" msgid="1759387181766603361">"完了"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ネットワーク監視"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 2349c32..b9963d5 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -42,7 +42,7 @@
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"თვითმფრინავის რეჟიმი"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"ავტოროტაციის ეკრანი"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"დადუმება"</string>
-    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ავტომატური"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ავტო."</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"შეტყობინებები"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth მიერთებულია."</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"შეყვანის მეთოდების დაყენება"</string>
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"უსადენო ეკრანი"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"განათება"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ავტომატურად"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"შეტყობინებები აქ გამოჩნდება"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"მათზე წვდომისათვის, ნებისმიერ დროს გადაფურცლეთ ქვემოთ.\nსისტემის კონტროლისთვისაც გადაფურცლეთ ქვემოთ."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"შესაძლოა ქსელი მონიტორინგის ქვეშ იმყოფება"</string>
     <string name="done_button" msgid="1759387181766603361">"დასრულდა"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ქსელის მონიტორინგი"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 8fb09ad..211c286 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"​បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ពន្លឺ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ស្វ័យប្រវត្តិ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"ការ​ជូន​ដំណឹង​​បង្ហាញ​​នៅ​ទីនេះ"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"ចូល​ដំណើរការ​ពួក​វា​ពេល​ណា​មួយ​ដោយ​អូស​ចុះក្រោម។\nអូស​ចុះក្រោម​ម្ដង​ទៀត​ ដើម្បី​ពិនិត្យ​ប្រព័ន្ធ។"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"បណ្ដាញ​អាច​ត្រូវ​បាន​តាមដាន"</string>
     <string name="done_button" msgid="1759387181766603361">"រួចរាល់"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ការ​ពិនិត្យ​បណ្ដាញ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5472235..3b37888 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"무선 디스플레이"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"밝기"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"자동"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"알림이 여기에 표시됨"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"아래로 스와이프하여 언제든 액세스하세요.\n한 번 더 아래로 스와이프하면 시스템 관리로 이동합니다."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"네트워크가 모니터링될 수 있음"</string>
     <string name="done_button" msgid="1759387181766603361">"완료"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"네트워크 모니터링"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index e17396f..968fee4 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ການສະແດງຜົນໄຮ້ສາຍ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ຄວາມແຈ້ງ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ອັດຕະໂນມັດ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"ການແຈ້ງເຕືອນຈະປາກົດບ່ອນນີ້"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"ເຂົ້າເຖິງໄດ້ທຸກເມື່ອໂດຍການປັດນິ້ວລົງ.\nປັດລົງອີກເທື່ອນຶ່ງສຳລັບການຄວບຄຸມລະບົບ."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ການນຳໃຊ້ເຄືອຂ່າຍອາດມີການກວດສອບຕິດຕາມ"</string>
     <string name="done_button" msgid="1759387181766603361">"ແລ້ວໆ"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ການກວດສອບຕິດຕາມເຄືອຂ່າຍ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ddafcb3..b0693d5 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Belaidis rodymas"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Skaistis"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATINIS"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Pranešimai rodomi čia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Perbraukę žemyn bet kuriuo metu pasieksite pranešimus.\nJei norite naudoti sistemos valdiklius, perbraukite žemyn dar kartą."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Tinklas gali būti stebimas"</string>
     <string name="done_button" msgid="1759387181766603361">"Atlikta"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Tinklo stebėjimas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0a04619..b18bd6c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezvadu attēlošana"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Spilgtums"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMĀTISKI"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Šeit tiek rādīti paziņojumi"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Piekļūstiet tiem jebkurā laikā, velkot uz leju.\nVēlreiz velciet, lai tiktu parādītas sistēmas vadīklas."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Iespējams, tīklā veiktās darbības tiek pārraudzītas."</string>
     <string name="done_button" msgid="1759387181766603361">"Gatavs"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Tīkla pārraudzība"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index aea7be1..e5d2af3 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Утасгүй дэлгэц"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Тодрол"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОМАТ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Мэдэгдэл энд харагдана"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Доош татаад тэдгээрт хандана уу.\nДахин доош татаад систем контролд хандана уу."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Сүлжээ хянагдаж байж болзошгүй"</string>
     <string name="done_button" msgid="1759387181766603361">"Дууссан"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Сүлжээний Хяналт"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index bcc3e48..40468f5 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Paparan Wayarles"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan dipaparkan di sini"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Akses panel pada bila-bila masa dengan meleret ke bawah.\nLeret ke bawah sekali lagi untuk mendapatkan kawalan sistem."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rangkaian mungkin dipantau"</string>
     <string name="done_button" msgid="1759387181766603361">"Selesai"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Pemantauan Rangkaian"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 6da69fb..cd463c8 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådløs skjerm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Varslene vises her"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Bruk dem når som helst ved å sveipe nedover.\nSveip nedover igjen for å gå til systemkontrollene."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nettverket blir muligens overvåket"</string>
     <string name="done_button" msgid="1759387181766603361">"Fullført"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Nettverksovervåking"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 18dc0f9..19e2744 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -171,7 +171,7 @@
     <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
     <string name="start_dreams" msgid="7219575858348719790">"दिवासपना"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
-    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"उडान मोड"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"हवाइजहाज मोड"</string>
     <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"चार्ज हुँदै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"चार्ज भयो"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ब्लुटुथ"</string>
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ताररहित प्रदर्शन"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"उज्यालपन"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वतः"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"यहाँ जानकारीहरू देखा पर्छन्"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"तल हुत्त्याएर तिनीहरूलाई सधैं पहुँच गर्नुहोस्\nप्रणाली नियन्त्रणको लागि पुनः तल हुत्त्याउनुहोस्"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"सञ्जाल अनुगमित हुन सक्छ"</string>
     <string name="done_button" msgid="1759387181766603361">"भयो"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"सञ्जाल निगरानी"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7e0d87a..0996392 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Draadloze display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Meldingen worden hier weergegeven"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"U kunt de meldingen op elk gewenst moment openen door met uw vinger omlaag te vegen.\nVeeg nogmaals met uw vinger omlaag om de systeembesturingselementen weer te geven."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan worden gecontroleerd"</string>
     <string name="done_button" msgid="1759387181766603361">"Gereed"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Netwerkcontrole"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 9bcfb10..c3476e5 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wyświetlacz bezprzewodowy"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jasność"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATYCZNA"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Tutaj pokazują się powiadomienia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Możesz je otworzyć w dowolnej chwili, przesuwając w dół.\nPrzesuń jeszcze raz w dół, by otworzyć ustawienia systemowe."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieć może być monitorowana"</string>
     <string name="done_button" msgid="1759387181766603361">"Gotowe"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitorowanie sieci"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 735733f..dac070f 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Display Sem Fios"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"As notificações são apresentadas aqui"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Pode aceder em qualquer altura, deslizando rapidamente para baixo com o dedo.\nDeslize novamente para baixo para aceder aos controlos do sistema."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorizada"</string>
     <string name="done_button" msgid="1759387181766603361">"Concluído"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitorização da Rede"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 1dbf90e..711956e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Display sem fio"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"As notificações aparecem aqui"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Acesse a qualquer momento deslizando para baixo.\nDeslize para baixo novamente para acessar os controles do sistema."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorada"</string>
     <string name="done_button" msgid="1759387181766603361">"Concluído"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitoramento de rede"</string>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 54ae2da..0a5689c 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -364,10 +364,6 @@
     <skip />
     <!-- no translation found for quick_settings_brightness_dialog_auto_brightness_label (5064982743784071218) -->
     <skip />
-    <!-- no translation found for status_bar_help_title (1199237744086469217) -->
-    <skip />
-    <!-- no translation found for status_bar_help_text (7874607155052076323) -->
-    <skip />
     <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
     <skip />
     <!-- no translation found for done_button (1759387181766603361) -->
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 42d06c3..0b93f57 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ecran wireless"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminozitate"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Notificările se afişează aici"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accesaţi-le oricând glisând în jos.\nGlisaţi în jos din nou pentru comenzile sistemului."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rețeaua poate fi monitorizată"</string>
     <string name="done_button" msgid="1759387181766603361">"Terminat"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitorizarea rețelei"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 215467a..520ffb4 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -201,8 +201,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wi-Fi-монитор"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркость"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Это панель уведомлений"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Ее можно открыть, пролистнув экран вниз.\nЧтобы открыть настройки, проведите пальцем вниз ещё раз."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Действия в сети могут отслеживаться"</string>
     <string name="done_button" msgid="1759387181766603361">"Готово"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Мониторинг сети"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index cbf3400..24accd1 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"නොරැහැන් සංදර්ශකය"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"දීප්තිමත් බව"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ස්වයංක්‍රීය"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"දැනුම්දීම් මෙතන පෙන්නුම් කරයි"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"පහලට සර්පණය කිරීමෙන් ඕනෑම වෙලාවක ඒවා වෙත පිවිසෙන්න.\nපද්ධති පාලක සඳහා නැවත පහළට සර්පණය කරන්න."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
     <string name="done_button" msgid="1759387181766603361">"හරි"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ජාල නිරීක්ෂණය කිරීම"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c708bce..d036f0e 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrôtový displej"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Tu sa zobrazujú upozornenia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Môžete ich kedykoľvek zobraziť tak, že posuniete prstom nadol.\nAk posuniete prstom nadol ešte raz, zobrazia sa ovládacie prvky systému."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieť môže byť monitorovaná"</string>
     <string name="done_button" msgid="1759387181766603361">"Hotovo"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Monitorovanie siete"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b19e6e0..e0b215a 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Prikaz brezžičnih naprav"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svetlost"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SAMODEJNO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Obvestila so prikazana tukaj"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Do njih lahko kadar koli dostopate tako, da povlečete navzdol.\nZa prikaz sistemskih kontrolnikov znova povlecite navzdol."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Omrežje je lahko nadzorovano"</string>
     <string name="done_button" msgid="1759387181766603361">"Dokončano"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Nadzor omrežja"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 216dc0a..84d72df 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Бежични екран"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Осветљеност"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АУТОМАТСКА"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Обавештења се појављују овде"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Приступите им у било ком тренутку листањем надоле.\nПоново листајте надоле да би се приказале системске контроле."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежа се можда надгледа"</string>
     <string name="done_button" msgid="1759387181766603361">"Готово"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Надгледање мреже"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 3b488a3..d27c9e4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös skärm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Meddelanden visas här"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Du kommer åt dem när som helst genom att dra nedåt.\nDra nedåt igen om du vill visa systemkontroller."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nätverket kan vara övervakat"</string>
     <string name="done_button" msgid="1759387181766603361">"Klart"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Nätverksövervakning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3f2ac75..d3ac4c2 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -128,7 +128,7 @@
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Hakuna SIM."</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Shiriki intaneti kwa Bluetooth."</string>
-    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modi ya ndege."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Hali ya ndege."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Asilimia <xliff:g id="NUMBER">%d</xliff:g> ya betri"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Mipangilio ya mfumo."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Arifa."</string>
@@ -169,7 +169,7 @@
     <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Hali Tulivu"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
-    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modi ya ndege"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Hali ya ndege"</string>
     <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Inachaji, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Imechajiwa"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
@@ -195,8 +195,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Uonyeshaji Pasiwaya"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ung\'avu"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Arifa zitaonekana hapa"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Zifikie wakati wowote kwa kutelezesha chini.\nTelezesha chini tena kupata vidhibiti vya mfumo."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mtandao unaweza kufuatiliwa"</string>
     <string name="done_button" msgid="1759387181766603361">"Imekamilika"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Ufuatiliaji wa Mtandao"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index d1f4660..2eb8896 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"จอแสดงผลไร้สาย"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ความสว่าง"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"อัตโนมัติ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"การแจ้งเตือนจะแสดงขึ้นที่นี่"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"เข้าถึงได้ทุกเมื่อด้วยการกวาดนิ้วลง\nกวาดนิ้วลงอีกครั้งสำหรับการควบคุมระบบ"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"เครือข่ายอาจได้รับการตรวจสอบ"</string>
     <string name="done_button" msgid="1759387181766603361">"เสร็จสิ้น"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"การตรวจสอบเครือข่าย"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 99a4815..69b5aff 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Dito lumalabas ang mga notification"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"I-access ang mga ito anumang oras sa pamamagitan ng pag-swipe pababa.\nMuling mag-swipe pababa para sa mga kontrol ng system."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Maaaring sinusubaybayan ang network"</string>
     <string name="done_button" msgid="1759387181766603361">"Tapos na"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Pagsubaybay sa Network"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 9ac21e9..67e2be2 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kablosuz Ekran"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaklık"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATİK"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Bildirimler burada görünür"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Aşağıya hızlıca kaydırarak bunlara istediğiniz zaman erişebilirsiniz.\nSistem denetimleri için tekrar hızlıca aşağı kaydırın."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ağ izlenebilir"</string>
     <string name="done_button" msgid="1759387181766603361">"Bitti"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Ağ İzleme"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 6fb2b14..527525e 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Бездротове відображення"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яскравість"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Сповіщення з’являються тут"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Отримуйте до них доступ будь-коли, провівши пальцем униз.\nЗнову проведіть униз, щоб відкрити елементи керування системи."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мережу можуть відстежувати"</string>
     <string name="done_button" msgid="1759387181766603361">"Готово"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Відстеження мережі"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 54897bb..4be1bf0 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Hiển thị không dây"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Độ sáng"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"TỰ ĐỘNG"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Thông báo xuất hiện tại đây"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Truy cập vào chúng bất kỳ lúc nào bằng cách vuốt xuống.\nVuốt lại xuống để hiển thị các điều khiển hệ thống."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mạng có thể được giám sát"</string>
     <string name="done_button" msgid="1759387181766603361">"Xong"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Giám sát mạng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c9710cc..1093d0c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"无线显示"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"通知会显示在这里"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"向下滑动可随时查看通知。\n再次向下滑动可使用系统控制功能。"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"网络可能会受到监控"</string>
     <string name="done_button" msgid="1759387181766603361">"完成"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"网络监控"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 1e77635..daef9d2 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"無線顯示"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"通知會在這裡顯示"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"向下快速滑動可隨時存取通知。\n再次向下快速滑動則可使用系統控制介面。"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網絡可能會受到監控"</string>
     <string name="done_button" msgid="1759387181766603361">"完成"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"網絡監控"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e10c6d8..73871c6 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -199,8 +199,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"無線螢幕分享"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"系統會在這裡顯示通知"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"向下滑動即可隨時存取通知。\n再次向下滑動即可使用系統控制項。"</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網路可能會受到監控"</string>
     <string name="done_button" msgid="1759387181766603361">"完成"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"網路監控"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 296e65e..4dfad2f 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -197,8 +197,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ukubonisa okungenazintambo"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ukugqama"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Izaziso zivela lapha"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Kufinyelele noma kunini ngokuswayiphela phansi.\nSwayiphela phansi futhi ngezilawuli zesistimu."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Inethiwekhi ingase inganyelwe"</string>
     <string name="done_button" msgid="1759387181766603361">"Kwenziwe"</string>
     <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Ukwenganyelwa kwenethiwekhi"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f58872a..2c06aec 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,7 +20,7 @@
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="status_bar_background">#ff000000</drawable>
-    <color name="status_bar_background_semi_transparent">#55000000</color>
+    <color name="status_bar_background_semi_transparent">#66000000</color>
     <color name="status_bar_background_transparent">#00000000</color>
     <color name="navigation_bar_background_transparent_start">#7f000000</color>
     <color name="navigation_bar_background_transparent_end">#00000000</color>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 1165b8d..6a0f6e3 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -29,11 +29,12 @@
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.os.BatteryManager;
+import android.os.Bundle;
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.View;
 
-public class BatteryMeterView extends View {
+public class BatteryMeterView extends View implements DemoMode {
     public static final String TAG = BatteryMeterView.class.getSimpleName();
     public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
 
@@ -204,7 +205,6 @@
     }
 
     private int getColorForLevel(int percent) {
-        if (mTracker.plugged) return mChargeColor;
         int thresh, color = 0;
         for (int i=0; i<mColors.length; i+=2) {
             thresh = mColors[i];
@@ -216,7 +216,8 @@
 
     @Override
     public void draw(Canvas c) {
-        final int level = mTracker.level;
+        BatteryTracker tracker = mDemoMode ? mDemoTracker : mTracker;
+        final int level = tracker.level;
         float drawFrac = (float) level / 100f;
         final int pt = getPaddingTop();
         final int pl = getPaddingLeft();
@@ -245,8 +246,8 @@
         c.drawRect(frame, mFramePaint);
 
         // fill 'er up
-        final int pct = mTracker.level;
-        final int color = getColorForLevel(pct);
+        final int pct = tracker.level;
+        final int color = tracker.plugged ? mChargeColor : getColorForLevel(pct);
         mBatteryPaint.setColor(color);
 
         if (level >= FULL) {
@@ -270,16 +271,16 @@
             final float x = mWidth * 0.5f;
             final float y = (mHeight + mWarningTextHeight) * 0.48f;
             c.drawText(mWarningString, x, y, mWarningTextPaint);
-        } else if (mTracker.plugged) {
+        } else if (tracker.plugged) {
             final Rect r = new Rect(
                     (int)frame.left + width / 4,  (int)frame.top + height / 5,
                     (int)frame.right - width / 4, (int)frame.bottom - height / 6);
             mLightning.setBounds(r);
             mLightning.draw(c);
-        } else if (mShowPercent && !(mTracker.level == 100 && !SHOW_100_PERCENT)) {
+        } else if (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
             mTextPaint.setTextSize(height *
                     (SINGLE_DIGIT_PERCENT ? 0.75f
-                            : (mTracker.level == 100 ? 0.38f : 0.5f)));
+                            : (tracker.level == 100 ? 0.38f : 0.5f)));
             mTextHeight = -mTextPaint.getFontMetrics().ascent;
 
             final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (pct/10) : pct);
@@ -302,4 +303,29 @@
 //            c.drawRect(1, 1, mWidth, mHeight, pt);
         }
     }
+
+    private boolean mDemoMode;
+    private BatteryTracker mDemoTracker = new BatteryTracker();
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+            mDemoTracker.level = mTracker.level;
+            mDemoTracker.plugged = mTracker.plugged;
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            postInvalidate();
+        } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
+           String level = args.getString("level");
+           String plugged = args.getString("plugged");
+           if (level != null) {
+               mDemoTracker.level = Math.min(Math.max(Integer.parseInt(level), 0), 100);
+           }
+           if (plugged != null) {
+               mDemoTracker.plugged = Boolean.parseBoolean(plugged);
+           }
+           postInvalidate();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java
new file mode 100644
index 0000000..8d271e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DemoMode.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.os.Bundle;
+
+public interface DemoMode {
+
+    void dispatchDemoCommand(String command, Bundle args);
+
+    public static final String ACTION_DEMO = "com.android.systemui.demo";
+
+    public static final String COMMAND_ENTER = "enter";
+    public static final String COMMAND_EXIT = "exit";
+    public static final String COMMAND_CLOCK = "clock";
+    public static final String COMMAND_BATTERY = "battery";
+    public static final String COMMAND_NETWORK = "network";
+    public static final String COMMAND_BARS = "bars";
+    public static final String COMMAND_STATUS = "status";
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index e32d7f2..ff85cb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -70,7 +70,6 @@
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SearchPanelView;
 import com.android.systemui.SystemUI;
-import com.android.systemui.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.policy.NotificationRowLayout;
 
 import java.util.ArrayList;
@@ -828,7 +827,7 @@
         // Construct the icon.
         final StatusBarIconView iconView = new StatusBarIconView(mContext,
                 notification.getPackageName() + "/0x" + Integer.toHexString(notification.getId()),
-                notification.getNotification(), getStatusBarMode());
+                notification.getNotification());
         iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
         final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
@@ -851,10 +850,6 @@
         return entry;
     }
 
-    protected int getStatusBarMode() {
-        return BarTransitions.MODE_OPAQUE;
-    }
-
     protected void addNotificationViews(NotificationData.Entry entry) {
         // Add the expanded view and icon.
         int pos = mNotificationData.add(entry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index ff84243..f1c8e01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -39,15 +39,15 @@
     NetworkController mNC;
 
     private boolean mWifiVisible = false;
-    private int mWifiStrengthId = 0, mWifiActivityId = 0;
+    private int mWifiStrengthId = 0;
     private boolean mMobileVisible = false;
-    private int mMobileStrengthId = 0, mMobileActivityId = 0, mMobileTypeId = 0;
+    private int mMobileStrengthId = 0, mMobileTypeId = 0;
     private boolean mIsAirplaneMode = false;
     private int mAirplaneIconId = 0;
     private String mWifiDescription, mMobileDescription, mMobileTypeDescription;
 
     ViewGroup mWifiGroup, mMobileGroup;
-    ImageView mWifi, mMobile, mWifiActivity, mMobileActivity, mMobileType, mAirplane;
+    ImageView mWifi, mMobile, mMobileType, mAirplane;
     View mSpacer;
 
     public SignalClusterView(Context context) {
@@ -73,10 +73,8 @@
 
         mWifiGroup      = (ViewGroup) findViewById(R.id.wifi_combo);
         mWifi           = (ImageView) findViewById(R.id.wifi_signal);
-        mWifiActivity   = (ImageView) findViewById(R.id.wifi_inout);
         mMobileGroup    = (ViewGroup) findViewById(R.id.mobile_combo);
         mMobile         = (ImageView) findViewById(R.id.mobile_signal);
-        mMobileActivity = (ImageView) findViewById(R.id.mobile_inout);
         mMobileType     = (ImageView) findViewById(R.id.mobile_type);
         mSpacer         =             findViewById(R.id.spacer);
         mAirplane       = (ImageView) findViewById(R.id.airplane);
@@ -88,10 +86,8 @@
     protected void onDetachedFromWindow() {
         mWifiGroup      = null;
         mWifi           = null;
-        mWifiActivity   = null;
         mMobileGroup    = null;
         mMobile         = null;
-        mMobileActivity = null;
         mMobileType     = null;
         mSpacer         = null;
         mAirplane       = null;
@@ -100,22 +96,19 @@
     }
 
     @Override
-    public void setWifiIndicators(boolean visible, int strengthIcon, int activityIcon,
-            String contentDescription) {
+    public void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription) {
         mWifiVisible = visible;
         mWifiStrengthId = strengthIcon;
-        mWifiActivityId = activityIcon;
         mWifiDescription = contentDescription;
 
         apply();
     }
 
     @Override
-    public void setMobileDataIndicators(boolean visible, int strengthIcon, int activityIcon,
+    public void setMobileDataIndicators(boolean visible, int strengthIcon,
             int typeIcon, String contentDescription, String typeContentDescription) {
         mMobileVisible = visible;
         mMobileStrengthId = strengthIcon;
-        mMobileActivityId = activityIcon;
         mMobileTypeId = typeIcon;
         mMobileDescription = contentDescription;
         mMobileTypeDescription = typeContentDescription;
@@ -149,16 +142,11 @@
         if (mWifi != null) {
             mWifi.setImageDrawable(null);
         }
-        if (mWifiActivity != null) {
-            mWifiActivity.setImageDrawable(null);
-        }
 
         if (mMobile != null) {
             mMobile.setImageDrawable(null);
         }
-        if (mMobileActivity != null) {
-            mMobileActivity.setImageDrawable(null);
-        }
+
         if (mMobileType != null) {
             mMobileType.setImageDrawable(null);
         }
@@ -176,7 +164,6 @@
 
         if (mWifiVisible) {
             mWifi.setImageResource(mWifiStrengthId);
-            mWifiActivity.setImageResource(mWifiActivityId);
 
             mWifiGroup.setContentDescription(mWifiDescription);
             mWifiGroup.setVisibility(View.VISIBLE);
@@ -185,13 +172,12 @@
         }
 
         if (DEBUG) Log.d(TAG,
-                String.format("wifi: %s sig=%d act=%d",
+                String.format("wifi: %s sig=%d",
                     (mWifiVisible ? "VISIBLE" : "GONE"),
-                    mWifiStrengthId, mWifiActivityId));
+                    mWifiStrengthId));
 
         if (mMobileVisible && !mIsAirplaneMode) {
             mMobile.setImageResource(mMobileStrengthId);
-            mMobileActivity.setImageResource(mMobileActivityId);
             mMobileType.setImageResource(mMobileTypeId);
 
             mMobileGroup.setContentDescription(mMobileTypeDescription + " " + mMobileDescription);
@@ -214,9 +200,9 @@
         }
 
         if (DEBUG) Log.d(TAG,
-                String.format("mobile: %s sig=%d act=%d typ=%d",
+                String.format("mobile: %s sig=%d typ=%d",
                     (mMobileVisible ? "VISIBLE" : "GONE"),
-                    mMobileStrengthId, mMobileActivityId, mMobileTypeId));
+                    mMobileStrengthId, mMobileTypeId));
 
         mMobileType.setVisibility(
                 !mWifiVisible ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 5689bfa..9f9524b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -16,11 +16,6 @@
 
 package com.android.systemui.statusbar;
 
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
-
-import android.animation.ObjectAnimator;
 import android.app.Notification;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -53,13 +48,10 @@
     private int mNumberY;
     private String mNumberText;
     private Notification mNotification;
-    private final float mAlphaWhenOpaque;
-    private final float mAlphaWhenTransparent = 1;
 
-    public StatusBarIconView(Context context, String slot, Notification notification, int mode) {
+    public StatusBarIconView(Context context, String slot, Notification notification) {
         super(context);
         final Resources res = context.getResources();
-        mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
         mSlot = slot;
         mNumberPain = new Paint();
         mNumberPain.setTextAlign(Paint.Align.CENTER);
@@ -76,7 +68,6 @@
             final float scale = (float)imageBounds / (float)outerBounds;
             setScaleX(scale);
             setScaleY(scale);
-            setAlpha(getAlphaFor(mode));
         }
 
         setScaleType(ImageView.ScaleType.CENTER);
@@ -85,22 +76,11 @@
     public StatusBarIconView(Context context, AttributeSet attrs) {
         super(context, attrs);
         final Resources res = context.getResources();
-        mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
         final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
         final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
         final float scale = (float)imageBounds / (float)outerBounds;
         setScaleX(scale);
         setScaleY(scale);
-        setAlpha(getAlphaFor(MODE_OPAQUE));
-    }
-
-    public ObjectAnimator animateTransitionTo(int mode) {
-        return ObjectAnimator.ofFloat(this, "alpha", getAlpha(), getAlphaFor(mode));
-    }
-
-    public float getAlphaFor(int mode) {
-        final boolean isTransparent = mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
-        return isTransparent ? mAlphaWhenTransparent : mAlphaWhenOpaque;
     }
 
     private static boolean streq(String a, String b) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
new file mode 100644
index 0000000..aba7afa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.DemoMode;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.policy.LocationController;
+
+public class DemoStatusIcons extends LinearLayout implements DemoMode {
+    private final LinearLayout mStatusIcons;
+    private final int mIconSize;
+
+    private boolean mDemoMode;
+
+    public DemoStatusIcons(LinearLayout statusIcons, int iconSize) {
+        super(statusIcons.getContext());
+        mStatusIcons = statusIcons;
+        mIconSize = iconSize;
+
+        setLayoutParams(mStatusIcons.getLayoutParams());
+        setOrientation(mStatusIcons.getOrientation());
+        setGravity(Gravity.CENTER_VERTICAL); // no LL.getGravity()
+        ViewGroup p = (ViewGroup) mStatusIcons.getParent();
+        p.addView(this, p.indexOfChild(mStatusIcons));
+    }
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+            mStatusIcons.setVisibility(View.GONE);
+            setVisibility(View.VISIBLE);
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            mStatusIcons.setVisibility(View.VISIBLE);
+            setVisibility(View.GONE);
+        } else if (mDemoMode && command.equals(COMMAND_STATUS)) {
+            String volume = args.getString("volume");
+            if (volume != null) {
+                int iconId = volume.equals("silent") ? R.drawable.stat_sys_ringer_silent
+                        : volume.equals("vibrate") ? R.drawable.stat_sys_ringer_vibrate
+                        : 0;
+                updateSlot("volume", null, iconId);
+            }
+            String bt = args.getString("bluetooth");
+            if (bt != null) {
+                int iconId = bt.equals("disconnected") ? R.drawable.stat_sys_data_bluetooth
+                        : bt.equals("connected") ? R.drawable.stat_sys_data_bluetooth_connected
+                        : 0;
+                updateSlot("bluetooth", null, iconId);
+            }
+            String location = args.getString("location");
+            if (location != null) {
+                int iconId = location.equals("show") ? LocationController.LOCATION_STATUS_ICON_ID
+                        : 0;
+                updateSlot(LocationController.LOCATION_STATUS_ICON_PLACEHOLDER, null, iconId);
+            }
+            String alarm = args.getString("alarm");
+            if (alarm != null) {
+                int iconId = alarm.equals("show") ? R.drawable.stat_sys_alarm
+                        : 0;
+                updateSlot("alarm_clock", null, iconId);
+            }
+            String sync = args.getString("sync");
+            if (sync != null) {
+                int iconId = sync.equals("show") ? R.drawable.stat_sys_sync
+                        : 0;
+                updateSlot("sync_active", null, iconId);
+            }
+            String tty = args.getString("tty");
+            if (tty != null) {
+                int iconId = tty.equals("show") ? R.drawable.stat_sys_tty_mode
+                        : 0;
+                updateSlot("tty", null, iconId);
+            }
+            String eri = args.getString("eri");
+            if (eri != null) {
+                int iconId = eri.equals("show") ? R.drawable.stat_sys_roaming_cdma_0
+                        : 0;
+                updateSlot("cdma_eri", null, iconId);
+            }
+            String mute = args.getString("mute");
+            if (mute != null) {
+                int iconId = mute.equals("show") ? android.R.drawable.stat_notify_call_mute
+                        : 0;
+                updateSlot("mute", null, iconId);
+            }
+            String speakerphone = args.getString("speakerphone");
+            if (speakerphone != null) {
+                int iconId = speakerphone.equals("show") ? android.R.drawable.stat_sys_speakerphone
+                        : 0;
+                updateSlot("speakerphone", null, iconId);
+            }
+        }
+    }
+
+    private void updateSlot(String slot, String iconPkg, int iconId) {
+        if (!mDemoMode) return;
+        int removeIndex = -1;
+        for (int i = 0; i < getChildCount(); i++) {
+            StatusBarIconView v = (StatusBarIconView) getChildAt(i);
+            if (slot.equals(v.getTag())) {
+                if (iconId == 0) {
+                    removeIndex = i;
+                    break;
+                } else {
+                    StatusBarIcon icon = v.getStatusBarIcon();
+                    icon.iconPackage = iconPkg;
+                    icon.iconId = iconId;
+                    v.set(icon);
+                    v.updateDrawable();
+                    return;
+                }
+            }
+        }
+        if (iconId == 0) {
+            if (removeIndex != -1) {
+                removeViewAt(removeIndex);
+                return;
+            }
+        }
+        StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.CURRENT, iconId, 0, 0, "Demo");
+        StatusBarIconView v = new StatusBarIconView(mContext, null);
+        v.setTag(slot);
+        v.set(icon);
+        addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+    }
+}
\ No newline at end of file
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 870202a..01e6c84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -47,6 +47,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.inputmethodservice.InputMethodService;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -79,6 +80,7 @@
 import android.widget.TextView;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.DemoMode;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -102,7 +104,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
-public class PhoneStatusBar extends BaseStatusBar {
+public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
     static final String TAG = "PhoneStatusBar";
     public static final boolean DEBUG = BaseStatusBar.DEBUG;
     public static final boolean SPEW = false;
@@ -363,7 +365,6 @@
         mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
         mStatusBarView.setBar(this);
 
-
         PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
         mStatusBarView.setPanelHolder(holder);
 
@@ -605,18 +606,13 @@
             }
         }
 
-//        final ImageView wimaxRSSI =
-//                (ImageView)sb.findViewById(R.id.wimax_signal);
-//        if (wimaxRSSI != null) {
-//            mNetworkController.addWimaxIconView(wimaxRSSI);
-//        }
-
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_SCREEN_ON);
+        filter.addAction(ACTION_DEMO);
         context.registerReceiver(mBroadcastReceiver, filter);
 
         // listen for USER_SETUP_COMPLETE setting (per-user)
@@ -839,7 +835,7 @@
     public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
         if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
                 + " icon=" + icon);
-        StatusBarIconView view = new StatusBarIconView(mContext, slot, null, getStatusBarMode());
+        StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
         view.set(icon);
         mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
     }
@@ -1741,7 +1737,9 @@
             mGestureRec.add(event);
         }
 
-        setInteracting(true);
+        if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
+            setInteracting(true);
+        }
         return false;
     }
 
@@ -1769,7 +1767,6 @@
                 && mStatusBarWindowState != state) {
             mStatusBarWindowState = state;
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
-            mStatusBarWindow.setEnabled(showing);
             if (!showing) {
                 mStatusBarView.collapseAllPanels(false);
             }
@@ -1779,7 +1776,6 @@
                 && mNavigationBarWindowState != state) {
             mNavigationBarWindowState = state;
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
-            mNavigationBarView.setEnabled(showing);
         }
     }
 
@@ -1857,11 +1853,6 @@
         }
     }
 
-    @Override
-    protected int getStatusBarMode() {
-        return mStatusBarView.getBarTransitions().getMode();
-    }
-
     private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
             int transientFlag, int transparentFlag) {
         final int oldMode = barMode(oldVis, transientFlag, transparentFlag);
@@ -1879,6 +1870,7 @@
     }
 
     private void checkBarModes() {
+        if (mDemoMode) return;
         checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
         if (mNavigationBarView != null) {
             checkBarMode(mNavigationBarMode,
@@ -2452,6 +2444,19 @@
                 repositionNavigationBar();
                 notifyNavigationBarScreenOn(true);
             }
+            else if (ACTION_DEMO.equals(action)) {
+                Bundle bundle = intent.getExtras();
+                if (bundle != null) {
+                    String command = bundle.getString("command", "").trim().toLowerCase();
+                    if (command.length() > 0) {
+                        try {
+                            dispatchDemoCommand(command, bundle);
+                        } catch (Throwable t) {
+                            Log.w(TAG, "Error running demo command, intent=" + intent, t);
+                        }
+                    }
+                }
+            }
         }
     };
 
@@ -2681,4 +2686,66 @@
         }
         mContext.unregisterReceiver(mBroadcastReceiver);
     }
+
+    private boolean mDemoModeAllowed;
+    private boolean mDemoMode;
+    private DemoStatusIcons mDemoStatusIcons;
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoModeAllowed) {
+            mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
+                    "sysui_demo_allowed", 0) != 0;
+        }
+        if (!mDemoModeAllowed) return;
+        if (command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+        } else if (command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            checkBarModes();
+        } else if (!mDemoMode) {
+            // automatically enter demo mode on first demo command
+            dispatchDemoCommand(COMMAND_ENTER, new Bundle());
+        }
+        boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
+        if (modeChange || command.equals(COMMAND_CLOCK)) {
+            dispatchDemoCommandToView(command, args, R.id.clock);
+        }
+        if (modeChange || command.equals(COMMAND_BATTERY)) {
+            dispatchDemoCommandToView(command, args, R.id.battery);
+        }
+        if (modeChange || command.equals(COMMAND_STATUS)) {
+            if (mDemoStatusIcons == null) {
+                mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
+            }
+            mDemoStatusIcons.dispatchDemoCommand(command, args);
+        }
+        if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
+            mNetworkController.dispatchDemoCommand(command, args);
+        }
+        if (command.equals(COMMAND_BARS)) {
+            String mode = args.getString("mode");
+            int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
+                    "transparent".equals(mode) ? MODE_TRANSPARENT :
+                    "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
+                    -1;
+            if (barMode != -1) {
+                boolean animate = true;
+                if (mStatusBarView != null) {
+                    mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
+                }
+                if (mNavigationBarView != null) {
+                    mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
+                }
+            }
+        }
+    }
+
+    private void dispatchDemoCommandToView(String command, Bundle args, int id) {
+        if (mStatusBarView == null) return;
+        View v = mStatusBarView.findViewById(id);
+        if (v instanceof DemoMode) {
+            ((DemoMode)v).dispatchDemoCommand(command, args);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 4ee2a4b..159bc62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -157,9 +157,8 @@
 
         // Sync state
         mService.setIcon("sync_active", R.drawable.stat_sys_sync, 0, null);
-        mService.setIcon("sync_failing", R.drawable.stat_sys_sync_error, 0, null);
         mService.setIconVisibility("sync_active", false);
-        mService.setIconVisibility("sync_failing", false);
+        // "sync_failing" is obsolete: b/1297963
 
         // volume
         mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);
@@ -175,10 +174,7 @@
     private final void updateSyncState(Intent intent) {
         if (!SHOW_SYNC_ICON) return;
         boolean isActive = intent.getBooleanExtra("active", false);
-        boolean isFailing = intent.getBooleanExtra("failing", false);
         mService.setIconVisibility("sync_active", isActive);
-        // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
-        //mService.setIconVisibility("sync_failing", isFailing && !isActive);
     }
 
     private final void updateSimState(Intent intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 2e9ee87..fa494c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -16,8 +16,12 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+
 import android.animation.Animator;
 import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Resources;
@@ -27,15 +31,10 @@
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.StatusBarIconView;
-
-import java.util.ArrayList;
-import java.util.List;
 
 public class PhoneStatusBarView extends PanelBar {
     private static final String TAG = "PhoneStatusBarView";
@@ -56,11 +55,22 @@
 
     private final class StatusBarTransitions extends BarTransitions {
         private final int mTransparent;
+        private final float mAlphaWhenOpaque;
+        private final float mAlphaWhenTransparent = 1;
+        private View mLeftSide;
+        private View mRightSide;
 
         public StatusBarTransitions(Context context) {
             super(context, PhoneStatusBarView.this);
             final Resources res = context.getResources();
             mTransparent = res.getColor(R.color.status_bar_background_transparent);
+            mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+        }
+
+        public void init() {
+            mLeftSide = findViewById(R.id.notification_icon_area);
+            mRightSide = findViewById(R.id.system_icon_area);
+            applyMode(getMode(), false /*animate*/);
         }
 
         @Override
@@ -69,41 +79,32 @@
             return super.getBackgroundColor(mode);
         }
 
+        public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
+            return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
+        }
+
+        public float getAlphaFor(int mode) {
+            final boolean isTransparent = mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
+            return isTransparent ? mAlphaWhenTransparent : mAlphaWhenOpaque;
+        }
+
         @Override
         protected void onTransition(int oldMode, int newMode, boolean animate) {
             super.onTransition(oldMode, newMode, animate);
+            applyMode(newMode, animate);
+        }
+
+        private void applyMode(int mode, boolean animate) {
+            float newAlpha = getAlphaFor(mode);
             if (animate) {
-                List<Animator> animators = new ArrayList<Animator>();
-                for(StatusBarIconView icon : findStatusBarIcons()) {
-                    animators.add(icon.animateTransitionTo(newMode));
-                }
+                ObjectAnimator lhs = animateTransitionTo(mLeftSide, newAlpha);
+                ObjectAnimator rhs = animateTransitionTo(mRightSide, newAlpha);
                 AnimatorSet set = new AnimatorSet();
-                set.playTogether(animators);
+                set.playTogether(lhs, rhs);
                 set.start();
             } else {
-                for(StatusBarIconView icon : findStatusBarIcons()) {
-                    icon.setAlpha(icon.getAlphaFor(newMode));
-                }
-            }
-        }
-
-        private List<StatusBarIconView> findStatusBarIcons() {
-            List<StatusBarIconView> icons = new ArrayList<StatusBarIconView>();
-            findStatusBarIcons(icons, findViewById(R.id.moreIcon));
-            findStatusBarIcons(icons, findViewById(R.id.statusIcons));
-            findStatusBarIcons(icons, findViewById(R.id.notificationIcons));
-            return icons;
-        }
-
-        private void findStatusBarIcons(List<StatusBarIconView> icons, View v) {
-            if (v instanceof StatusBarIconView) {
-                icons.add((StatusBarIconView) v);
-            } else if (v instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) v;
-                final int N = group.getChildCount();
-                for (int i = 0; i < N; i++) {
-                    findStatusBarIcons(icons, group.getChildAt(i));
-                }
+                mLeftSide.setAlpha(newAlpha);
+                mRightSide.setAlpha(newAlpha);
             }
         }
     }
@@ -140,6 +141,7 @@
         for (PanelView pv : mPanels) {
             pv.setRubberbandingEnabled(!mFullWidthNotifications);
         }
+        mBarTransitions.init();
     }
 
     @Override
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 b9c6fef..0d591ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -640,10 +640,10 @@
                 @Override
                 public boolean onLongClick(View v) {
                     boolean newLocationEnabledState = !mLocationController.isLocationEnabled();
-                    mLocationController.setLocationEnabled(newLocationEnabledState);
-                    if (newLocationEnabledState) {
-                        // Close the notifications tray so that the network location provider
-                        // consent dialog can be shown.
+                    if (mLocationController.setLocationEnabled(newLocationEnabledState)
+                            && newLocationEnabledState) {
+                        // If we've successfully switched from location off to on, close the
+                        // notifications tray to show the network location provider consent dialog.
                         Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                         mContext.sendBroadcast(closeDialog);
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
index fece57e..0e53f0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
@@ -23,10 +23,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -35,11 +31,6 @@
 public class BluetoothController extends BroadcastReceiver {
     private static final String TAG = "StatusBar.BluetoothController";
 
-    private Context mContext;
-    private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>();
-
-    private int mIconId = R.drawable.stat_sys_data_bluetooth;
-    private int mContentDescriptionId = 0;
     private boolean mEnabled = false;
 
     private Set<BluetoothDevice> mBondedDevices = new HashSet<BluetoothDevice>();
@@ -48,7 +39,6 @@
             new ArrayList<BluetoothStateChangeCallback>();
 
     public BluetoothController(Context context) {
-        mContext = context;
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
@@ -59,16 +49,11 @@
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null) {
             handleAdapterStateChange(adapter.getState());
-            handleConnectionStateChange(adapter.getConnectionState());
         }
-        refreshViews();
+        fireCallbacks();
         updateBondedBluetoothDevices();
     }
 
-    public void addIconView(ImageView v) {
-        mIconViews.add(v);
-    }
-
     public void addStateChangedCallback(BluetoothStateChangeCallback cb) {
         mChangeCallbacks.add(cb);
     }
@@ -84,14 +69,8 @@
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
             handleAdapterStateChange(
                     intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR));
-        } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
-            handleConnectionStateChange(
-                    intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
-                        BluetoothAdapter.STATE_DISCONNECTED));
-        } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
-            // Fall through and update bonded devices and refresh view
         }
-        refreshViews();
+        fireCallbacks();
         updateBondedBluetoothDevices();
     }
 
@@ -111,31 +90,11 @@
         }
     }
 
-    public void handleAdapterStateChange(int adapterState) {
+    private void handleAdapterStateChange(int adapterState) {
         mEnabled = (adapterState == BluetoothAdapter.STATE_ON);
     }
 
-    public void handleConnectionStateChange(int connectionState) {
-        final boolean connected = (connectionState == BluetoothAdapter.STATE_CONNECTED);
-        if (connected) {
-            mIconId = R.drawable.stat_sys_data_bluetooth_connected;
-            mContentDescriptionId = R.string.accessibility_bluetooth_connected;
-        } else {
-            mIconId = R.drawable.stat_sys_data_bluetooth;
-            mContentDescriptionId = R.string.accessibility_bluetooth_disconnected;
-        }
-    }
-
-    public void refreshViews() {
-        int N = mIconViews.size();
-        for (int i=0; i<N; i++) {
-            ImageView v = mIconViews.get(i);
-            v.setImageResource(mIconId);
-            v.setVisibility(mEnabled ? View.VISIBLE : View.GONE);
-            v.setContentDescription((mContentDescriptionId == 0)
-                    ? null
-                    : mContext.getString(mContentDescriptionId));
-        }
+    private void fireCallbacks() {
         for (BluetoothStateChangeCallback cb : mChangeCallbacks) {
             cb.onBluetoothStateChange(mEnabled);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 93fb14f..8ced1c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.Bundle;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.format.DateFormat;
@@ -28,6 +29,8 @@
 import android.util.AttributeSet;
 import android.widget.TextView;
 
+import com.android.systemui.DemoMode;
+
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
@@ -38,7 +41,7 @@
 /**
  * Digital clock for the status bar.
  */
-public class Clock extends TextView {
+public class Clock extends TextView implements DemoMode {
     private boolean mAttached;
     private Calendar mCalendar;
     private String mClockFormatString;
@@ -121,6 +124,7 @@
     };
 
     final void updateClock() {
+        if (mDemoMode) return;
         mCalendar.setTimeInMillis(System.currentTimeMillis());
         setText(getSmallTime());
     }
@@ -196,5 +200,29 @@
         return result;
 
     }
+
+    private boolean mDemoMode;
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            updateClock();
+        } else if (mDemoMode && command.equals(COMMAND_CLOCK)) {
+            String millis = args.getString("millis");
+            String hhmm = args.getString("hhmm");
+            if (millis != null) {
+                mCalendar.setTimeInMillis(Long.parseLong(millis));
+            } else if (hhmm != null && hhmm.length() == 4) {
+                int hh = Integer.parseInt(hhmm.substring(0, 2));
+                int mm = Integer.parseInt(hhmm.substring(2));
+                mCalendar.set(Calendar.HOUR, hh);
+                mCalendar.set(Calendar.MINUTE, mm);
+            }
+            setText(getSmallTime());
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 7e75584..5f6063d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
@@ -26,6 +27,7 @@
 import android.database.ContentObserver;
 import android.location.LocationManager;
 import android.os.Handler;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
 
@@ -40,8 +42,8 @@
 public class LocationController extends BroadcastReceiver {
     // The name of the placeholder corresponding to the location request status icon.
     // This string corresponds to config_statusBarIcons in core/res/res/values/config.xml.
-    private static final String LOCATION_STATUS_ICON_PLACEHOLDER = "location";
-    private static final int LOCATION_STATUS_ICON_ID
+    public static final String LOCATION_STATUS_ICON_PLACEHOLDER = "location";
+    public static final int LOCATION_STATUS_ICON_ID
         = R.drawable.stat_sys_device_access_location_found;
 
     private static final int[] mHighPowerRequestAppOpArray
@@ -81,18 +83,18 @@
         mStatusBarManager
                 = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
 
-        // Register to listen for changes to the location settings
-        context.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true,
-                new ContentObserver(new Handler()) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        boolean isEnabled = isLocationEnabled();
-                        for (LocationSettingsChangeCallback cb : mSettingsChangeCallbacks) {
-                            cb.onLocationSettingsChanged(isEnabled);
-                        }
-                    }
-                });
+        // Register to listen for changes in location settings.
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(LocationManager.MODE_CHANGED_ACTION);
+        context.registerReceiverAsUser(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (LocationManager.MODE_CHANGED_ACTION.equals(action)) {
+                    locationSettingsChanged();
+                }
+            }
+        }, UserHandle.ALL, intentFilter, null, new Handler());
 
         // Examine the current location state and initialize the status view.
         updateActiveLocationRequests();
@@ -114,31 +116,49 @@
      *
      * <p>If enabling, a user consent dialog will pop up prompting the user to accept.
      * If the user doesn't accept, network location won't be enabled.
+     *
+     * @return true if attempt to change setting was successful.
      */
-    public void setLocationEnabled(boolean enabled) {
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        if (um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) {
-            return;
+    public boolean setLocationEnabled(boolean enabled) {
+        int currentUserId = ActivityManager.getCurrentUser();
+        if (isUserLocationRestricted(currentUserId)) {
+            return false;
         }
         final ContentResolver cr = mContext.getContentResolver();
         // When enabling location, a user consent dialog will pop up, and the
         // setting won't be fully enabled until the user accepts the agreement.
         int mode = enabled
                 ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY : Settings.Secure.LOCATION_MODE_OFF;
-        Settings.Secure.putInt(cr, Settings.Secure.LOCATION_MODE, mode);
+        return Settings.Secure
+                .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, currentUserId);
     }
 
     /**
      * Returns true if location isn't disabled in settings.
      */
     public boolean isLocationEnabled() {
+        int currentUserId = ActivityManager.getCurrentUser();
+        if (isUserLocationRestricted(currentUserId)) {
+            return false;
+        }
+
         ContentResolver resolver = mContext.getContentResolver();
-        int mode = Settings.Secure.getInt(resolver, Settings.Secure.LOCATION_MODE,
-                Settings.Secure.LOCATION_MODE_OFF);
+        int mode = Settings.Secure.getIntForUser(resolver, Settings.Secure.LOCATION_MODE,
+                Settings.Secure.LOCATION_MODE_OFF, currentUserId);
         return mode != Settings.Secure.LOCATION_MODE_OFF;
     }
 
     /**
+     * Returns true if the current user is restricted from using location.
+     */
+    private boolean isUserLocationRestricted(int userId) {
+        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        return um.hasUserRestriction(
+                UserManager.DISALLOW_SHARE_LOCATION,
+                new UserHandle(userId));
+    }
+
+    /**
      * Returns true if there currently exist active high power location requests.
      */
     private boolean areActiveHighPowerLocationRequests() {
@@ -188,6 +208,13 @@
         }
     }
 
+    private void locationSettingsChanged() {
+        boolean isEnabled = isLocationEnabled();
+        for (LocationSettingsChangeCallback cb : mSettingsChangeCallbacks) {
+            cb.onLocationSettingsChanged(isEnabled);
+        }
+    }
+
     @Override
     public void onReceive(Context context, Intent intent) {
         final String action = intent.getAction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 34e3013..1e7e692 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -27,6 +27,7 @@
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wimax.WimaxManagerConstants;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
@@ -37,13 +38,13 @@
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.view.View;
-import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.internal.util.AsyncChannel;
+import com.android.systemui.DemoMode;
 import com.android.systemui.R;
 
 import java.io.FileDescriptor;
@@ -52,12 +53,14 @@
 import java.util.List;
 import java.util.Locale;
 
-public class NetworkController extends BroadcastReceiver {
+public class NetworkController extends BroadcastReceiver implements DemoMode {
     // debug
     static final String TAG = "StatusBar.NetworkController";
     static final boolean DEBUG = false;
     static final boolean CHATTY = false; // additional diagnostics, but not logspew
 
+    private static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_signal_flightmode;
+
     // telephony
     boolean mHspaDataDistinguishable;
     final TelephonyManager mPhone;
@@ -81,7 +84,6 @@
     int mQSDataTypeIconId;
     int mAirplaneIconId;
     boolean mDataActive;
-    int mMobileActivityIconId; // overlay arrows for data direction
     int mLastSignalLevel;
     boolean mShowPhoneRSSIForData = false;
     boolean mShowAtLeastThreeGees = false;
@@ -101,7 +103,6 @@
     String mWifiSsid;
     int mWifiIconId = 0;
     int mQSWifiIconId = 0;
-    int mWifiActivityIconId = 0; // overlay arrows for wifi direction
     int mWifiActivity = WifiManager.DATA_ACTIVITY_NONE;
 
     // bluetooth
@@ -135,13 +136,6 @@
 
     // our ui
     Context mContext;
-    ArrayList<ImageView> mPhoneSignalIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mDataDirectionIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mDataDirectionOverlayIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mWifiIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mWimaxIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>();
     ArrayList<TextView> mCombinedLabelViews = new ArrayList<TextView>();
     ArrayList<TextView> mMobileLabelViews = new ArrayList<TextView>();
     ArrayList<TextView> mWifiLabelViews = new ArrayList<TextView>();
@@ -151,7 +145,6 @@
             new ArrayList<NetworkSignalChangedCallback>();
     int mLastPhoneSignalIconId = -1;
     int mLastDataDirectionIconId = -1;
-    int mLastDataDirectionOverlayIconId = -1;
     int mLastWifiIconId = -1;
     int mLastWimaxIconId = -1;
     int mLastCombinedSignalIconId = -1;
@@ -163,9 +156,9 @@
     boolean mDataAndWifiStacked = false;
 
     public interface SignalCluster {
-        void setWifiIndicators(boolean visible, int strengthIcon, int activityIcon,
+        void setWifiIndicators(boolean visible, int strengthIcon,
                 String contentDescription);
-        void setMobileDataIndicators(boolean visible, int strengthIcon, int activityIcon,
+        void setMobileDataIndicators(boolean visible, int strengthIcon,
                 int typeIcon, String contentDescription, String typeContentDescription);
         void setIsAirplaneMode(boolean is, int airplaneIcon);
     }
@@ -261,33 +254,6 @@
         return (mServiceState != null && mServiceState.isEmergencyOnly());
     }
 
-    public void addPhoneSignalIconView(ImageView v) {
-        mPhoneSignalIconViews.add(v);
-    }
-
-    public void addDataDirectionIconView(ImageView v) {
-        mDataDirectionIconViews.add(v);
-    }
-
-    public void addDataDirectionOverlayIconView(ImageView v) {
-        mDataDirectionOverlayIconViews.add(v);
-    }
-
-    public void addWifiIconView(ImageView v) {
-        mWifiIconViews.add(v);
-    }
-    public void addWimaxIconView(ImageView v) {
-        mWimaxIconViews.add(v);
-    }
-
-    public void addCombinedSignalIconView(ImageView v) {
-        mCombinedSignalIconViews.add(v);
-    }
-
-    public void addDataTypeIconView(ImageView v) {
-        mDataTypeIconViews.add(v);
-    }
-
     public void addCombinedLabelView(TextView v) {
         mCombinedLabelViews.add(v);
     }
@@ -315,11 +281,11 @@
     }
 
     public void refreshSignalCluster(SignalCluster cluster) {
+        if (mDemoMode) return;
         cluster.setWifiIndicators(
                 // only show wifi in the cluster if connected or if wifi-only
                 mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature),
                 mWifiIconId,
-                mWifiActivityIconId,
                 mContentDescriptionWifi);
 
         if (mIsWimaxEnabled && mWimaxConnected) {
@@ -327,7 +293,6 @@
             cluster.setMobileDataIndicators(
                     true,
                     mAlwaysShowCdmaRssi ? mPhoneSignalIconId : mWimaxIconId,
-                    mMobileActivityIconId,
                     mDataTypeIconId,
                     mContentDescriptionWimax,
                     mContentDescriptionDataType);
@@ -336,7 +301,6 @@
             cluster.setMobileDataIndicators(
                     mHasMobileDataFeature,
                     mShowPhoneRSSIForData ? mPhoneSignalIconId : mDataSignalIconId,
-                    mMobileActivityIconId,
                     mDataTypeIconId,
                     mContentDescriptionPhoneSignal,
                     mContentDescriptionDataType);
@@ -1008,7 +972,6 @@
         Context context = mContext;
 
         int combinedSignalIconId = 0;
-        int combinedActivityIconId = 0;
         String combinedLabel = "";
         String wifiLabel = "";
         String mobileLabel = "";
@@ -1046,56 +1009,23 @@
             // Now for things that should only be shown when actually using mobile data.
             if (mDataConnected) {
                 combinedSignalIconId = mDataSignalIconId;
-                switch (mDataActivity) {
-                    case TelephonyManager.DATA_ACTIVITY_IN:
-                        mMobileActivityIconId = R.drawable.stat_sys_signal_in;
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_OUT:
-                        mMobileActivityIconId = R.drawable.stat_sys_signal_out;
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_INOUT:
-                        mMobileActivityIconId = R.drawable.stat_sys_signal_inout;
-                        break;
-                    default:
-                        mMobileActivityIconId = 0;
-                        break;
-                }
 
                 combinedLabel = mobileLabel;
-                combinedActivityIconId = mMobileActivityIconId;
                 combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
                 mContentDescriptionCombinedSignal = mContentDescriptionDataType;
-            } else {
-                mMobileActivityIconId = 0;
             }
         }
 
         if (mWifiConnected) {
             if (mWifiSsid == null) {
                 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
-                mWifiActivityIconId = 0; // no wifis, no bits
             } else {
                 wifiLabel = mWifiSsid;
                 if (DEBUG) {
                     wifiLabel += "xxxxXXXXxxxxXXXX";
                 }
-                switch (mWifiActivity) {
-                    case WifiManager.DATA_ACTIVITY_IN:
-                        mWifiActivityIconId = R.drawable.stat_sys_wifi_in;
-                        break;
-                    case WifiManager.DATA_ACTIVITY_OUT:
-                        mWifiActivityIconId = R.drawable.stat_sys_wifi_out;
-                        break;
-                    case WifiManager.DATA_ACTIVITY_INOUT:
-                        mWifiActivityIconId = R.drawable.stat_sys_wifi_inout;
-                        break;
-                    case WifiManager.DATA_ACTIVITY_NONE:
-                        mWifiActivityIconId = 0;
-                        break;
-                }
             }
 
-            combinedActivityIconId = mWifiActivityIconId;
             combinedLabel = wifiLabel;
             combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
             mContentDescriptionCombinedSignal = mContentDescriptionWifi;
@@ -1126,7 +1056,7 @@
             // look again; your radios are now airplanes
             mContentDescriptionPhoneSignal = mContext.getString(
                     R.string.accessibility_airplane_mode);
-            mAirplaneIconId = R.drawable.stat_sys_signal_flightmode;
+            mAirplaneIconId = FLIGHT_MODE_ICON;
             mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0;
             mQSPhoneSignalIconId = 0;
 
@@ -1178,7 +1108,6 @@
                     + " combinedSignalIconId=0x"
                     + Integer.toHexString(combinedSignalIconId)
                     + "/" + getResourceName(combinedSignalIconId)
-                    + " combinedActivityIconId=0x" + Integer.toHexString(combinedActivityIconId)
                     + " mobileLabel=" + mobileLabel
                     + " wifiLabel=" + wifiLabel
                     + " emergencyOnly=" + emergencyOnly
@@ -1197,7 +1126,6 @@
         }
 
         if (mLastPhoneSignalIconId          != mPhoneSignalIconId
-         || mLastDataDirectionOverlayIconId != combinedActivityIconId
          || mLastWifiIconId                 != mWifiIconId
          || mLastWimaxIconId                != mWimaxIconId
          || mLastDataTypeIconId             != mDataTypeIconId
@@ -1224,105 +1152,30 @@
         // the phone icon on phones
         if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
             mLastPhoneSignalIconId = mPhoneSignalIconId;
-            N = mPhoneSignalIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mPhoneSignalIconViews.get(i);
-                if (mPhoneSignalIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mPhoneSignalIconId);
-                    v.setContentDescription(mContentDescriptionPhoneSignal);
-                }
-            }
         }
 
         // the data icon on phones
         if (mLastDataDirectionIconId != mDataDirectionIconId) {
             mLastDataDirectionIconId = mDataDirectionIconId;
-            N = mDataDirectionIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mDataDirectionIconViews.get(i);
-                v.setImageResource(mDataDirectionIconId);
-                v.setContentDescription(mContentDescriptionDataType);
-            }
         }
 
         // the wifi icon on phones
         if (mLastWifiIconId != mWifiIconId) {
             mLastWifiIconId = mWifiIconId;
-            N = mWifiIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mWifiIconViews.get(i);
-                if (mWifiIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mWifiIconId);
-                    v.setContentDescription(mContentDescriptionWifi);
-                }
-            }
         }
 
         // the wimax icon on phones
         if (mLastWimaxIconId != mWimaxIconId) {
             mLastWimaxIconId = mWimaxIconId;
-            N = mWimaxIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mWimaxIconViews.get(i);
-                if (mWimaxIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mWimaxIconId);
-                    v.setContentDescription(mContentDescriptionWimax);
-                }
-           }
         }
         // the combined data signal icon
         if (mLastCombinedSignalIconId != combinedSignalIconId) {
             mLastCombinedSignalIconId = combinedSignalIconId;
-            N = mCombinedSignalIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mCombinedSignalIconViews.get(i);
-                v.setImageResource(combinedSignalIconId);
-                v.setContentDescription(mContentDescriptionCombinedSignal);
-            }
         }
 
         // the data network type overlay
         if (mLastDataTypeIconId != mDataTypeIconId) {
             mLastDataTypeIconId = mDataTypeIconId;
-            N = mDataTypeIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mDataTypeIconViews.get(i);
-                if (mDataTypeIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mDataTypeIconId);
-                    v.setContentDescription(mContentDescriptionDataType);
-                }
-            }
-        }
-
-        // the data direction overlay
-        if (mLastDataDirectionOverlayIconId != combinedActivityIconId) {
-            if (DEBUG) {
-                Log.d(TAG, "changing data overlay icon id to " + combinedActivityIconId);
-            }
-            mLastDataDirectionOverlayIconId = combinedActivityIconId;
-            N = mDataDirectionOverlayIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mDataDirectionOverlayIconViews.get(i);
-                if (combinedActivityIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(combinedActivityIconId);
-                    v.setContentDescription(mContentDescriptionDataType);
-                }
-            }
         }
 
         // the combinedLabel in the notification panel
@@ -1481,10 +1334,6 @@
         pw.print(Integer.toHexString(mLastDataDirectionIconId));
         pw.print("/");
         pw.println(getResourceName(mLastDataDirectionIconId));
-        pw.print("  mLastDataDirectionOverlayIconId=0x");
-        pw.print(Integer.toHexString(mLastDataDirectionOverlayIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastDataDirectionOverlayIconId));
         pw.print("  mLastWifiIconId=0x");
         pw.print(Integer.toHexString(mLastWifiIconId));
         pw.print("/");
@@ -1515,4 +1364,87 @@
         }
     }
 
+    private boolean mDemoMode;
+    private int mDemoInetCondition;
+    private int mDemoWifiLevel;
+    private int mDemoDataTypeIconId;
+    private int mDemoMobileLevel;
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+            mDemoWifiLevel = mWifiLevel;
+            mDemoInetCondition = mInetCondition;
+            mDemoDataTypeIconId = mDataTypeIconId;
+            mDemoMobileLevel = mLastSignalLevel;
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            for (SignalCluster cluster : mSignalClusters) {
+                refreshSignalCluster(cluster);
+            }
+        } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
+            String airplane = args.getString("airplane");
+            if (airplane != null) {
+                boolean show = airplane.equals("show");
+                for (SignalCluster cluster : mSignalClusters) {
+                    cluster.setIsAirplaneMode(show, FLIGHT_MODE_ICON);
+                }
+            }
+            String fully = args.getString("fully");
+            if (fully != null) {
+                mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0;
+            }
+            String wifi = args.getString("wifi");
+            if (wifi != null) {
+                boolean show = wifi.equals("show");
+                String level = args.getString("level");
+                if (level != null) {
+                    mDemoWifiLevel = level.equals("null") ? -1
+                            : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
+                }
+                int iconId = mDemoWifiLevel < 0 ? R.drawable.stat_sys_wifi_signal_null
+                        : WifiIcons.WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
+                for (SignalCluster cluster : mSignalClusters) {
+                    cluster.setWifiIndicators(
+                            show,
+                            iconId,
+                            "Demo");
+                }
+            }
+            String mobile = args.getString("mobile");
+            if (mobile != null) {
+                boolean show = mobile.equals("show");
+                String datatype = args.getString("datatype");
+                if (datatype != null) {
+                    mDemoDataTypeIconId =
+                            datatype.equals("1x") ? R.drawable.stat_sys_data_connected_1x :
+                            datatype.equals("3g") ? R.drawable.stat_sys_data_connected_3g :
+                            datatype.equals("4g") ? R.drawable.stat_sys_data_connected_4g :
+                            datatype.equals("e") ? R.drawable.stat_sys_data_connected_e :
+                            datatype.equals("g") ? R.drawable.stat_sys_data_connected_g :
+                            datatype.equals("h") ? R.drawable.stat_sys_data_connected_h :
+                            datatype.equals("lte") ? R.drawable.stat_sys_data_connected_lte :
+                            datatype.equals("roam") ? R.drawable.stat_sys_data_connected_roam :
+                            0;
+                }
+                int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
+                String level = args.getString("level");
+                if (level != null) {
+                    mDemoMobileLevel = level.equals("null") ? -1
+                            : Math.min(Integer.parseInt(level), icons[0].length - 1);
+                }
+                int iconId = mDemoMobileLevel < 0 ? R.drawable.stat_sys_signal_null :
+                        icons[mDemoInetCondition][mDemoMobileLevel];
+                for (SignalCluster cluster : mSignalClusters) {
+                    cluster.setMobileDataIndicators(
+                            show,
+                            iconId,
+                            mDemoDataTypeIconId,
+                            "Demo",
+                            "Demo");
+                }
+            }
+        }
+    }
 }
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 95c768f..de29155 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1156,6 +1156,8 @@
         if (changesMade) {
             mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION),
                     UserHandle.ALL);
+            mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION),
+                    UserHandle.ALL);
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 4678b85..75cf5d0 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -407,12 +407,13 @@
         @Override
         public void run() {
             if (activityExtras == null) {
-                Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
+                Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from activtity "
+                        + activity);
             }
             for (int i = 0; i < services.size(); i++) {
                 if (servicesExtras[i] == null) {
-                    Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from "
-                            + services.get(i));
+                    Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from service "
+                            + i + " " + services.get(i));
                 }
             }
             synchronized (this) {
@@ -6517,8 +6518,11 @@
                     }
                 }
                 final long origId = Binder.clearCallingIdentity();
-                stack.moveTaskToBackLocked(taskId, null);
-                Binder.restoreCallingIdentity(origId);
+                try {
+                    stack.moveTaskToBackLocked(taskId, null);
+                } finally {
+                    Binder.restoreCallingIdentity(origId);
+                }
             }
         }
     }
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2fefadf..8d27c5c 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -255,7 +255,7 @@
         //public Handler() {
         //    if (localLOGV) Slog.v(TAG, "Handler started!");
         //}
-        public ActivityStackHandler(Looper looper) {
+        ActivityStackHandler(Looper looper) {
             super(looper);
         }
 
@@ -331,7 +331,6 @@
         mWindowManager = service.mWindowManager;
         mStackSupervisor = service.mStackSupervisor;
         mContext = context;
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mStackId = stackId;
         mCurrentUser = service.mCurrentUserId;
     }
@@ -837,7 +836,7 @@
         }
     }
 
-    private final void completePauseLocked() {
+    private void completePauseLocked() {
         ActivityRecord prev = mPausingActivity;
         if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
 
@@ -1765,7 +1764,7 @@
         for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
             TaskRecord task = mTaskHistory.get(taskNdx);
             final ArrayList<ActivityRecord> activities = task.mActivities;
-            if (activities.size() == 0) {
+            if (activities.isEmpty()) {
                 continue;
             }
             TaskGroup group = new TaskGroup();
@@ -2335,7 +2334,7 @@
 
         finishActivityResultsLocked(r, resultCode, resultData);
 
-        if (mService.mPendingThumbnails.size() > 0) {
+        if (!mService.mPendingThumbnails.isEmpty()) {
             // There are clients waiting to receive thumbnails so, in case
             // this is an activity that someone is waiting for, add it
             // to the pending list so we can correctly update the clients.
@@ -2561,7 +2560,7 @@
             cleanUpActivityServicesLocked(r);
         }
 
-        if (mService.mPendingThumbnails.size() > 0) {
+        if (!mService.mPendingThumbnails.isEmpty()) {
             // There are clients waiting to receive thumbnails so, in case
             // this is an activity that someone is waiting for, add it
             // to the pending list so we can correctly update the clients.
@@ -2698,7 +2697,7 @@
                     mService.mHandler.sendEmptyMessage(
                             ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
                 }
-                if (r.app.activities.size() == 0) {
+                if (r.app.activities.isEmpty()) {
                     // No longer have activities, so update oom adj.
                     mService.updateOomAdjLocked();
                 }
@@ -3009,9 +3008,38 @@
         if (tr == null) {
             return false;
         }
+
         mTaskHistory.remove(tr);
         mTaskHistory.add(0, tr);
 
+        // There is an assumption that moving a task to the back moves it behind the home activity.
+        // We make sure here that some activity in the stack will launch home.
+        ActivityRecord lastActivity = null;
+        int numTasks = mTaskHistory.size();
+        int taskNdx;
+        for (taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            int activityNdx;
+            for (activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.mLaunchHomeTaskNext) {
+                    break;
+                }
+                if (taskNdx == 1 && activityNdx == 0) {
+                    // Final activity before tr task.
+                    lastActivity = r;
+                }
+            }
+            if (activityNdx >= 0) {
+                // Early exit, we found an activity that will launchHomeTaskNext.
+                break;
+            }
+        }
+        if (lastActivity != null) {
+            // No early exit, we did not find an activity that will launchHomeTaskNext, set one.
+            lastActivity.mLaunchHomeTaskNext = true;
+        }
+
         if (reason != null &&
                 (reason.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
             mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
@@ -3020,8 +3048,7 @@
                 mNoAnimActivities.add(r);
             }
         } else {
-            mWindowManager.prepareAppTransition(
-                    AppTransition.TRANSIT_TASK_TO_BACK, false);
+            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false);
         }
         mWindowManager.moveTaskToBottom(task);
 
@@ -3029,9 +3056,8 @@
             validateAppTokensLocked();
         }
 
-        if (mResumedActivity != null && mResumedActivity.task == tr &&
-                mResumedActivity.mLaunchHomeTaskNext) {
-            // TODO: Can we skip the next line and just pass mResumedAct. to resumeHomeAct.()?
+        if (numTasks <= 1 || (mResumedActivity != null && mResumedActivity.task == tr &&
+                mResumedActivity.mLaunchHomeTaskNext)) {
             mResumedActivity.mLaunchHomeTaskNext = false;
             return mStackSupervisor.resumeHomeActivity(null);
         }
@@ -3175,7 +3201,7 @@
         return true;
     }
 
-    private final boolean relaunchActivityLocked(ActivityRecord r,
+    private boolean relaunchActivityLocked(ActivityRecord r,
             int changes, boolean andResume) {
         List<ResultInfo> results = null;
         List<Intent> newIntents = null;
@@ -3487,7 +3513,7 @@
 
     boolean removeTask(TaskRecord task) {
         mTaskHistory.remove(task);
-        return mTaskHistory.size() == 0;
+        return mTaskHistory.isEmpty();
     }
 
     TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 12cad7b..0dd950e 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -481,7 +481,7 @@
     
     private void dumpHelp(PrintWriter pw) {
         pw.println("Battery stats (batterystats) dump options:");
-        pw.println("  [--checkin] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
+        pw.println("  [--checkin] [-c] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
         pw.println("  --checkin: format output for a checkin report.");
         pw.println("  --unplugged: only output data since last unplugged.");
         pw.println("  --reset: reset the stats, clearing all current data.");
@@ -501,6 +501,7 @@
         }
 
         boolean isCheckin = false;
+        boolean includeHistory = false;
         boolean isUnpluggedOnly = false;
         boolean noOutput = false;
         int reqUid = -1;
@@ -508,6 +509,9 @@
             for (String arg : args) {
                 if ("--checkin".equals(arg)) {
                     isCheckin = true;
+                } else if ("-c".equals(arg)) {
+                    isCheckin = true;
+                    includeHistory = true;
                 } else if ("--unplugged".equals(arg)) {
                     isUnpluggedOnly = true;
                 } else if ("--reset".equals(arg)) {
@@ -550,7 +554,7 @@
         if (isCheckin) {
             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
             synchronized (mStats) {
-                mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly);
+                mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly, includeHistory);
             }
         } else {
             synchronized (mStats) {
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index 4ba26fb..55409c2 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -677,11 +677,9 @@
                                 if (checkedIn) pw.print(" (checked in)");
                                 pw.println(":");
                                 // Don't really need to lock because we uniquely own this object.
-                                if (dumpDetails) {
-                                    processStats.dumpLocked(pw, reqPackage, now, dumpAll);
-                                } else {
-                                    processStats.dumpSummaryLocked(pw, reqPackage, now);
-                                }
+                                // Always dump summary here, dumping all details is just too
+                                // much crud.
+                                processStats.dumpSummaryLocked(pw, reqPackage, now);
                             }
                             if (isCheckin) {
                                 // Rename file suffix to mark that it has checked in.
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index cd201f5..9a4cfb7 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -150,6 +150,8 @@
 
     // Certification
     private boolean mWifiDisplayCertMode;
+    private int mWifiDisplayWpsConfig = WpsInfo.INVALID;
+
     private WifiP2pDevice mThisDevice;
 
     public WifiDisplayController(Context context, Handler handler, Listener listener) {
@@ -179,6 +181,8 @@
                 Settings.Global.WIFI_DISPLAY_ON), false, settingsObserver);
         resolver.registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON), false, settingsObserver);
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.WIFI_DISPLAY_WPS_CONFIG), false, settingsObserver);
         updateSettings();
     }
 
@@ -189,6 +193,12 @@
         mWifiDisplayCertMode = Settings.Global.getInt(resolver,
                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0;
 
+        mWifiDisplayWpsConfig = WpsInfo.INVALID;
+        if (mWifiDisplayCertMode) {
+            mWifiDisplayWpsConfig = Settings.Global.getInt(resolver,
+                  Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
+        }
+
         updateWfdEnableState();
     }
 
@@ -286,6 +296,25 @@
             }
         } else {
             // WFD should be disabled.
+            if (mWfdEnabled || mWfdEnabling) {
+                WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
+                wfdInfo.setWfdEnabled(false);
+                mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+                    @Override
+                    public void onSuccess() {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Successfully set WFD info.");
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(int reason) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Failed to set WFD info with reason " + reason + ".");
+                        }
+                    }
+                });
+            }
             mWfdEnabling = false;
             mWfdEnabled = false;
             reportFeatureState();
@@ -589,7 +618,9 @@
             mConnectingDevice = mDesiredDevice;
             WifiP2pConfig config = new WifiP2pConfig();
             WpsInfo wps = new WpsInfo();
-            if (mConnectingDevice.wpsPbcSupported()) {
+            if (mWifiDisplayWpsConfig != WpsInfo.INVALID) {
+                wps.setup = mWifiDisplayWpsConfig;
+            } else if (mConnectingDevice.wpsPbcSupported()) {
                 wps.setup = WpsInfo.PBC;
             } else if (mConnectingDevice.wpsDisplaySupported()) {
                 // We do keypad if peer does display
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index ff1128d..415cda1 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1385,6 +1385,11 @@
 
                 StringBuilder sb = new StringBuilder();
                 for (final PackageSetting pkg : mPackages.values()) {
+                    if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
+                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
+                        continue;
+                    }
+
                     final ApplicationInfo ai = pkg.pkg.applicationInfo;
                     final String dataPath = ai.dataDir;
                     final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index c661b00..4be11b8 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -96,6 +96,7 @@
     public static final int CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA = BASE + 36;
     public static final int CMD_ENABLE_MOBILE_PROVISIONING = BASE + 37;
     public static final int CMD_IS_PROVISIONING_APN = BASE + 38;
+    public static final int EVENT_PROVISIONING_APN_ALARM = BASE + 39;
 
     /***** Constants *****/
 
diff --git a/tests/TransitionTests/res/scene/incorrect_password_scene.xml b/tests/TransitionTests/res/scene/incorrect_password_scene.xml
deleted file mode 100644
index a31ad22..0000000
--- a/tests/TransitionTests/res/scene/incorrect_password_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/incorrect_password"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/login_scene.xml b/tests/TransitionTests/res/scene/login_scene.xml
deleted file mode 100644
index b258303..0000000
--- a/tests/TransitionTests/res/scene/login_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/activity_login"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/new_user_scene.xml b/tests/TransitionTests/res/scene/new_user_scene.xml
deleted file mode 100644
index d6e5f0f..0000000
--- a/tests/TransitionTests/res/scene/new_user_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/new_user"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/password_scene.xml b/tests/TransitionTests/res/scene/password_scene.xml
deleted file mode 100644
index 99a0038..0000000
--- a/tests/TransitionTests/res/scene/password_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/login_password"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/results_scene.xml b/tests/TransitionTests/res/scene/results_scene.xml
deleted file mode 100644
index 9c9fc69..0000000
--- a/tests/TransitionTests/res/scene/results_scene.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/results_screen">
-</scene>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/search_scene.xml b/tests/TransitionTests/res/scene/search_scene.xml
deleted file mode 100644
index 742cd57..0000000
--- a/tests/TransitionTests/res/scene/search_scene.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/search_screen">
-</scene>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/success_scene.xml b/tests/TransitionTests/res/scene/success_scene.xml
deleted file mode 100644
index 3d76d89..0000000
--- a/tests/TransitionTests/res/scene/success_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout="@layout/success"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/colorizer_transition.xml b/tests/TransitionTests/res/transition/colorizer_transition.xml
index 731d7ee..12f4be7 100644
--- a/tests/TransitionTests/res/transition/colorizer_transition.xml
+++ b/tests/TransitionTests/res/transition/colorizer_transition.xml
@@ -1,6 +1,6 @@
-<recolor xmlns:android="http://schemas.android.com/apk/res/android">>
+<recolor xmlns:android="http://schemas.android.com/apk/res/android">
     <targets>
-        <target android:targetID="@id/password"/>
-        <target android:targetID="@id/passwordEdit"/>
+        <target android:targetId="@id/password"/>
+        <target android:targetId="@id/passwordEdit"/>
     </targets>
 </recolor>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/login_slider_transition.xml b/tests/TransitionTests/res/transition/login_slider_transition.xml
index dbdd6e9..2317857 100644
--- a/tests/TransitionTests/res/transition/login_slider_transition.xml
+++ b/tests/TransitionTests/res/transition/login_slider_transition.xml
@@ -1,21 +1,21 @@
-<transitionGroup xmlns:android="http://schemas.android.com/apk/res/android">
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
     <slide>
         <targets>
-            <target android:targetID="@id/retype"/>
-            <target android:targetID="@id/retypeEdit"/>
+            <target android:targetId="@id/retype"/>
+            <target android:targetId="@id/retypeEdit"/>
         </targets>
     </slide>
     <recolor>
         <targets>
-            <target android:targetID="@id/password"/>
-            <target android:targetID="@id/passwordEdit"/>
+            <target android:targetId="@id/password"/>
+            <target android:targetId="@id/passwordEdit"/>
         </targets>
     </recolor>
     <fade/>
-</transitionGroup>
+</transitionSet>
 
 <!--
-                TransitionGroup slider = new TransitionGroup();
+                TransitionSet slider = new TransitionSet();
         slider.addTransition(new Slide(R.id.retype, R.id.retypeEdit));
         slider.addTransition(new Recolor(R.id.password, R.id.passwordEdit));
         slider.addTransition(new Fade());
diff --git a/tests/TransitionTests/res/transition/login_transition_mgr.xml b/tests/TransitionTests/res/transition/login_transition_mgr.xml
index 8a8b9e9..5d07be0 100644
--- a/tests/TransitionTests/res/transition/login_transition_mgr.xml
+++ b/tests/TransitionTests/res/transition/login_transition_mgr.xml
@@ -1,39 +1,14 @@
 <transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
-    <transition fromScene="@scene/login_scene" toScene="@scene/new_user_scene"
-                transition="@transition/login_slider_transition"/>
-    <transition fromScene="@scene/password_scene" toScene="@scene/new_user_scene"
-                transition="@transition/login_slider_transition"/>
-    <transition fromScene="@scene/new_user_scene" toScene="@scene/login_scene"
-                transition="@transition/login_slider_transition"/>
-    <transition fromScene="@scene/new_user_scene" toScene="@scene/password_scene"
-                transition="@transition/login_slider_transition"/>
-    <transition fromScene="@scene/login_scene" toScene="@scene/password_scene"
-                transition="@transition/colorizer_transition"/>
-    <transition fromScene="@scene/password_scene" toScene="@scene/login_scene"
-                transition="@transition/colorizer_transition"/>
+    <transition android:fromScene="@layout/activity_login" android:toScene="@layout/new_user"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/login_password" android:toScene="@layout/new_user"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/new_user" android:toScene="@layout/activity_login"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/new_user" android:toScene="@layout/login_password"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/activity_login" android:toScene="@layout/login_password"
+                android:transition="@transition/colorizer_transition"/>
+    <transition android:fromScene="@layout/login_password" android:toScene="@layout/activity_login"
+                android:transition="@transition/colorizer_transition"/>
 </transitionManager>
-
-        <!--
-                        mLoginScene = new Scene(this, mSceneRoot, R.layout.activity_login);
-        mPasswordScene = new Scene(this, mSceneRoot, R.layout.login_password);
-        mIncorrectPasswordScene = new Scene(this, mSceneRoot, R.layout.incorrect_password);
-        mUsernameTakenScene = new Scene(this, mSceneRoot, R.layout.username_taken);
-        mSuccessScene = new Scene(this, mSceneRoot, R.layout.success);
-        mNewUserScene = new Scene(this, mSceneRoot, R.layout.new_user);
-
-        mTransitionManager = new TransitionManager();
-        // Custom transitions in/out of NewUser screen - slide in the 2nd password UI
-        TransitionGroup slider = new TransitionGroup();
-        slider.addTransition(new Slide(R.id.retype, R.id.retypeEdit));
-        slider.addTransition(new Recolor(R.id.password, R.id.passwordEdit));
-        slider.addTransition(new Fade());
-        mTransitionManager.setTransition(mLoginScene, mNewUserScene, slider);
-        mTransitionManager.setTransition(mPasswordScene, mNewUserScene, slider);
-        mTransitionManager.setTransition(mNewUserScene, mLoginScene, slider);
-        mTransitionManager.setTransition(mNewUserScene, mPasswordScene, slider);
-
-        // Custom transitions with recoloring password field
-        Transition colorizer = new Recolor(R.id.password, R.id.passwordEdit);
-        mTransitionManager.setTransition(mLoginScene, mPasswordScene, colorizer);
-        mTransitionManager.setTransition(mPasswordScene, mLoginScene, colorizer);
--->
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/mover.xml b/tests/TransitionTests/res/transition/mover.xml
index 3c47606..b23d2a5 100644
--- a/tests/TransitionTests/res/transition/mover.xml
+++ b/tests/TransitionTests/res/transition/mover.xml
@@ -1 +1 @@
-<move/>
\ No newline at end of file
+<changeBounds/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/mover_fader.xml b/tests/TransitionTests/res/transition/mover_fader.xml
index 8b805e9..ef11676 100644
--- a/tests/TransitionTests/res/transition/mover_fader.xml
+++ b/tests/TransitionTests/res/transition/mover_fader.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<transitionGroup xmlns:android="http://schemas.android.com/apk/res/android">
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
     <fade/>
-    <move/>
-</transitionGroup>
\ No newline at end of file
+    <changeBounds/>
+</transitionSet>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/my_scene.xml b/tests/TransitionTests/res/transition/my_scene.xml
similarity index 100%
rename from tests/TransitionTests/res/scene/my_scene.xml
rename to tests/TransitionTests/res/transition/my_scene.xml
diff --git a/tests/TransitionTests/res/transition/my_transition.xml b/tests/TransitionTests/res/transition/my_transition.xml
index 14c91b9..022313c 100644
--- a/tests/TransitionTests/res/transition/my_transition.xml
+++ b/tests/TransitionTests/res/transition/my_transition.xml
@@ -1,20 +1,20 @@
-<transitionGroup xmlns:android="http://schemas.android.com/apk/res/android">
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
     <fade></fade>
-    <transitionGroup>
-        <move android:duration="500">
+    <transitionSet>
+        <changeBounds android:duration="500">
             <targets>
-                <target android:targetID="@id/container"/>
-                <target android:targetID="@id/resultsList"/>
+                <target android:targetId="@id/container"/>
+                <target android:targetId="@id/resultsList"/>
             </targets>
-        </move>
-        <transitionGroup>
+        </changeBounds>
+        <transitionSet>
             <targets>
-                <target android:targetID="@id/container"/>
-                <target android:targetID="@id/resultsList"/>
+                <target android:targetId="@id/container"/>
+                <target android:targetId="@id/resultsList"/>
             </targets>
             <fade android:startOffset="25"/>
-        </transitionGroup>
+        </transitionSet>
         <recolor/>
-    </transitionGroup>
-    <move/>
-</transitionGroup>
\ No newline at end of file
+    </transitionSet>
+    <changeBounds/>
+</transitionSet>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/my_transition_mgr.xml b/tests/TransitionTests/res/transition/my_transition_mgr.xml
index ca9705a..5d8f799 100644
--- a/tests/TransitionTests/res/transition/my_transition_mgr.xml
+++ b/tests/TransitionTests/res/transition/my_transition_mgr.xml
@@ -1,6 +1,6 @@
 <transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
-    <transition fromScene="@scene/search_scene" toScene="@scene/results_scene"
-                transition="@transition/mover_fader"/>
-    <transition fromScene="@scene/results_scene" toScene="@scene/search_scene"
-                transition="@transition/mover_fader"/>
+    <transition android:fromScene="@layout/search_screen" android:toScene="@layout/results_screen"
+                android:transition="@transition/mover_fader"/>
+    <transition android:fromScene="@layout/results_screen" android:toScene="@layout/search_screen"
+                android:transition="@transition/mover_fader"/>
 </transitionManager>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/username_taken_scene.xml b/tests/TransitionTests/res/transition/username_taken_scene.xml
similarity index 100%
rename from tests/TransitionTests/res/scene/username_taken_scene.xml
rename to tests/TransitionTests/res/transition/username_taken_scene.xml
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
index 05bed5f..a1ddd74 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
@@ -19,42 +19,43 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.TextChange;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.ChangeBounds;
+import android.transition.TextChange;
+import android.transition.TransitionManager;
 
 public class ChangingText extends Activity {
 
     Scene mScene1, mScene2;
     ViewGroup mSceneRoot;
-    TransitionGroup mChanger;
+    TransitionSet mChanger;
+    Scene mCurrentScene;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.changing_text_1);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mScene1 = new Scene(mSceneRoot, R.layout.changing_text_1, this);
-        mScene2 = new Scene(mSceneRoot, R.layout.changing_text_2, this);
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.changing_text_1, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.changing_text_2, this);
 
-        mChanger = new TransitionGroup(TransitionGroup.TOGETHER);
-        mChanger.addTransitions(new Move(), new TextChange());
+        mChanger = new TransitionSet().setOrdering(TransitionSet.ORDERING_TOGETHER);
+        mChanger.addTransition(new ChangeBounds()).addTransition(new TextChange());
 
-        mSceneRoot.setCurrentScene(mScene1);
+        mCurrentScene = mScene1;
     }
 
     public void sendMessage(View view) {
-        if (mSceneRoot.getCurrentScene() == mScene1) {
+        if (mCurrentScene == mScene1) {
             TransitionManager.go(mScene2, mChanger);
+            mCurrentScene = mScene2;
         } else {
             TransitionManager.go(mScene1, mChanger);
+            mCurrentScene = mScene1;
         }
     }
 }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
index c3201f2..85702fa 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
@@ -17,15 +17,15 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
 import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.TextChange;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.TextChange;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 public class ClippingText extends Activity {
 
@@ -34,7 +34,8 @@
     ViewGroup mSceneRoot;
     //    static Fade sFade = new Fade(R.id.removingButton, R.id.invisibleButton, R.id.goneButton);
     Fade fader;
-    TransitionGroup mChanger;
+    TransitionSet mChanger;
+    Scene mCurrentScene;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -44,22 +45,24 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mScene1 = new Scene(mSceneRoot, R.layout.clipping_text_1, this);
-        mScene2 = new Scene(mSceneRoot, R.layout.clipping_text_2, this);
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_1, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_2, this);
 
-        mChanger = new TransitionGroup(TransitionGroup.TOGETHER);
-        Move move = new Move();
-        move.setResizeClip(true);
-        mChanger.addTransitions(move, new TextChange());
+        mChanger = new TransitionSet().setOrdering(TransitionSet.ORDERING_TOGETHER);
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setResizeClip(true);
+        mChanger.addTransition(changeBounds).addTransition(new TextChange());
 
-        mSceneRoot.setCurrentScene(mScene1);
+        mCurrentScene = mScene1;
     }
 
     public void sendMessage(View view) {
-        if (mSceneRoot.getCurrentScene() == mScene1) {
+        if (mCurrentScene == mScene1) {
             TransitionManager.go(mScene2, mChanger);
+            mCurrentScene = mScene2;
         } else {
             TransitionManager.go(mScene1, mChanger);
+            mCurrentScene = mScene1;
         }
     }
 }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
index c7da6a3..482dc05 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
@@ -18,19 +18,19 @@
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
+import android.transition.Fade;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
 import android.widget.ImageView;
 import android.widget.TextView;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Rotate;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.Rotate;
+import android.transition.TransitionManager;
 
 public class ContactsExpansion extends Activity {
 
@@ -42,7 +42,8 @@
 
     View currentItem = null;
 
-    TransitionGroup mMyAutoTransition = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+    TransitionSet mMyAutoTransition = new TransitionSet().
+            setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -73,11 +74,12 @@
         ((TextView)contactItem.findViewById(R.id.contact_email)).setText(contactsData[dataIndex++]);
         container.addView(contactItem);
 
-        final TransitionGroup myTransition = new TransitionGroup();
-        myTransition.addTransitions(new Fade(Fade.IN),
-                new Rotate().setTargetIds(R.id.contact_arrow),
-                new Move(), new Fade(Fade.OUT),
-                new Crossfade().setTargetIds(R.id.contact_picture));
+        final TransitionSet myTransition = new TransitionSet();
+        myTransition.addTransition(new Fade(Fade.IN)).
+                addTransition(new Rotate().addTargetId(R.id.contact_arrow)).
+                addTransition(new ChangeBounds()).
+                addTransition(new Fade(Fade.OUT)).
+                addTransition(new Crossfade().addTargetId(R.id.contact_picture));
         final ToggleScene toggleScene = new ToggleScene(container, myTransition);
         contactItem.setOnClickListener(new View.OnClickListener() {
             @Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
index d5f6a28..eb799ec 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
@@ -17,13 +17,13 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class CrossFadeDemo extends Activity {
@@ -41,16 +41,17 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mScene1 = new Scene(mSceneRoot, R.layout.crossfade, this);
-        mScene2 = new Scene(mSceneRoot, R.layout.crossfade_1, this);
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade_1, this);
 
         Crossfade crossfade = new Crossfade();
         crossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_CROSSFADE);
         crossfade.setResizeBehavior(Crossfade.RESIZE_BEHAVIOR_NONE);
-        crossfade.setTargetIds(R.id.textview, R.id.textview1, R.id.textview2);
+        crossfade.addTargetId(R.id.textview).addTargetId(R.id.textview1).
+                addTargetId(R.id.textview2);
         mTransitionManager = new TransitionManager();
-        TransitionGroup moveCrossFade = new TransitionGroup();
-        moveCrossFade.addTransitions(crossfade, new Move());
+        TransitionSet moveCrossFade = new TransitionSet();
+        moveCrossFade.addTransition(crossfade).addTransition(new ChangeBounds());
         mTransitionManager.setTransition(mScene1, moveCrossFade);
         mTransitionManager.setTransition(mScene2, moveCrossFade);
         mCurrentScene = 1;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
index 28e055f..09b495f 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
@@ -19,12 +19,12 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 import android.widget.ImageView;
 
 public class CrossfadeImage extends Activity {
@@ -48,11 +48,11 @@
         mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
 
         Crossfade mCrossfade = new Crossfade();
-        mCrossfade.setTargetIds(R.id.contact_picture);
+        mCrossfade.addTargetId(R.id.contact_picture);
 
-        TransitionGroup group = new TransitionGroup();
+        TransitionSet group = new TransitionSet();
         group.setDuration(1500);
-        group.addTransitions(mCrossfade, new Move());
+        group.addTransition(mCrossfade).addTransition(new ChangeBounds());
         mTransition = group;
     }
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
index b82dbd8..c1183987 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
@@ -17,14 +17,14 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.TextChange;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.TextChange;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -40,9 +40,9 @@
     TextView mTextView;
     Button mButton;
     Crossfade mCrossfade;
-    TransitionGroup mCrossfadeGroup;
-    TransitionGroup mTextChangeGroup1, mTextChangeGroup2;
-    TransitionGroup mInOutGroup;
+    TransitionSet mCrossfadeGroup;
+    TransitionSet mTextChangeGroup1, mTextChangeGroup2;
+    TransitionSet mInOutGroup;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -57,34 +57,35 @@
         mTextView = (TextView) findViewById(R.id.textview);
 
         mCrossfade = new Crossfade();
-        mCrossfade.setTargetIds(R.id.button, R.id.textview, R.id.imageview);
+        mCrossfade.addTargetId(R.id.button).addTargetId(R.id.textview).addTargetId(R.id.imageview);
 
-        mCrossfadeGroup = new TransitionGroup();
+        mCrossfadeGroup = new TransitionSet();
         mCrossfadeGroup.setDuration(300);
-        mCrossfadeGroup.addTransitions(mCrossfade, new Move());
+        mCrossfadeGroup.addTransition(mCrossfade).addTransition(new ChangeBounds());
         mTransition = mCrossfadeGroup;
 
-        mInOutGroup = new TransitionGroup();
+        mInOutGroup = new TransitionSet();
         Crossfade inOut = new Crossfade();
         inOut.setDuration(300);
         inOut.setFadeBehavior(Crossfade.FADE_BEHAVIOR_OUT_IN);
-        Move move = new Move();
-        move.setStartDelay(150);
-        move.setDuration(0);
-        mInOutGroup.addTransitions(inOut, move);
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setStartDelay(150);
+        changeBounds.setDuration(0);
+        mInOutGroup.addTransition(inOut).addTransition(changeBounds);
 
-        mTextChangeGroup1 = new TransitionGroup();
+        mTextChangeGroup1 = new TransitionSet();
         TextChange textChangeInOut = new TextChange();
         textChangeInOut.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT_IN);
-        mTextChangeGroup1.addTransitions(textChangeInOut, new Move());
+        mTextChangeGroup1.addTransition(textChangeInOut).addTransition(new ChangeBounds());
 
-        mTextChangeGroup2 = new TransitionGroup();
-        mTextChangeGroup2.setOrdering(TransitionGroup.SEQUENTIALLY);
+        mTextChangeGroup2 = new TransitionSet();
+        mTextChangeGroup2.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
         TextChange textChangeOut = new TextChange();
         textChangeOut.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT);
         TextChange textChangeIn = new TextChange();
         textChangeIn.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_IN);
-        mTextChangeGroup2.addTransitions(textChangeOut, new Move(), textChangeIn);
+        mTextChangeGroup2.addTransition(textChangeOut).addTransition(new ChangeBounds()).
+                addTransition(textChangeIn);
     }
 
     public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
index f05ea78..fe5f05a 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
@@ -19,7 +19,7 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
 import android.widget.Button;
 import android.widget.LinearLayout;
 import static android.widget.LinearLayout.LayoutParams;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
index ce7f439..5c0cd45 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
@@ -21,11 +21,11 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class Demo1 extends Activity {
@@ -69,9 +69,10 @@
     public void sendMessage(View view) {
         if (mFirstTime) {
             mFirstTime = false;
-            TransitionGroup transition = new TransitionGroup();
-            transition.addTransitions(new Fade().setTargetIds(R.id.resultsText, R.id.resultsList),
-                    new Move().setTargetIds(R.id.searchContainer));
+            TransitionSet transition = new TransitionSet();
+            transition.addTransition(new Fade().addTargetId(R.id.resultsText).
+                    addTargetId(R.id.resultsList)).
+                    addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
             mTransitionManager = new TransitionManager();
             mTransitionManager.setTransition(mSearchScreen, transition);
             mTransitionManager.setTransition(mResultsScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
index 7e1afab..334b777 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
@@ -19,13 +19,12 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionInflater;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 public class Demo2 extends Activity {
     ViewGroup mSceneRoot;
@@ -51,18 +50,17 @@
 //        mSearchScreen = new Scene(this, mSceneRoot, R.layout.search_screen);
 //        mResultsScreen = new Scene(this, mSceneRoot, R.layout.results_screen);
             try {
-                mSearchScreen = TransitionInflater.from(this).
-                        inflateScene(R.scene.search_scene, mSceneRoot);
-                mResultsScreen = TransitionInflater.from(this).
-                        inflateScene(R.scene.results_scene, mSceneRoot);
+                mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+                mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
             } catch (Exception e) {
                 System.out.println("Problem loading scene resource: " + e);
             }
 
-            TransitionGroup transition = new TransitionGroup();
-            transition.addTransitions(new Fade().setTargetIds(R.id.resultsText, R.id.resultsList),
-                    new Move().setTargetIds(R.id.searchContainer),
-                    new Recolor().setTargetIds(R.id.container));
+            TransitionSet transition = new TransitionSet();
+            transition.addTransition(new Fade().addTargetId(R.id.resultsText).
+                    addTargetId(R.id.resultsList)).
+                    addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
+                    addTransition(new Recolor().addTargetId(R.id.container));
             mTransitionManager = new TransitionManager();
             mTransitionManager.setTransition(mSearchScreen, transition);
             mTransitionManager.setTransition(mResultsScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
index b8daff5..0ffa1f5 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
@@ -17,14 +17,14 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class Demo3 extends Activity {
@@ -41,11 +41,11 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
 
-        TransitionGroup transition = new TransitionGroup();
-        transition.addTransitions(new Fade(), new Move(), new Recolor());
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new Fade()).addTransition(new ChangeBounds()).addTransition(new Recolor());
 
         mTransitionManager = new TransitionManager();
         mTransitionManager.setTransition(mSearchScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
index 8be54f5..d1c3358 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
@@ -17,14 +17,14 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class Demo4 extends Activity {
@@ -41,20 +41,22 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
 
-        TransitionGroup transitionToResults = new TransitionGroup();
+        TransitionSet transitionToResults = new TransitionSet();
         Fade fade = new Fade();
-        fade.setTargetIds(R.id.resultsText, R.id.resultsList);
+        fade.addTargetId(R.id.resultsText).addTargetId(R.id.resultsList);
         fade.setStartDelay(300);
         fade.setDuration(1000);
-        transitionToResults.addTransitions(fade, new Move().setTargetIds(R.id.searchContainer),
-                new Recolor().setTargetIds(R.id.container));
+        transitionToResults.addTransition(fade).
+                addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
+                addTransition(new Recolor().addTargetId(R.id.container));
 
-        TransitionGroup transitionToSearch = new TransitionGroup();
-        transitionToSearch.addTransitions(fade, new Move().setTargetIds(R.id.searchContainer),
-                new Recolor().setTargetIds(R.id.container));
+        TransitionSet transitionToSearch = new TransitionSet();
+        transitionToSearch.addTransition(fade).
+                addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
+                addTransition(new Recolor().addTargetId(R.id.container));
 
         mTransitionManager = new TransitionManager();
         mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
index e64511e..c36abda 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
@@ -19,8 +19,8 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 
 
 public class Demo5 extends Activity {
@@ -36,8 +36,8 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
 
     }
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
index e0fe379..d497abe 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
@@ -19,8 +19,7 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
 import android.widget.Button;
 
 public class FadingHierarchy extends Activity {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
index 400e994..000ea9b 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
@@ -19,10 +19,10 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
 import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.TransitionManager;
 
 
 public class FadingTest extends Activity {
@@ -31,9 +31,11 @@
     Scene mScene1, mScene2;
     ViewGroup mSceneRoot;
     static Fade sFade = new Fade();
+    Scene mCurrentScene;
 
     static {
-        sFade.setTargetIds(R.id.removingButton, R.id.invisibleButton, R.id.goneButton);
+        sFade.addTargetId(R.id.removingButton).addTargetId(R.id.invisibleButton).
+                addTargetId(R.id.goneButton);
     }
 
     @Override
@@ -56,17 +58,19 @@
             }
         });
 
-        mScene1 = new Scene(mSceneRoot, R.layout.fading_test, this);
-        mScene2 = new Scene(mSceneRoot, R.layout.fading_test_scene_2, this);
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
 
-        mSceneRoot.setCurrentScene(mScene1);
+        mCurrentScene = mScene1;
     }
 
     public void sendMessage(View view) {
-        if (mSceneRoot.getCurrentScene() == mScene1) {
+        if (mCurrentScene == mScene1) {
             TransitionManager.go(mScene2);
+            mCurrentScene = mScene2;
         } else {
             TransitionManager.go(mScene1);
+            mCurrentScene = mScene1;
         }
     }
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
index 093d7c1..1146e20 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
@@ -17,12 +17,12 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Move;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 import android.widget.Button;
 
 import static android.widget.LinearLayout.LayoutParams;
@@ -59,33 +59,37 @@
         //       group (sequentially)
         //          Move 3
         //          Move 4/5
-        TransitionGroup rootTransition = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+        TransitionSet rootTransition = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
 
         // button0
-        Transition move0 = new Move();
-        move0.setTargets(buttons[0]);
+        Transition move0 = new ChangeBounds();
+        move0.addTarget(buttons[0]);
 
         // buttons 1/2/3/4/5
-        TransitionGroup group12345 = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+        TransitionSet group12345 = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
 
         // buttons 1/2
-        TransitionGroup group12 = new TransitionGroup(TransitionGroup.TOGETHER);
-        Move move1 = new Move();
-        move1.setTargets(buttons[1]);
-        Move move2 = new Move();
-        move2.setTargets(buttons[2]);
-        group12.addTransitions(move1, move2);
+        TransitionSet group12 = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_TOGETHER);
+        ChangeBounds changeBounds1 = new ChangeBounds();
+        changeBounds1.addTarget(buttons[1]);
+        ChangeBounds changeBounds2 = new ChangeBounds();
+        changeBounds2.addTarget(buttons[2]);
+        group12.addTransition(changeBounds1).addTransition(changeBounds2);
 
-        TransitionGroup group345 = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
-        Move move3 = new Move();
-        move3.setTargets(buttons[3]);
-        Move move45 = new Move();
-        move45.setTargets(buttons[4], buttons[5]);
-        group345.addTransitions(move3, move45);
+        TransitionSet group345 = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        ChangeBounds changeBounds3 = new ChangeBounds();
+        changeBounds3.addTarget(buttons[3]);
+        ChangeBounds changeBounds45 = new ChangeBounds();
+        changeBounds45.addTarget(buttons[4]).addTarget(buttons[5]);
+        group345.addTransition(changeBounds3).addTransition(changeBounds45);
 
-        group12345.addTransitions(move0, group12, group345);
+        group12345.addTransition(move0).addTransition(group12).addTransition(group345);
 
-        rootTransition.addTransitions(group12345);
+        rootTransition.addTransition(group12345);
         rootTransition.setDuration(1000);
         mTransition = rootTransition;
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
index cf4ea9a..a06ba8f 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
@@ -16,16 +16,12 @@
 package com.android.transitiontests;
 
 import android.app.Activity;
-import android.content.Context;
 import android.os.Bundle;
-import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.ChangeBounds;
+import android.transition.TransitionManager;
 import android.widget.Button;
-import android.widget.RelativeLayout;
 
 import static android.widget.RelativeLayout.ALIGN_PARENT_LEFT;
 import static android.widget.RelativeLayout.ALIGN_PARENT_RIGHT;
@@ -46,23 +42,19 @@
     }
 
     public void sendMessage(final View view) {
-        TransitionManager.go(mSceneRoot, new Runnable() {
-            @Override
-            public void run() {
-                for (int i = 0; i < mSceneRoot.getChildCount(); ++i) {
-                    Button button = (Button) mSceneRoot.getChildAt(i);
-                    LayoutParams params = (LayoutParams) button.getLayoutParams();
-                    int rules[] = params.getRules();
-                    if (rules[ALIGN_PARENT_RIGHT] != 0) {
-                        params.removeRule(ALIGN_PARENT_RIGHT);
-                        params.addRule(ALIGN_PARENT_LEFT);
-                    } else {
-                        params.removeRule(ALIGN_PARENT_LEFT);
-                        params.addRule(ALIGN_PARENT_RIGHT);
-                    }
-                    button.setLayoutParams(params);
-                }
+        TransitionManager.beginDelayedTransition(mSceneRoot, new ChangeBounds().addTarget(view));
+        for (int i = 0; i < mSceneRoot.getChildCount(); ++i) {
+            Button button = (Button) mSceneRoot.getChildAt(i);
+            LayoutParams params = (LayoutParams) button.getLayoutParams();
+            int rules[] = params.getRules();
+            if (rules[ALIGN_PARENT_RIGHT] != 0) {
+                params.removeRule(ALIGN_PARENT_RIGHT);
+                params.addRule(ALIGN_PARENT_LEFT);
+            } else {
+                params.removeRule(ALIGN_PARENT_LEFT);
+                params.addRule(ALIGN_PARENT_RIGHT);
             }
-        }, new Move().setTargets(view));
+            button.setLayoutParams(params);
+        }
     }
 }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
index b380225..70257bb 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
@@ -17,15 +17,12 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.AutoTransition;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TextChange;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 import android.widget.RadioButton;
 
 public class InterruptionTest extends Activity {
@@ -35,7 +32,8 @@
     private Scene mScene2;
     private Scene mScene3;
     private Scene mScene4;
-    TransitionGroup mSequencedMove = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+    TransitionSet mSequencedMove = new TransitionSet().
+            setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -44,24 +42,22 @@
 
         ViewGroup sceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
 
-        mScene1 = new Scene(sceneRoot, R.layout.interruption_inner_1, this);
-        mScene2 = new Scene(sceneRoot, R.layout.interruption_inner_2, this);
-        mScene3 = new Scene(sceneRoot, R.layout.interruption_inner_3, this);
-        mScene4 = new Scene(sceneRoot, R.layout.interruption_inner_4, this);
+        mScene1 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_1, this);
+        mScene2 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_2, this);
+        mScene3 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_3, this);
+        mScene4 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_4, this);
 
         mScene1RB = (RadioButton) findViewById(R.id.scene1RB);
         mScene2RB = (RadioButton) findViewById(R.id.scene2RB);
         mScene3RB = (RadioButton) findViewById(R.id.scene3RB);
         mScene4RB = (RadioButton) findViewById(R.id.scene4RB);
 
-        sceneRoot.setCurrentScene(mScene1);
+        ChangeBounds changeBounds1 = new ChangeBounds();
+        changeBounds1.addTargetId(R.id.button);
+        ChangeBounds changeBounds2 = new ChangeBounds();
+        changeBounds2.addTargetId(R.id.button1);
 
-        Move move1 = new Move();
-        move1.setTargetIds(R.id.button);
-        Move move2 = new Move();
-        move2.setTargetIds(R.id.button1);
-
-        mSequencedMove.addTransitions(move1, move2);
+        mSequencedMove.addTransition(changeBounds1).addTransition(changeBounds2);
         mSequencedMove.setDuration(1000);
     }
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
index 87ee874..6629770 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
@@ -20,18 +20,18 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewTreeObserver;
-import android.view.transition.Fade;
-import android.view.transition.Scene;
+import android.transition.Fade;
+import android.transition.Scene;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.view.transition.AutoTransition;
-import android.view.transition.Move;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.AutoTransition;
+import android.transition.ChangeBounds;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -78,10 +78,11 @@
             }
         });
         final Transition myTransition = new AutoTransition();
-        final TransitionGroup noFadeIn = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+        final TransitionSet noFadeIn = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
         Fade fadeIn = new Fade(Fade.IN);
         fadeIn.setDuration(50);
-        noFadeIn.addTransitions(new Fade(Fade.OUT), new Move(), fadeIn);
+        noFadeIn.addTransition(new Fade(Fade.OUT)).addTransition(new ChangeBounds()).addTransition(fadeIn);
 
         myTransition.addListener(new Transition.TransitionListenerAdapter() {
             @Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
index 06fa9f4..34ec6cc 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
@@ -19,14 +19,14 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
 import android.widget.TextView;
-import android.view.transition.Fade;
-import android.view.transition.Recolor;
-import android.view.transition.Slide;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Slide;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class LoginActivity extends Activity {
@@ -43,32 +43,33 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mLoginScene = new Scene(mSceneRoot, R.layout.activity_login, this);
-        mPasswordScene = new Scene(mSceneRoot, R.layout.login_password, this);
-        mIncorrectPasswordScene = new Scene(mSceneRoot, R.layout.incorrect_password, this);
-        mUsernameTakenScene = new Scene(mSceneRoot, R.layout.username_taken, this);
-        mSuccessScene = new Scene(mSceneRoot, R.layout.success, this);
-        mNewUserScene = new Scene(mSceneRoot, R.layout.new_user, this);
+        mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
+        mPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.login_password, this);
+        mIncorrectPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.incorrect_password, this);
+        mUsernameTakenScene = Scene.getSceneForLayout(mSceneRoot, R.layout.username_taken, this);
+        mSuccessScene = Scene.getSceneForLayout(mSceneRoot, R.layout.success, this);
+        mNewUserScene = Scene.getSceneForLayout(mSceneRoot, R.layout.new_user, this);
 
         mTransitionManager = new TransitionManager();
 
         // Custom transitions in/out of NewUser screen - slide in the 2nd password UI
-        TransitionGroup slider = new TransitionGroup();
-        slider.addTransitions(new Slide().setTargetIds(R.id.retype, R.id.retypeEdit));
-        slider.addTransitions(new Recolor().setTargetIds(R.id.password, R.id.passwordEdit));
-        slider.addTransitions(new Fade());
+        TransitionSet slider = new TransitionSet();
+        slider.addTransition(new Slide().addTargetId(R.id.retype).addTargetId(R.id.retypeEdit));
+        slider.addTransition(new Recolor().addTargetId(R.id.password).
+                addTargetId(R.id.passwordEdit));
+        slider.addTransition(new Fade());
         mTransitionManager.setTransition(mLoginScene, mNewUserScene, slider);
         mTransitionManager.setTransition(mPasswordScene, mNewUserScene, slider);
         mTransitionManager.setTransition(mNewUserScene, mLoginScene, slider);
         mTransitionManager.setTransition(mNewUserScene, mPasswordScene, slider);
 
         // Custom transitions with recoloring password field
-        Transition colorizer = new Recolor().setTargetIds(R.id.password, R.id.passwordEdit);
+        Transition colorizer = new Recolor().addTargetId(R.id.password).
+                addTargetId(R.id.passwordEdit);
         mTransitionManager.setTransition(mLoginScene, mPasswordScene, colorizer);
         mTransitionManager.setTransition(mPasswordScene, mLoginScene, colorizer);
 
         mCurrentScene = mLoginScene;
-        mSceneRoot.setCurrentScene(mLoginScene);
     }
 
     public void applyScene(Scene scene) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
index ff617aa..600c791 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
@@ -19,10 +19,10 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionInflater;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
 import android.widget.TextView;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
 
 
 public class LoginActivityFromResources extends Activity {
@@ -36,7 +36,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_login);
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
     }
@@ -50,21 +50,19 @@
         if (mTransitionManager == null) {
             TransitionInflater inflater = TransitionInflater.from(this);
 
-            mLoginScene = inflater.inflateScene(R.scene.login_scene, mSceneRoot);
-            mPasswordScene = inflater.inflateScene(R.scene.password_scene, mSceneRoot);
-            mIncorrectPasswordScene =
-                    inflater.inflateScene(R.scene.incorrect_password_scene,mSceneRoot);
-            mUsernameTakenScene =
-                    inflater.inflateScene(R.scene.username_taken_scene, mSceneRoot);
-            mSuccessScene = inflater.inflateScene(R.scene.success_scene, mSceneRoot);
-            mNewUserScene = inflater.inflateScene(R.scene.new_user_scene, mSceneRoot);
+            mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
+            mPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.login_password, this);
+            mIncorrectPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout
+                    .incorrect_password, this);
+            mUsernameTakenScene = Scene.getSceneForLayout(mSceneRoot, R.layout.username_taken, this);
+            mSuccessScene = Scene.getSceneForLayout(mSceneRoot, R.layout.success, this);
+            mNewUserScene = Scene.getSceneForLayout(mSceneRoot, R.layout.new_user, this);
 
             mTransitionManager =
                     inflater.inflateTransitionManager(R.transition.login_transition_mgr,
                             mSceneRoot);
 
             mCurrentScene = mLoginScene;
-            mSceneRoot.setCurrentScene(mLoginScene);
         }
         TextView textView = (TextView) view;
         CharSequence text = textView.getText();
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
index e559c72..1ee8621 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
@@ -17,11 +17,11 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 import android.widget.Button;
 
 public class Reparenting extends Activity {
@@ -67,7 +67,7 @@
                     newParent.addView(v);
                 }
             });
-            Move reparent = new Move();
+            ChangeBounds reparent = new ChangeBounds();
             reparent.setReparent(true);
             TransitionManager.go(newScene, reparent);
         }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
index 3d7bd9b..1aee258 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
@@ -19,10 +19,10 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionInflater;
-import android.view.transition.Transition;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 
 
 public class ResourceLoadingTest extends Activity {
@@ -54,7 +54,7 @@
                 mTransitionManager =
                         inflater.inflateTransitionManager(R.transition.my_transition_mgr,
                                 mSceneRoot);
-                Scene loadedScene = inflater.inflateScene(R.scene.my_scene, mSceneRoot);
+                Scene loadedScene = new Scene(mSceneRoot);
                 System.out.println("loadedScene = " + loadedScene);
                 Transition loadedTransition = inflater.inflateTransition(R.transition.my_transition);
                 System.out.println("loadedTransition = " + loadedTransition);
@@ -63,11 +63,11 @@
             }
         }
         if (mCurrentScene == RESULTS_SCREEN) {
-            Scene scene = mInflater.inflateScene(R.scene.search_scene, mSceneRoot);
+            Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
             mTransitionManager.transitionTo(scene);
             mCurrentScene = SEARCH_SCREEN;
         } else {
-            Scene scene = mInflater.inflateScene(R.scene.results_scene, mSceneRoot);
+            Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
             mTransitionManager.transitionTo(scene);
             mCurrentScene = RESULTS_SCREEN;
         }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
index 374a9ab..7504058 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
@@ -18,14 +18,14 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class ScenesTestAutoTargets extends Activity {
@@ -42,11 +42,11 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
 
-        TransitionGroup transition = new TransitionGroup();
-        transition.addTransitions(new Fade(), new Move(), new Recolor());
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new Fade()).addTransition(new ChangeBounds()).addTransition(new Recolor());
 
         mTransitionManager = new TransitionManager();
         mTransitionManager.setTransition(mSearchScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
index fb1ba07..23b28ec 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
@@ -20,10 +20,10 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.AutoTransition;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
-import android.view.transition.TransitionManager;
+import android.transition.AutoTransition;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 
 
 public class ScenesTestAutoTransition extends Activity {
@@ -40,8 +40,8 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
     }
 
     public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
index c75d419..5a9fa9d 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
@@ -20,8 +20,8 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 
 
 public class ScenesTestAutoTransition2 extends Activity {
@@ -38,8 +38,8 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
     }
 
     public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
index 399c2be..c6011f2 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
@@ -18,14 +18,14 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 
 
 public class ScenesTestv21 extends Activity {
@@ -42,21 +42,22 @@
         View container = (View) findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
-        mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
 
-        TransitionGroup transitionToResults = new TransitionGroup();
+        TransitionSet transitionToResults = new TransitionSet();
         Fade fade = new Fade();
-        fade.setTargetIds(R.id.resultsText, R.id.resultsList);
+        fade.addTargetId(R.id.resultsText).addTargetId(R.id.resultsList);
         fade.setStartDelay(300);
-        transitionToResults.addTransitions(fade);
-        transitionToResults.addTransitions(new Move().setTargetIds(R.id.searchContainer));
-        transitionToResults.addTransitions(new Recolor().setTargetIds(R.id.container));
+        transitionToResults.addTransition(fade);
+        transitionToResults.addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
+        transitionToResults.addTransition(new Recolor().addTargetId(R.id.container));
 
-        TransitionGroup transitionToSearch = new TransitionGroup();
-        transitionToSearch.addTransitions(new Fade().setTargetIds(R.id.resultsText, R.id.resultsList));
-        transitionToSearch.addTransitions(new Move().setTargetIds(R.id.searchContainer));
-        transitionToSearch.addTransitions(new Recolor().setTargetIds(R.id.container));
+        TransitionSet transitionToSearch = new TransitionSet();
+        transitionToSearch.addTransition(new Fade().addTargetId(R.id.resultsText).
+                addTargetId(R.id.resultsList));
+        transitionToSearch.addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
+        transitionToSearch.addTransition(new Recolor().addTargetId(R.id.container));
         mTransitionManager = new TransitionManager();
         mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
         mTransitionManager.setTransition(mResultsScreen, transitionToResults);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
index 6b34420..ab1dc26 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
@@ -19,13 +19,13 @@
 import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
 import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.TransitionManager;
 
 
 public class SequenceTest extends Activity {
@@ -33,7 +33,8 @@
     Button mRemovingButton, mInvisibleButton, mGoneButton;
     Scene mScene1, mScene2;
     ViewGroup mSceneRoot;
-    TransitionGroup sequencedFade, reverseSequencedFade;
+    TransitionSet sequencedFade, reverseSequencedFade;
+    Scene mCurrentScene;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -47,27 +48,33 @@
         mInvisibleButton = (Button) findViewById(R.id.invisibleButton);
         mGoneButton = (Button) findViewById(R.id.goneButton);
 
-        mScene1 = new Scene(mSceneRoot, R.layout.fading_test, this);
-        mScene2 = new Scene(mSceneRoot, R.layout.fading_test_scene_2, this);
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
 
-        Transition fade1 = new Fade().setTargetIds(R.id.removingButton);
-        Transition fade2 = new Fade().setTargetIds(R.id.invisibleButton);
-        Transition fade3 = new Fade().setTargetIds(R.id.goneButton);
-        TransitionGroup fader = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
-        fader.addTransitions(fade1, fade2, fade3, new Move());
+        Transition fade1 = new Fade().addTargetId(R.id.removingButton);
+        Transition fade2 = new Fade().addTargetId(R.id.invisibleButton);
+        Transition fade3 = new Fade().addTargetId(R.id.goneButton);
+        TransitionSet fader = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        fader.addTransition(fade1).addTransition(fade2).addTransition(fade3).
+                addTransition(new ChangeBounds());
         sequencedFade = fader;
 
-        reverseSequencedFade = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
-        reverseSequencedFade.addTransitions(new Move(), fade3, fade2, fade1);
+        reverseSequencedFade = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        reverseSequencedFade.addTransition(new ChangeBounds()).addTransition(fade3).addTransition(fade2).
+                addTransition(fade1);
 
-        mSceneRoot.setCurrentScene(mScene1);
+        mCurrentScene = mScene1;
     }
 
     public void sendMessage(View view) {
-        if (mSceneRoot.getCurrentScene() == mScene1) {
+        if (mCurrentScene == mScene1) {
             TransitionManager.go(mScene2, sequencedFade);
+            mCurrentScene = mScene2;
         } else {
             TransitionManager.go(mScene1, reverseSequencedFade);
+            mCurrentScene = mScene1;
         }
     }
 }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
index 972d30e..52c21c9 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
@@ -17,15 +17,15 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.transition.ChangeBounds;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
+import android.transition.TransitionSet;
 import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 
 
 public class SequenceTestSimple extends Activity {
@@ -34,7 +34,8 @@
     Scene mScene1, mScene2;
     ViewGroup mSceneRoot;
     Transition sequencedFade;
-    TransitionGroup sequencedFadeReverse;
+    TransitionSet sequencedFadeReverse;
+    Scene mCurrentScene;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -46,25 +47,29 @@
 
         mRemovingButton = (Button) findViewById(R.id.removingButton);
 
-        mScene1 = new Scene(mSceneRoot, R.layout.fading_test_simple, this);
-        mScene2 = new Scene(mSceneRoot, R.layout.fading_test_simple2, this);
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple2, this);
 
-        TransitionGroup fader = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
-        fader.addTransitions(new Fade().setTargetIds(R.id.removingButton));
-        fader.addTransitions(new Move().setTargetIds(R.id.sceneSwitchButton));
+        TransitionSet fader = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        fader.addTransition(new Fade().addTargetId(R.id.removingButton));
+        fader.addTransition(new ChangeBounds().addTargetId(R.id.sceneSwitchButton));
         sequencedFade = fader;
 
-        sequencedFadeReverse = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
-        sequencedFadeReverse.addTransitions(new Move().setTargetIds(R.id.sceneSwitchButton));
-        sequencedFadeReverse.addTransitions(new Fade().setTargetIds(R.id.removingButton));
+        sequencedFadeReverse = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        sequencedFadeReverse.addTransition(new ChangeBounds().addTargetId(R.id.sceneSwitchButton));
+        sequencedFadeReverse.addTransition(new Fade().addTargetId(R.id.removingButton));
 
-        mSceneRoot.setCurrentScene(mScene1);
+        mCurrentScene = mScene1;
     }
 
     public void sendMessage(View view) {
-        if (mSceneRoot.getCurrentScene() == mScene1) {
+        if (mCurrentScene == mScene1) {
             TransitionManager.go(mScene2, sequencedFade);
+            mCurrentScene = mScene2;
         } else {
             TransitionManager.go(mScene1, sequencedFadeReverse);
+            mCurrentScene = mScene1;
         }
     }}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
index aa76923..05af044 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
@@ -27,11 +27,11 @@
 import android.view.TextureView;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
 import android.widget.Button;
 
 import static android.widget.LinearLayout.LayoutParams;
@@ -66,8 +66,9 @@
         mTextureView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
         container.addView(mTextureView);
 
-        final TransitionGroup transition = new TransitionGroup();
-        transition.addTransitions(new Move(), new Crossfade().setTargetIds(0, 1, 2));
+        final TransitionSet transition = new TransitionSet();
+        transition.addTransition(new ChangeBounds()).addTransition(new Crossfade().addTargetId(0).
+                addTargetId(1).addTargetId(2));
 
         toggleButton.setOnClickListener(new View.OnClickListener() {
             @Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
index 433a91c4..c824956 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
@@ -20,11 +20,11 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
+import android.transition.Scene;
+import android.transition.Transition;
 import android.widget.Button;
 import android.widget.LinearLayout;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
 
 
 import java.util.HashMap;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index d617928..08ad7a0 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -172,7 +172,7 @@
 bool isValidResourceType(const String8& type)
 {
     return type == "anim" || type == "animator" || type == "interpolator"
-        || type == "transition" || type == "scene"
+        || type == "transition"
         || type == "drawable" || type == "layout"
         || type == "values" || type == "xml" || type == "raw"
         || type == "color" || type == "menu" || type == "mipmap";
@@ -934,7 +934,6 @@
     sp<ResourceTypeSet> animators;
     sp<ResourceTypeSet> interpolators;
     sp<ResourceTypeSet> transitions;
-    sp<ResourceTypeSet> scenes;
     sp<ResourceTypeSet> xmls;
     sp<ResourceTypeSet> raws;
     sp<ResourceTypeSet> colors;
@@ -947,7 +946,6 @@
     ASSIGN_IT(animator);
     ASSIGN_IT(interpolator);
     ASSIGN_IT(transition);
-    ASSIGN_IT(scene);
     ASSIGN_IT(xml);
     ASSIGN_IT(raw);
     ASSIGN_IT(color);
@@ -971,7 +969,6 @@
             !applyFileOverlay(bundle, assets, &animators, "animator") ||
             !applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
             !applyFileOverlay(bundle, assets, &transitions, "transition") ||
-            !applyFileOverlay(bundle, assets, &scenes, "scene") ||
             !applyFileOverlay(bundle, assets, &xmls, "xml") ||
             !applyFileOverlay(bundle, assets, &raws, "raw") ||
             !applyFileOverlay(bundle, assets, &colors, "color") ||
@@ -1038,13 +1035,6 @@
         }
     }
 
-    if (scenes != NULL) {
-        err = makeFileResources(bundle, assets, &table, scenes, "scene");
-        if (err != NO_ERROR) {
-            hasErrors = true;
-        }
-    }
-
     if (interpolators != NULL) {
         err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
         if (err != NO_ERROR) {
@@ -1204,21 +1194,6 @@
         err = NO_ERROR;
     }
 
-    if (scenes != NULL) {
-        ResourceDirIterator it(scenes, String8("scene"));
-        while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
-            if (err != NO_ERROR) {
-                hasErrors = true;
-            }
-        }
-
-        if (err < NO_ERROR) {
-            hasErrors = true;
-        }
-        err = NO_ERROR;
-    }
-
     if (xmls != NULL) {
         ResourceDirIterator it(xmls, String8("xml"));
         while ((err=it.next()) == NO_ERROR) {