Merge "AudioService: synchronized access to volume index" into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 40f92ba..ffe994e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -315,7 +315,6 @@
     field public static final int cacheColorHint = 16843009; // 0x1010101
     field public static final int calendarViewShown = 16843596; // 0x101034c
     field public static final int calendarViewStyle = 16843613; // 0x101035d
-    field public static final int canHandleGestures = 16843691; // 0x10103ab
     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
@@ -754,7 +753,7 @@
     field public static final int pathPrefix = 16842795; // 0x101002b
     field public static final int permission = 16842758; // 0x1010006
     field public static final int permissionGroup = 16842762; // 0x101000a
-    field public static final int permissionGroupFlags = 16843692; // 0x10103ac
+    field public static final int permissionGroupFlags = 16843691; // 0x10103ab
     field public static final int persistent = 16842765; // 0x101000d
     field public static final int persistentDrawingCache = 16842990; // 0x10100ee
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
@@ -2033,8 +2032,6 @@
     field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7
     field public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; // 0xd
     field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; // 0xe
-    field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18; // 0x12
-    field public static final int GESTURE_TWO_FINGER_TAP = 17; // 0x11
     field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
     field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
     field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
@@ -2048,7 +2045,6 @@
     method public int describeContents();
     method public static java.lang.String feedbackTypeToString(int);
     method public static java.lang.String flagToString(int);
-    method public boolean getCanHandleGestures();
     method public boolean getCanRetrieveWindowContent();
     method public deprecated java.lang.String getDescription();
     method public java.lang.String getId();
@@ -2064,7 +2060,8 @@
     field public static final int FEEDBACK_HAPTIC = 2; // 0x2
     field public static final int FEEDBACK_SPOKEN = 1; // 0x1
     field public static final int FEEDBACK_VISUAL = 8; // 0x8
-    field public static final int INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public int eventTypes;
     field public int feedbackType;
     field public int flags;
@@ -2823,6 +2820,7 @@
     field public long availMem;
     field public boolean lowMemory;
     field public long threshold;
+    field public long totalMem;
   }
 
   public static class ActivityManager.ProcessErrorStateInfo implements android.os.Parcelable {
@@ -3724,10 +3722,6 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
-    field public static final java.lang.String KIND_CALL = "android.call";
-    field public static final java.lang.String KIND_EMAIL = "android.email";
-    field public static final java.lang.String KIND_EVENT = "android.event";
-    field public static final java.lang.String KIND_MESSAGE = "android.message";
     field public static final java.lang.String KIND_PROMO = "android.promo";
     field public static final int PRIORITY_DEFAULT = 0; // 0x0
     field public static final int PRIORITY_HIGH = 1; // 0x1
@@ -3745,7 +3739,6 @@
     field public android.app.PendingIntent fullScreenIntent;
     field public int icon;
     field public int iconLevel;
-    field public java.lang.String[] kind;
     field public android.graphics.Bitmap largeIcon;
     field public int ledARGB;
     field public int ledOffMS;
@@ -3780,7 +3773,6 @@
   public static class Notification.Builder {
     ctor public Notification.Builder(android.content.Context);
     method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
-    method public android.app.Notification.Builder addKind(java.lang.String);
     method public android.app.Notification build();
     method public deprecated android.app.Notification getNotification();
     method public android.app.Notification.Builder setAutoCancel(boolean);
@@ -5121,6 +5113,8 @@
     ctor public ContentResolver(android.content.Context);
     method public final android.content.ContentProviderClient acquireContentProviderClient(android.net.Uri);
     method public final android.content.ContentProviderClient acquireContentProviderClient(java.lang.String);
+    method public final android.content.ContentProviderClient acquireUnstableContentProviderClient(android.net.Uri);
+    method public final android.content.ContentProviderClient acquireUnstableContentProviderClient(java.lang.String);
     method public static void addPeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle, long);
     method public static java.lang.Object addStatusChangeListener(int, android.content.SyncStatusObserver);
     method public android.content.ContentProviderResult[] applyBatch(java.lang.String, java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
@@ -7016,9 +7010,9 @@
     method public void unregisterDataSetObserver(android.database.DataSetObserver);
     field protected boolean mClosed;
     field protected android.content.ContentResolver mContentResolver;
-    field protected java.lang.Long mCurrentRowID;
+    field protected deprecated java.lang.Long mCurrentRowID;
     field protected int mPos;
-    field protected int mRowIdColumnIndex;
+    field protected deprecated int mRowIdColumnIndex;
     field protected deprecated java.util.HashMap mUpdatedRows;
   }
 
@@ -11236,7 +11230,6 @@
     method public void unselectTrack(int);
     field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
     field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
-    field public static final int SEEK_TO_CLOSEST = 3; // 0x3
     field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2
     field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1
     field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
@@ -11263,6 +11256,7 @@
     field public static final java.lang.String KEY_CHANNEL_MASK = "channel-mask";
     field public static final java.lang.String KEY_COLOR_FORMAT = "color-format";
     field public static final java.lang.String KEY_DURATION = "durationUs";
+    field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
     field public static final java.lang.String KEY_FRAME_RATE = "frame-rate";
     field public static final java.lang.String KEY_HEIGHT = "height";
     field public static final java.lang.String KEY_IS_ADTS = "is-adts";
@@ -12493,7 +12487,7 @@
     method public abstract boolean isHierarchical();
     method public boolean isOpaque();
     method public abstract boolean isRelative();
-    method public android.net.Uri normalize();
+    method public android.net.Uri normalizeScheme();
     method public static android.net.Uri parse(java.lang.String);
     method public abstract java.lang.String toString();
     method public static android.net.Uri withAppendedPath(android.net.Uri, java.lang.String);
@@ -12709,8 +12703,45 @@
 
 package android.net.nsd {
 
-  public class DnsSdServiceInfo implements android.os.Parcelable {
-    ctor public DnsSdServiceInfo();
+  public final class NsdManager {
+    method public void discoverServices(java.lang.String, int, android.net.nsd.NsdManager.DiscoveryListener);
+    method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
+    method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
+    method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
+    method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
+    field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
+    field public static final java.lang.String EXTRA_NSD_STATE = "nsd_state";
+    field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
+    field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
+    field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
+    field public static final int NSD_STATE_DISABLED = 1; // 0x1
+    field public static final int NSD_STATE_ENABLED = 2; // 0x2
+    field public static final int PROTOCOL_DNS_SD = 1; // 0x1
+  }
+
+  public static abstract interface NsdManager.DiscoveryListener {
+    method public abstract void onDiscoveryStarted(java.lang.String);
+    method public abstract void onDiscoveryStopped(java.lang.String);
+    method public abstract void onServiceFound(android.net.nsd.NsdServiceInfo);
+    method public abstract void onServiceLost(android.net.nsd.NsdServiceInfo);
+    method public abstract void onStartDiscoveryFailed(java.lang.String, int);
+    method public abstract void onStopDiscoveryFailed(java.lang.String, int);
+  }
+
+  public static abstract interface NsdManager.RegistrationListener {
+    method public abstract void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
+    method public abstract void onServiceRegistered(android.net.nsd.NsdServiceInfo);
+    method public abstract void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
+    method public abstract void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
+  }
+
+  public static abstract interface NsdManager.ResolveListener {
+    method public abstract void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
+    method public abstract void onServiceResolved(android.net.nsd.NsdServiceInfo);
+  }
+
+  public final class NsdServiceInfo implements android.os.Parcelable {
+    ctor public NsdServiceInfo();
     method public int describeContents();
     method public java.net.InetAddress getHost();
     method public int getPort();
@@ -12724,71 +12755,6 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public class DnsSdTxtRecord implements android.os.Parcelable {
-    ctor public DnsSdTxtRecord();
-    ctor public DnsSdTxtRecord(byte[]);
-    ctor public DnsSdTxtRecord(android.net.nsd.DnsSdTxtRecord);
-    method public boolean contains(java.lang.String);
-    method public int describeContents();
-    method public java.lang.String get(java.lang.String);
-    method public byte[] getRawData();
-    method public int keyCount();
-    method public int remove(java.lang.String);
-    method public void set(java.lang.String, java.lang.String);
-    method public int size();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
-  public class NsdManager {
-    method public void deinitialize(android.net.nsd.NsdManager.Channel);
-    method public void discoverServices(android.net.nsd.NsdManager.Channel, java.lang.String, android.net.nsd.NsdManager.DnsSdDiscoveryListener);
-    method public void initialize(android.content.Context, android.os.Looper, android.net.nsd.NsdManager.ChannelListener);
-    method public void registerService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, int, android.net.nsd.NsdManager.DnsSdRegisterListener);
-    method public void resolveService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, android.net.nsd.NsdManager.DnsSdResolveListener);
-    method public void stopServiceDiscovery(android.net.nsd.NsdManager.Channel, android.net.nsd.NsdManager.ActionListener);
-    method public void unregisterService(android.net.nsd.NsdManager.Channel, int, android.net.nsd.NsdManager.ActionListener);
-    field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
-    field public static final int ALREADY_ACTIVE = 3; // 0x3
-    field public static final int BUSY = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
-    field public static final java.lang.String EXTRA_NSD_STATE = "nsd_state";
-    field public static final int MAX_REGS_REACHED = 4; // 0x4
-    field public static final int NSD_STATE_DISABLED = 1; // 0x1
-    field public static final int NSD_STATE_ENABLED = 2; // 0x2
-    field public static final int UNSUPPORTED = 1; // 0x1
-  }
-
-  public static abstract interface NsdManager.ActionListener {
-    method public abstract void onFailure(int);
-    method public abstract void onSuccess();
-  }
-
-  public static class NsdManager.Channel {
-  }
-
-  public static abstract interface NsdManager.ChannelListener {
-    method public abstract void onChannelConnected(android.net.nsd.NsdManager.Channel);
-    method public abstract void onChannelDisconnected();
-  }
-
-  public static abstract interface NsdManager.DnsSdDiscoveryListener {
-    method public abstract void onFailure(int);
-    method public abstract void onServiceFound(android.net.nsd.DnsSdServiceInfo);
-    method public abstract void onServiceLost(android.net.nsd.DnsSdServiceInfo);
-    method public abstract void onStarted(java.lang.String);
-  }
-
-  public static abstract interface NsdManager.DnsSdRegisterListener {
-    method public abstract void onFailure(int);
-    method public abstract void onServiceRegistered(int, android.net.nsd.DnsSdServiceInfo);
-  }
-
-  public static abstract interface NsdManager.DnsSdResolveListener {
-    method public abstract void onFailure(int);
-    method public abstract void onServiceResolved(android.net.nsd.DnsSdServiceInfo);
-  }
-
 }
 
 package android.net.rtp {
@@ -13358,7 +13324,7 @@
   }
 
   public static abstract interface WifiP2pManager.DnsSdTxtRecordListener {
-    method public abstract void onDnsSdTxtRecordAvailable(java.lang.String, android.net.nsd.DnsSdTxtRecord, android.net.wifi.p2p.WifiP2pDevice);
+    method public abstract void onDnsSdTxtRecordAvailable(java.lang.String, java.util.Map<java.lang.String, java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
   }
 
   public static abstract interface WifiP2pManager.GroupInfoListener {
@@ -13382,7 +13348,7 @@
 package android.net.wifi.p2p.nsd {
 
   public class WifiP2pDnsSdServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
-    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo newInstance(java.lang.String, java.lang.String, android.net.nsd.DnsSdTxtRecord);
+    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo newInstance(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>);
   }
 
   public class WifiP2pDnsSdServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
@@ -18423,7 +18389,6 @@
     field public static final java.lang.String RADIO_NFC = "nfc";
     field public static final java.lang.String RADIO_WIFI = "wifi";
     field public static final java.lang.String RINGTONE = "ringtone";
-    field public static final java.lang.String SCREEN_AUTO_BRIGHTNESS_ADJ = "screen_auto_brightness_adj";
     field public static final java.lang.String SCREEN_BRIGHTNESS = "screen_brightness";
     field public static final java.lang.String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode";
     field public static final int SCREEN_BRIGHTNESS_MODE_AUTOMATIC = 1; // 0x1
@@ -18753,7 +18718,7 @@
     method public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
     method public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
     method public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
-    method public static android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
+    method public static deprecated android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
     method public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
     method public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
     method public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
@@ -18908,27 +18873,27 @@
     method public void skip(int);
   }
 
-  public class FileA3D extends android.renderscript.BaseObj {
-    method public static android.renderscript.FileA3D createFromAsset(android.renderscript.RenderScript, android.content.res.AssetManager, java.lang.String);
-    method public static android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.lang.String);
-    method public static android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.io.File);
-    method public static android.renderscript.FileA3D createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int);
-    method public android.renderscript.FileA3D.IndexEntry getIndexEntry(int);
-    method public int getIndexEntryCount();
+  public deprecated class FileA3D extends android.renderscript.BaseObj {
+    method public static deprecated android.renderscript.FileA3D createFromAsset(android.renderscript.RenderScript, android.content.res.AssetManager, java.lang.String);
+    method public static deprecated android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.lang.String);
+    method public static deprecated android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.io.File);
+    method public static deprecated android.renderscript.FileA3D createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int);
+    method public deprecated android.renderscript.FileA3D.IndexEntry getIndexEntry(int);
+    method public deprecated int getIndexEntryCount();
   }
 
-  public static final class FileA3D.EntryType extends java.lang.Enum {
+  public static final deprecated class FileA3D.EntryType extends java.lang.Enum {
     method public static android.renderscript.FileA3D.EntryType valueOf(java.lang.String);
     method public static final android.renderscript.FileA3D.EntryType[] values();
-    enum_constant public static final android.renderscript.FileA3D.EntryType MESH;
-    enum_constant public static final android.renderscript.FileA3D.EntryType UNKNOWN;
+    enum_constant public static final deprecated android.renderscript.FileA3D.EntryType MESH;
+    enum_constant public static final deprecated android.renderscript.FileA3D.EntryType UNKNOWN;
   }
 
-  public static class FileA3D.IndexEntry {
-    method public android.renderscript.FileA3D.EntryType getEntryType();
-    method public android.renderscript.Mesh getMesh();
-    method public java.lang.String getName();
-    method public android.renderscript.BaseObj getObject();
+  public static deprecated class FileA3D.IndexEntry {
+    method public deprecated android.renderscript.FileA3D.EntryType getEntryType();
+    method public deprecated android.renderscript.Mesh getMesh();
+    method public deprecated java.lang.String getName();
+    method public deprecated android.renderscript.BaseObj getObject();
   }
 
   public class Float2 {
@@ -18955,21 +18920,21 @@
     field public float z;
   }
 
-  public class Font extends android.renderscript.BaseObj {
-    method public static android.renderscript.Font create(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, android.renderscript.Font.Style, float);
-    method public static android.renderscript.Font createFromAsset(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
-    method public static android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
-    method public static android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.io.File, float);
-    method public static android.renderscript.Font createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int, float);
+  public deprecated class Font extends android.renderscript.BaseObj {
+    method public static deprecated android.renderscript.Font create(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, android.renderscript.Font.Style, float);
+    method public static deprecated android.renderscript.Font createFromAsset(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
+    method public static deprecated android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
+    method public static deprecated android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.io.File, float);
+    method public static deprecated android.renderscript.Font createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int, float);
   }
 
-  public static final class Font.Style extends java.lang.Enum {
+  public static final deprecated class Font.Style extends java.lang.Enum {
     method public static android.renderscript.Font.Style valueOf(java.lang.String);
     method public static final android.renderscript.Font.Style[] values();
-    enum_constant public static final android.renderscript.Font.Style BOLD;
-    enum_constant public static final android.renderscript.Font.Style BOLD_ITALIC;
-    enum_constant public static final android.renderscript.Font.Style ITALIC;
-    enum_constant public static final android.renderscript.Font.Style NORMAL;
+    enum_constant public static final deprecated android.renderscript.Font.Style BOLD;
+    enum_constant public static final deprecated android.renderscript.Font.Style BOLD_ITALIC;
+    enum_constant public static final deprecated android.renderscript.Font.Style ITALIC;
+    enum_constant public static final deprecated android.renderscript.Font.Style NORMAL;
   }
 
   public class Int2 {
@@ -19086,59 +19051,59 @@
     method public void transpose();
   }
 
-  public class Mesh extends android.renderscript.BaseObj {
-    method public android.renderscript.Allocation getIndexSetAllocation(int);
-    method public android.renderscript.Mesh.Primitive getPrimitive(int);
-    method public int getPrimitiveCount();
-    method public android.renderscript.Allocation getVertexAllocation(int);
-    method public int getVertexAllocationCount();
+  public deprecated class Mesh extends android.renderscript.BaseObj {
+    method public deprecated android.renderscript.Allocation getIndexSetAllocation(int);
+    method public deprecated android.renderscript.Mesh.Primitive getPrimitive(int);
+    method public deprecated int getPrimitiveCount();
+    method public deprecated android.renderscript.Allocation getVertexAllocation(int);
+    method public deprecated int getVertexAllocationCount();
   }
 
-  public static class Mesh.AllocationBuilder {
-    ctor public Mesh.AllocationBuilder(android.renderscript.RenderScript);
-    method public android.renderscript.Mesh.AllocationBuilder addIndexSetAllocation(android.renderscript.Allocation, android.renderscript.Mesh.Primitive);
-    method public android.renderscript.Mesh.AllocationBuilder addIndexSetType(android.renderscript.Mesh.Primitive);
-    method public android.renderscript.Mesh.AllocationBuilder addVertexAllocation(android.renderscript.Allocation) throws java.lang.IllegalStateException;
-    method public android.renderscript.Mesh create();
-    method public int getCurrentIndexSetIndex();
-    method public int getCurrentVertexTypeIndex();
+  public static deprecated class Mesh.AllocationBuilder {
+    ctor public deprecated Mesh.AllocationBuilder(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.Mesh.AllocationBuilder addIndexSetAllocation(android.renderscript.Allocation, android.renderscript.Mesh.Primitive);
+    method public deprecated android.renderscript.Mesh.AllocationBuilder addIndexSetType(android.renderscript.Mesh.Primitive);
+    method public deprecated android.renderscript.Mesh.AllocationBuilder addVertexAllocation(android.renderscript.Allocation) throws java.lang.IllegalStateException;
+    method public deprecated android.renderscript.Mesh create();
+    method public deprecated int getCurrentIndexSetIndex();
+    method public deprecated int getCurrentVertexTypeIndex();
   }
 
-  public static class Mesh.Builder {
-    ctor public Mesh.Builder(android.renderscript.RenderScript, int);
-    method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
-    method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
-    method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
-    method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
-    method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
-    method public android.renderscript.Mesh create();
-    method public int getCurrentIndexSetIndex();
-    method public int getCurrentVertexTypeIndex();
+  public static deprecated class Mesh.Builder {
+    ctor public deprecated Mesh.Builder(android.renderscript.RenderScript, int);
+    method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
+    method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
+    method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
+    method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
+    method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
+    method public deprecated android.renderscript.Mesh create();
+    method public deprecated int getCurrentIndexSetIndex();
+    method public deprecated int getCurrentVertexTypeIndex();
   }
 
-  public static final class Mesh.Primitive extends java.lang.Enum {
+  public static final deprecated class Mesh.Primitive extends java.lang.Enum {
     method public static android.renderscript.Mesh.Primitive valueOf(java.lang.String);
     method public static final android.renderscript.Mesh.Primitive[] values();
-    enum_constant public static final android.renderscript.Mesh.Primitive LINE;
-    enum_constant public static final android.renderscript.Mesh.Primitive LINE_STRIP;
-    enum_constant public static final android.renderscript.Mesh.Primitive POINT;
-    enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE;
-    enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_FAN;
-    enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
+    enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE;
+    enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE_STRIP;
+    enum_constant public static final deprecated android.renderscript.Mesh.Primitive POINT;
+    enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE;
+    enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_FAN;
+    enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
   }
 
-  public static class Mesh.TriangleMeshBuilder {
-    ctor public Mesh.TriangleMeshBuilder(android.renderscript.RenderScript, int, int);
-    method public android.renderscript.Mesh.TriangleMeshBuilder addTriangle(int, int, int);
-    method public android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float);
-    method public android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float, float);
-    method public android.renderscript.Mesh create(boolean);
-    method public android.renderscript.Mesh.TriangleMeshBuilder setColor(float, float, float, float);
-    method public android.renderscript.Mesh.TriangleMeshBuilder setNormal(float, float, float);
-    method public android.renderscript.Mesh.TriangleMeshBuilder setTexture(float, float);
-    field public static final int COLOR = 1; // 0x1
-    field public static final int NORMAL = 2; // 0x2
-    field public static final int TEXTURE_0 = 256; // 0x100
+  public static deprecated class Mesh.TriangleMeshBuilder {
+    ctor public deprecated Mesh.TriangleMeshBuilder(android.renderscript.RenderScript, int, int);
+    method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addTriangle(int, int, int);
+    method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float);
+    method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float, float);
+    method public deprecated android.renderscript.Mesh create(boolean);
+    method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setColor(float, float, float, float);
+    method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setNormal(float, float, float);
+    method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setTexture(float, float);
+    field public static final deprecated int COLOR = 1; // 0x1
+    field public static final deprecated int NORMAL = 2; // 0x2
+    field public static final deprecated int TEXTURE_0 = 256; // 0x100
   }
 
   public class Program extends android.renderscript.BaseObj {
@@ -19171,64 +19136,64 @@
     enum_constant public static final android.renderscript.Program.TextureType TEXTURE_CUBE;
   }
 
-  public class ProgramFragment extends android.renderscript.Program {
+  public deprecated class ProgramFragment extends android.renderscript.Program {
   }
 
-  public static class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
-    ctor public ProgramFragment.Builder(android.renderscript.RenderScript);
-    method public android.renderscript.ProgramFragment create();
+  public static deprecated class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
+    ctor public deprecated ProgramFragment.Builder(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.ProgramFragment create();
   }
 
-  public class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
+  public deprecated class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
   }
 
-  public static class ProgramFragmentFixedFunction.Builder {
-    ctor public ProgramFragmentFixedFunction.Builder(android.renderscript.RenderScript);
-    method public android.renderscript.ProgramFragmentFixedFunction create();
-    method public android.renderscript.ProgramFragmentFixedFunction.Builder setPointSpriteTexCoordinateReplacement(boolean);
-    method public android.renderscript.ProgramFragmentFixedFunction.Builder setTexture(android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode, android.renderscript.ProgramFragmentFixedFunction.Builder.Format, int) throws java.lang.IllegalArgumentException;
-    method public android.renderscript.ProgramFragmentFixedFunction.Builder setVaryingColor(boolean);
-    field public static final int MAX_TEXTURE = 2; // 0x2
+  public static deprecated class ProgramFragmentFixedFunction.Builder {
+    ctor public deprecated ProgramFragmentFixedFunction.Builder(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.ProgramFragmentFixedFunction create();
+    method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setPointSpriteTexCoordinateReplacement(boolean);
+    method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setTexture(android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode, android.renderscript.ProgramFragmentFixedFunction.Builder.Format, int) throws java.lang.IllegalArgumentException;
+    method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setVaryingColor(boolean);
+    field public static final deprecated int MAX_TEXTURE = 2; // 0x2
   }
 
-  public static final class ProgramFragmentFixedFunction.Builder.EnvMode extends java.lang.Enum {
+  public static final deprecated class ProgramFragmentFixedFunction.Builder.EnvMode extends java.lang.Enum {
     method public static android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode valueOf(java.lang.String);
     method public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode[] values();
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode DECAL;
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode MODULATE;
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode REPLACE;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode DECAL;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode MODULATE;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode REPLACE;
   }
 
-  public static final class ProgramFragmentFixedFunction.Builder.Format extends java.lang.Enum {
+  public static final deprecated class ProgramFragmentFixedFunction.Builder.Format extends java.lang.Enum {
     method public static android.renderscript.ProgramFragmentFixedFunction.Builder.Format valueOf(java.lang.String);
     method public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format[] values();
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format ALPHA;
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format LUMINANCE_ALPHA;
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGB;
-    enum_constant public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format ALPHA;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format LUMINANCE_ALPHA;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGB;
+    enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
   }
 
-  public class ProgramRaster extends android.renderscript.BaseObj {
-    method public static android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
-    method public static android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
-    method public static android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
-    method public android.renderscript.ProgramRaster.CullMode getCullMode();
-    method public boolean isPointSpriteEnabled();
+  public deprecated class ProgramRaster extends android.renderscript.BaseObj {
+    method public static deprecated android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
+    method public static deprecated android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
+    method public static deprecated android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.ProgramRaster.CullMode getCullMode();
+    method public deprecated boolean isPointSpriteEnabled();
   }
 
-  public static class ProgramRaster.Builder {
-    ctor public ProgramRaster.Builder(android.renderscript.RenderScript);
-    method public android.renderscript.ProgramRaster create();
-    method public android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
-    method public android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
+  public static deprecated class ProgramRaster.Builder {
+    ctor public deprecated ProgramRaster.Builder(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.ProgramRaster create();
+    method public deprecated android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
+    method public deprecated android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
   }
 
-  public static final class ProgramRaster.CullMode extends java.lang.Enum {
+  public static final deprecated class ProgramRaster.CullMode extends java.lang.Enum {
     method public static android.renderscript.ProgramRaster.CullMode valueOf(java.lang.String);
     method public static final android.renderscript.ProgramRaster.CullMode[] values();
-    enum_constant public static final android.renderscript.ProgramRaster.CullMode BACK;
-    enum_constant public static final android.renderscript.ProgramRaster.CullMode FRONT;
-    enum_constant public static final android.renderscript.ProgramRaster.CullMode NONE;
+    enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode BACK;
+    enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode FRONT;
+    enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode NONE;
   }
 
   public class ProgramStore extends android.renderscript.BaseObj {
@@ -19296,33 +19261,33 @@
     enum_constant public static final android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
   }
 
-  public class ProgramVertex extends android.renderscript.Program {
-    method public android.renderscript.Element getInput(int);
-    method public int getInputCount();
+  public deprecated class ProgramVertex extends android.renderscript.Program {
+    method public deprecated android.renderscript.Element getInput(int);
+    method public deprecated int getInputCount();
   }
 
-  public static class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
-    ctor public ProgramVertex.Builder(android.renderscript.RenderScript);
-    method public android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
-    method public android.renderscript.ProgramVertex create();
+  public static deprecated class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
+    ctor public deprecated ProgramVertex.Builder(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
+    method public deprecated android.renderscript.ProgramVertex create();
   }
 
-  public class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
-    method public void bindConstants(android.renderscript.ProgramVertexFixedFunction.Constants);
+  public deprecated class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
+    method public deprecated void bindConstants(android.renderscript.ProgramVertexFixedFunction.Constants);
   }
 
-  public static class ProgramVertexFixedFunction.Builder {
-    ctor public ProgramVertexFixedFunction.Builder(android.renderscript.RenderScript);
-    method public android.renderscript.ProgramVertexFixedFunction create();
-    method public android.renderscript.ProgramVertexFixedFunction.Builder setTextureMatrixEnable(boolean);
+  public static deprecated class ProgramVertexFixedFunction.Builder {
+    ctor public deprecated ProgramVertexFixedFunction.Builder(android.renderscript.RenderScript);
+    method public deprecated android.renderscript.ProgramVertexFixedFunction create();
+    method public deprecated android.renderscript.ProgramVertexFixedFunction.Builder setTextureMatrixEnable(boolean);
   }
 
-  public static class ProgramVertexFixedFunction.Constants {
-    ctor public ProgramVertexFixedFunction.Constants(android.renderscript.RenderScript);
-    method public void destroy();
-    method public void setModelview(android.renderscript.Matrix4f);
-    method public void setProjection(android.renderscript.Matrix4f);
-    method public void setTexture(android.renderscript.Matrix4f);
+  public static deprecated class ProgramVertexFixedFunction.Constants {
+    ctor public deprecated ProgramVertexFixedFunction.Constants(android.renderscript.RenderScript);
+    method public deprecated void destroy();
+    method public deprecated void setModelview(android.renderscript.Matrix4f);
+    method public deprecated void setProjection(android.renderscript.Matrix4f);
+    method public deprecated void setTexture(android.renderscript.Matrix4f);
   }
 
   public class RSDriverException extends android.renderscript.RSRuntimeException {
@@ -19341,33 +19306,33 @@
     ctor public RSRuntimeException(java.lang.String);
   }
 
-  public class RSSurfaceView extends android.view.SurfaceView implements android.view.SurfaceHolder.Callback {
-    ctor public RSSurfaceView(android.content.Context);
-    ctor public RSSurfaceView(android.content.Context, android.util.AttributeSet);
-    method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public void destroyRenderScriptGL();
-    method public android.renderscript.RenderScriptGL getRenderScriptGL();
-    method public void pause();
-    method public void resume();
-    method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
-    method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
-    method public void surfaceCreated(android.view.SurfaceHolder);
-    method public void surfaceDestroyed(android.view.SurfaceHolder);
+  public deprecated class RSSurfaceView extends android.view.SurfaceView implements android.view.SurfaceHolder.Callback {
+    ctor public deprecated RSSurfaceView(android.content.Context);
+    ctor public deprecated RSSurfaceView(android.content.Context, android.util.AttributeSet);
+    method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public deprecated void destroyRenderScriptGL();
+    method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
+    method public deprecated void pause();
+    method public deprecated void resume();
+    method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
+    method public deprecated void surfaceChanged(android.view.SurfaceHolder, int, int, int);
+    method public deprecated void surfaceCreated(android.view.SurfaceHolder);
+    method public deprecated void surfaceDestroyed(android.view.SurfaceHolder);
   }
 
-  public class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
-    ctor public RSTextureView(android.content.Context);
-    ctor public RSTextureView(android.content.Context, android.util.AttributeSet);
-    method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public void destroyRenderScriptGL();
-    method public android.renderscript.RenderScriptGL getRenderScriptGL();
-    method public void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
-    method public boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
-    method public void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
-    method public void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
-    method public void pause();
-    method public void resume();
-    method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
+  public deprecated class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
+    ctor public deprecated RSTextureView(android.content.Context);
+    ctor public deprecated RSTextureView(android.content.Context, android.util.AttributeSet);
+    method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public deprecated void destroyRenderScriptGL();
+    method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
+    method public deprecated void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
+    method public deprecated boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
+    method public deprecated void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
+    method public deprecated void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
+    method public deprecated void pause();
+    method public deprecated void resume();
+    method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
   }
 
   public class RenderScript {
@@ -19405,28 +19370,28 @@
     field protected int mLength;
   }
 
-  public class RenderScriptGL extends android.renderscript.RenderScript {
-    ctor public RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public void bindProgramFragment(android.renderscript.ProgramFragment);
-    method public void bindProgramRaster(android.renderscript.ProgramRaster);
-    method public void bindProgramStore(android.renderscript.ProgramStore);
-    method public void bindProgramVertex(android.renderscript.ProgramVertex);
-    method public void bindRootScript(android.renderscript.Script);
-    method public int getHeight();
-    method public int getWidth();
-    method public void pause();
-    method public void resume();
-    method public void setSurface(android.view.SurfaceHolder, int, int);
-    method public void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
+  public deprecated class RenderScriptGL extends android.renderscript.RenderScript {
+    ctor public deprecated RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public deprecated void bindProgramFragment(android.renderscript.ProgramFragment);
+    method public deprecated void bindProgramRaster(android.renderscript.ProgramRaster);
+    method public deprecated void bindProgramStore(android.renderscript.ProgramStore);
+    method public deprecated void bindProgramVertex(android.renderscript.ProgramVertex);
+    method public deprecated void bindRootScript(android.renderscript.Script);
+    method public deprecated int getHeight();
+    method public deprecated int getWidth();
+    method public deprecated void pause();
+    method public deprecated void resume();
+    method public deprecated void setSurface(android.view.SurfaceHolder, int, int);
+    method public deprecated void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
   }
 
-  public static class RenderScriptGL.SurfaceConfig {
-    ctor public RenderScriptGL.SurfaceConfig();
-    ctor public RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public void setAlpha(int, int);
-    method public void setColor(int, int);
-    method public void setDepth(int, int);
-    method public void setSamples(int, int, float);
+  public static deprecated class RenderScriptGL.SurfaceConfig {
+    ctor public deprecated RenderScriptGL.SurfaceConfig();
+    ctor public deprecated RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public deprecated void setAlpha(int, int);
+    method public deprecated void setColor(int, int);
+    method public deprecated void setDepth(int, int);
+    method public deprecated void setSamples(int, int, float);
   }
 
   public class Sampler extends android.renderscript.BaseObj {
@@ -25269,6 +25234,8 @@
     field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
     field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
     field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
     field public static final int ACTION_SELECT = 4; // 0x4
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
@@ -25284,7 +25251,7 @@
     ctor public AccessibilityNodeProvider();
     method public android.view.accessibility.AccessibilityNodeInfo accessibilityFocusSearch(int, int);
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
-    method public android.view.accessibility.AccessibilityNodeInfo findAccessibilitiyFocus(int);
+    method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public boolean performAction(int, int, android.os.Bundle);
   }
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index fcf3c7e..341f30f 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -17,8 +17,6 @@
 package com.android.commands.input;
 
 import android.hardware.input.InputManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.InputDevice;
@@ -59,7 +57,11 @@
                 }
             } else if (command.equals("keyevent")) {
                 if (args.length == 2) {
-                    sendKeyEvent(Integer.parseInt(args[1]));
+                    int keyCode = KeyEvent.keyCodeFromString(args[1]);
+                    if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
+                        keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[1]);
+                    }
+                    sendKeyEvent(keyCode);
                     return;
                 }
             } else if (command.equals("tap")) {
@@ -163,7 +165,7 @@
     private void showUsage() {
         System.err.println("usage: input ...");
         System.err.println("       input text <string>");
-        System.err.println("       input keyevent <key code>");
+        System.err.println("       input keyevent <key code number or name>");
         System.err.println("       input tap <x> <y>");
         System.err.println("       input swipe <x1> <y1> <x2> <y2>");
     }
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index b644dd1..850fe48 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -284,16 +284,6 @@
     public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
 
     /**
-     * The user has performed a two finger tap gesture on the touch screen.
-     */
-    public static final int GESTURE_TWO_FINGER_TAP = 17;
-
-    /**
-     * The user has performed a two finger long press gesture on the touch screen.
-     */
-    public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18;
-
-    /**
      * The {@link Intent} that must be declared as handled by the service.
      */
     public static final String SERVICE_INTERFACE =
@@ -377,14 +367,12 @@
 
     /**
      * Called by the system when the user performs a specific gesture on the
-     * touch screen. If the gesture is not handled in this callback the system
-     * may provide default handing. Therefore, one should return true from this
-     * function if overriding of default behavior is desired.
+     * touch screen.
      *
-     * <strong>Note:</strong> To receive gestures an accessibility service
-     *         must declare that it can handle such by specifying the
-     *         <code>&lt;{@link android.R.styleable#AccessibilityService_canHandleGestures
-     *         canHandleGestures}&gt;</code> attribute.
+     * <strong>Note:</strong> To receive gestures an accessibility service must
+     * request that the device is in touch exploration mode by setting the
+     * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS}
+     * flag.
      *
      * @param gestureId The unique id of the performed gesture.
      *
@@ -406,13 +394,8 @@
      * @see #GESTURE_SWIPE_RIGHT_AND_UP
      * @see #GESTURE_SWIPE_RIGHT_AND_LEFT
      * @see #GESTURE_SWIPE_RIGHT_AND_DOWN
-     * @see #GESTURE_CLOCKWISE_CIRCLE
-     * @see #GESTURE_COUNTER_CLOCKWISE_CIRCLE
-     * @see #GESTURE_TWO_FINGER_TAP
-     * @see #GESTURE_TWO_FINGER_LONG_PRESS
      */
     protected boolean onGesture(int gestureId) {
-        // TODO: Describe the default gesture processing in the javaDoc once it is finalized.
         return false;
     }
 
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 7e6786b..10ea0fe 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -131,7 +131,19 @@
      * elements.
      * </p>
      */
-    public static final int INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002;
+    public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002;
+
+    /**
+     * This flag requests that the system gets into touch exploration mode.
+     * In this mode a single finger moving on the screen behaves as a mouse
+     * pointer hovering over the user interface. The system will also detect
+     * certain gestures performed on the touch screen and notify this service.
+     * The system will enable touch exploration mode if there is at least one
+     * accessibility service that has this flag set. Hence, clearing this
+     * flag does not guarantee that the device will not be in touch exploration
+     * mode since there may be another enabled service that requested it.
+     */
+    public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE= 0x0000004;
 
     /**
      * The event types an {@link AccessibilityService} is interested in.
@@ -198,7 +210,8 @@
      *   <strong>Can be dynamically set at runtime.</strong>
      * </p>
      * @see #DEFAULT
-     * @see #INCLUDE_NOT_IMPORTANT_VIEWS
+     * @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+     * @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE
      */
     public int flags;
 
@@ -224,11 +237,6 @@
     private boolean mCanRetrieveWindowContent;
 
     /**
-     * Flag whether this accessibility service can handle gestures.
-     */
-    private boolean mCanHandleGestures;
-
-    /**
      * Resource id of the description of the accessibility service.
      */
     private int mDescriptionResId;
@@ -308,8 +316,6 @@
             mCanRetrieveWindowContent = asAttributes.getBoolean(
                     com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
                     false);
-            mCanHandleGestures = asAttributes.getBoolean(
-                    com.android.internal.R.styleable.AccessibilityService_canHandleGestures, false);
             TypedValue peekedValue = asAttributes.peekValue(
                     com.android.internal.R.styleable.AccessibilityService_description);
             if (peekedValue != null) {
@@ -392,18 +398,6 @@
     }
 
     /**
-     * Whether this service can handle gestures.
-     * <p>
-     *    <strong>Statically set from
-     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
-     * </p>
-     * @return True if the service can handle gestures.
-     */
-    public boolean getCanHandleGestures() {
-        return mCanHandleGestures;
-    }
-
-    /**
      * Gets the non-localized description of the accessibility service.
      * <p>
      *    <strong>Statically set from
@@ -614,8 +608,10 @@
         switch (flag) {
             case DEFAULT:
                 return "DEFAULT";
-            case INCLUDE_NOT_IMPORTANT_VIEWS:
-                return "REGARD_VIEWS_NOT_IMPORTANT_FOR_ACCESSIBILITY";
+            case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS:
+                return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS";
+            case FLAG_REQUEST_TOUCH_EXPLORATION_MODE:
+                return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE";
             default:
                 return null;
         }
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index 69195c1..6837386 100644
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
@@ -83,7 +83,7 @@
      * @return The event.
      */
     public AccessibilityEvent getLastAccessibilityEvent() {
-        return mLastEvent; 
+        return mLastEvent;
     }
 
     /**
@@ -142,7 +142,7 @@
 
             @Override
             public void onInterrupt() {
-                UiTestAutomationBridge.this.onInterrupt();  
+                UiTestAutomationBridge.this.onInterrupt();
             }
 
             @Override
@@ -189,7 +189,7 @@
         final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
         info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
         info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
-        info.flags |= AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS;
+        info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
 
         try {
             manager.registerUiTestAutomationService(mListener, info);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 7746ca9..4e61c3c 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1078,13 +1078,20 @@
      */
     public static class MemoryInfo implements Parcelable {
         /**
-         * The total available memory on the system.  This number should not
+         * The available memory on the system.  This number should not
          * be considered absolute: due to the nature of the kernel, a significant
          * portion of this memory is actually in use and needed for the overall
          * system to run well.
          */
         public long availMem;
-        
+
+        /**
+         * The total memory accessible by the kernel.  This is basically the
+         * RAM size of the device, not including below-kernel fixed allocations
+         * like DMA buffers, RAM for the baseband CPU, etc.
+         */
+        public long totalMem;
+
         /**
          * The threshold of {@link #availMem} at which we consider memory to be
          * low and start killing background services and other non-extraneous
@@ -1116,6 +1123,7 @@
 
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeLong(availMem);
+            dest.writeLong(totalMem);
             dest.writeLong(threshold);
             dest.writeInt(lowMemory ? 1 : 0);
             dest.writeLong(hiddenAppThreshold);
@@ -1126,6 +1134,7 @@
         
         public void readFromParcel(Parcel source) {
             availMem = source.readLong();
+            totalMem = source.readLong();
             threshold = source.readLong();
             lowMemory = source.readInt() != 0;
             hiddenAppThreshold = source.readLong();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 3d0b7d8..523a78d 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -98,6 +98,8 @@
     public static final int ANIM_SCALE_UP = 2;
     /** @hide */
     public static final int ANIM_THUMBNAIL = 3;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_DELAYED = 4;
 
     private String mPackageName;
     private int mAnimationType = ANIM_NONE;
@@ -219,9 +221,38 @@
      */
     public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
             Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
+        return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, listener, false);
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where a thumbnail
+     * is scaled from a given position to the new activity window that is
+     * being started. Before the animation, there is a short delay.
+     *
+     * @param source The View that this thumbnail is animating from.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param thumbnail The bitmap that will be shown as the initial thumbnail
+     * of the animation.
+     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
+     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
+     * @param listener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     * @hide
+     */
+    public static ActivityOptions makeDelayedThumbnailScaleUpAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
+        return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, listener, true);
+    }
+
+    private static ActivityOptions makeThumbnailScaleUpAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
+            boolean delayed) {
         ActivityOptions opts = new ActivityOptions();
         opts.mPackageName = source.getContext().getPackageName();
-        opts.mAnimationType = ANIM_THUMBNAIL;
+        opts.mAnimationType = delayed ? ANIM_THUMBNAIL_DELAYED : ANIM_THUMBNAIL;
         opts.mThumbnail = thumbnail;
         int[] pts = new int[2];
         source.getLocationOnScreen(pts);
@@ -258,7 +289,8 @@
             mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
             mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
             mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
-        } else if (mAnimationType == ANIM_THUMBNAIL) {
+        } else if (mAnimationType == ANIM_THUMBNAIL ||
+                mAnimationType == ANIM_THUMBNAIL_DELAYED) {
             mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
             mStartX = opts.getInt(KEY_ANIM_START_X, 0);
             mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
@@ -359,6 +391,7 @@
                 mStartHeight = otherOptions.mStartHeight;
                 break;
             case ANIM_THUMBNAIL:
+            case ANIM_THUMBNAIL_DELAYED:
                 mAnimationType = otherOptions.mAnimationType;
                 mThumbnail = otherOptions.mThumbnail;
                 mStartX = otherOptions.mStartX;
@@ -401,6 +434,7 @@
                 b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight);
                 break;
             case ANIM_THUMBNAIL:
+            case ANIM_THUMBNAIL_DELAYED:
                 b.putInt(KEY_ANIM_TYPE, mAnimationType);
                 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
                 b.putInt(KEY_ANIM_START_X, mStartX);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8799194..e2ebeba 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4278,6 +4278,14 @@
         }
     }
 
+    public final IContentProvider acquireUnstableProvider(Context c, String name) {
+        return acquireProvider(c, name);
+    }
+
+    public final boolean releaseUnstableProvider(IContentProvider provider) {
+        return releaseProvider(provider);
+    }
+
     final void completeRemoveProvider(IContentProvider provider) {
         IBinder jBinder = provider.asBinder();
         String remoteProviderName = null;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 64a05a8..299e408 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -387,7 +387,7 @@
                 public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(NSD_SERVICE);
                     INsdManager service = INsdManager.Stub.asInterface(b);
-                    return new NsdManager(service);
+                    return new NsdManager(ctx.getOuterContext(), service);
                 }});
 
         // Note: this was previously cached in a static variable, but
@@ -1692,6 +1692,16 @@
             return mMainThread.releaseProvider(provider);
         }
 
+        @Override
+        protected IContentProvider acquireUnstableProvider(Context c, String name) {
+            return mMainThread.acquireUnstableProvider(c, name);
+        }
+
+        @Override
+        public boolean releaseUnstableProvider(IContentProvider icp) {
+            return mMainThread.releaseUnstableProvider(icp);
+        }
+
         private final ActivityThread mMainThread;
     }
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f962259..ed9babf 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -390,21 +390,25 @@
     public int priority;
     
     /**
+     * @hide
      * Notification type: incoming call (voice or video) or similar synchronous communication request.
      */
     public static final String KIND_CALL = "android.call";
 
     /**
+     * @hide
      * Notification type: incoming direct message (SMS, instant message, etc.).
      */
     public static final String KIND_MESSAGE = "android.message";
 
     /**
+     * @hide
      * Notification type: asynchronous bulk message (email).
      */
     public static final String KIND_EMAIL = "android.email";
 
     /**
+     * @hide
      * Notification type: calendar event.
      */
     public static final String KIND_EVENT = "android.event";
@@ -415,6 +419,7 @@
     public static final String KIND_PROMO = "android.promo";
 
     /**
+     * @hide
      * If this notification matches of one or more special types (see the <code>KIND_*</code>
      * constants), add them here, best match first.
      */
@@ -796,6 +801,12 @@
         if (this.icon != 0) {
             contentView.setImageViewResource(R.id.icon, this.icon);
         }
+        if (priority < PRIORITY_LOW) {
+            contentView.setInt(R.id.icon,
+                    "setBackgroundResource", R.drawable.notification_template_icon_low_bg);
+            contentView.setInt(R.id.status_bar_latest_event_content,
+                    "setBackgroundResource", R.drawable.notification_bg_low);
+        }
         if (contentTitle != null) {
             contentView.setTextViewText(R.id.title, contentTitle);
         }
@@ -971,8 +982,14 @@
         }
 
         /**
-         * Show the {@link Notification#when} field as a countdown (or count-up) timer instead of a timestamp.  
+         * Show the {@link Notification#when} field as a stopwatch.
+         * 
+         * Instead of presenting <code>when</code> as a timestamp, the notification will show an 
+         * automatically updating display of the minutes and seconds since <code>when</code>.
          *
+         * Useful when showing an elapsed time (like an ongoing phone call).
+         *
+         * @see android.widget.Chronometer
          * @see Notification#when
          */
         public Builder setUsesChronometer(boolean b) {
@@ -1297,6 +1314,8 @@
         }
         
         /**
+         * @hide
+         * 
          * Add a kind (category) to this notification. Optional.
          * 
          * @see Notification#kind
@@ -1364,6 +1383,12 @@
                 contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
                 smallIconImageViewId = R.id.right_icon;
             }
+            if (mPriority < PRIORITY_LOW) {
+                contentView.setInt(R.id.icon,
+                        "setBackgroundResource", R.drawable.notification_template_icon_low_bg);
+                contentView.setInt(R.id.status_bar_latest_event_content,
+                        "setBackgroundResource", R.drawable.notification_bg_low);
+            }
             if (mSmallIcon != 0) {
                 contentView.setImageViewResource(smallIconImageViewId, mSmallIcon);
                 contentView.setViewVisibility(smallIconImageViewId, View.VISIBLE);
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index e546f6c..14c5736 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -196,18 +196,12 @@
         try {
             ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
             String parentActivity = info.parentActivityName;
-            Intent parent = new Intent().setComponent(
-                    new ComponentName(info.packageName, parentActivity));
-            while (parent != null) {
+            while (parentActivity != null) {
+                Intent parent = new Intent().setComponent(
+                        new ComponentName(info.packageName, parentActivity));
                 mIntents.add(insertAt, parent);
                 info = pm.getActivityInfo(parent.getComponent(), 0);
                 parentActivity = info.parentActivityName;
-                if (parentActivity != null) {
-                    parent = new Intent().setComponent(
-                            new ComponentName(info.packageName, parentActivity));
-                } else {
-                    parent = null;
-                }
             }
         } catch (NameNotFoundException e) {
             Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index c9bacba..01b68d4 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -208,8 +208,10 @@
     }
 
     /**
-     * Provide guidance about the size of this widget to the AppWidgetManager. This information
-     * gets embedded into the AppWidgetExtras and causes a callback to the AppWidgetProvider.
+     * Provide guidance about the size of this widget to the AppWidgetManager. The widths and
+     * heights should correspond to the full area the AppWidgetHostView is given. Padding added by
+     * the framework will be accounted for automatically. This information gets embedded into the
+     * AppWidget options and causes a callback to the AppWidgetProvider.
      * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
      *
      * @param options The bundle of options, in addition to the size information,
@@ -225,10 +227,20 @@
         if (options == null) {
             options = new Bundle();
         }
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
+
+        Rect padding = new Rect();
+        if (mInfo != null) {
+            padding = getDefaultPaddingForWidget(mContext, mInfo.provider, padding);
+        }
+        float density = getResources().getDisplayMetrics().density;
+
+        int xPaddingDips = (int) ((padding.left + padding.right) / density);
+        int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
+
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth - xPaddingDips);
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight - yPaddingDips);
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth - xPaddingDips);
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight - yPaddingDips);
         updateAppWidgetOptions(options);
     }
 
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index da2ab94..423f1f6 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -37,13 +37,16 @@
 public class ContentProviderClient {
     private final IContentProvider mContentProvider;
     private final ContentResolver mContentResolver;
+    private final boolean mStable;
 
     /**
      * @hide
      */
-    ContentProviderClient(ContentResolver contentResolver, IContentProvider contentProvider) {
+    ContentProviderClient(ContentResolver contentResolver,
+            IContentProvider contentProvider, boolean stable) {
         mContentProvider = contentProvider;
         mContentResolver = contentResolver;
+        mStable = stable;
     }
 
     /** See {@link ContentProvider#query ContentProvider.query} */
@@ -141,7 +144,11 @@
      * @return true if this was release, false if it was already released
      */
     public boolean release() {
-        return mContentResolver.releaseProvider(mContentProvider);
+        if (mStable) {
+            return mContentResolver.releaseProvider(mContentProvider);
+        } else {
+            return mContentResolver.releaseUnstableProvider(mContentProvider);
+        }
     }
 
     /**
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index d4bca0a..f509fd8 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -198,6 +198,10 @@
     }
     /** @hide */
     public abstract boolean releaseProvider(IContentProvider icp);
+    /** @hide */
+    protected abstract IContentProvider acquireUnstableProvider(Context c, String name);
+    /** @hide */
+    public abstract boolean releaseUnstableProvider(IContentProvider icp);
 
     /**
      * Return the MIME type of the given content URL.
@@ -588,34 +592,48 @@
             if ("r".equals(mode)) {
                 return openTypedAssetFileDescriptor(uri, "*/*", null);
             } else {
-                IContentProvider provider = acquireProvider(uri);
-                if (provider == null) {
-                    throw new FileNotFoundException("No content provider: " + uri);
-                }
-                try {
-                    AssetFileDescriptor fd = provider.openAssetFile(uri, mode);
-                    if(fd == null) {
-                        // The provider will be released by the finally{} clause
-                        return null;
+                int n = 0;
+                while (true) {
+                    n++;
+                    IContentProvider provider = acquireUnstableProvider(uri);
+                    if (provider == null) {
+                        throw new FileNotFoundException("No content provider: " + uri);
                     }
-                    ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
-                            fd.getParcelFileDescriptor(), provider);
+                    try {
+                        AssetFileDescriptor fd = provider.openAssetFile(uri, mode);
+                        if (fd == null) {
+                            // The provider will be released by the finally{} clause
+                            return null;
+                        }
+                        ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
+                                fd.getParcelFileDescriptor(), provider);
 
-                    // Success!  Don't release the provider when exiting, let
-                    // ParcelFileDescriptorInner do that when it is closed.
-                    provider = null;
+                        // Success!  Don't release the provider when exiting, let
+                        // ParcelFileDescriptorInner do that when it is closed.
+                        provider = null;
 
-                    return new AssetFileDescriptor(pfd, fd.getStartOffset(),
-                            fd.getDeclaredLength());
-                } catch (RemoteException e) {
-                    // Somewhat pointless, as Activity Manager will kill this
-                    // process shortly anyway if the depdendent ContentProvider dies.
-                    throw new FileNotFoundException("Dead content provider: " + uri);
-                } catch (FileNotFoundException e) {
-                    throw e;
-                } finally {
-                    if (provider != null) {
-                        releaseProvider(provider);
+                        return new AssetFileDescriptor(pfd, fd.getStartOffset(),
+                                fd.getDeclaredLength());
+                    } catch (RemoteException e) {
+                        // The provider died for some reason.  Since we are
+                        // acquiring it unstable, its process could have gotten
+                        // killed and need to be restarted.  We'll retry a couple
+                        // times and if still can't succeed then fail.
+                        if (n <= 2) {
+                            try {
+                                Thread.sleep(100);
+                            } catch (InterruptedException e1) {
+                            }
+                            continue;
+                        }
+                        // Whatever, whatever, we'll go away.
+                        throw new FileNotFoundException("Dead content provider: " + uri);
+                    } catch (FileNotFoundException e) {
+                        throw e;
+                    } finally {
+                        if (provider != null) {
+                            releaseUnstableProvider(provider);
+                        }
                     }
                 }
             }
@@ -652,32 +670,48 @@
      */
     public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
             String mimeType, Bundle opts) throws FileNotFoundException {
-        IContentProvider provider = acquireProvider(uri);
-        if (provider == null) {
-            throw new FileNotFoundException("No content provider: " + uri);
-        }
-        try {
-            AssetFileDescriptor fd = provider.openTypedAssetFile(uri, mimeType, opts);
-            if (fd == null) {
-                // The provider will be released by the finally{} clause
-                return null;
+        int n = 0;
+        while (true) {
+            n++;
+            IContentProvider provider = acquireUnstableProvider(uri);
+            if (provider == null) {
+                throw new FileNotFoundException("No content provider: " + uri);
             }
-            ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
-                    fd.getParcelFileDescriptor(), provider);
+            try {
+                AssetFileDescriptor fd = provider.openTypedAssetFile(uri, mimeType, opts);
+                if (fd == null) {
+                    // The provider will be released by the finally{} clause
+                    return null;
+                }
+                ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
+                        fd.getParcelFileDescriptor(), provider);
 
-            // Success!  Don't release the provider when exiting, let
-            // ParcelFileDescriptorInner do that when it is closed.
-            provider = null;
+                // Success!  Don't release the provider when exiting, let
+                // ParcelFileDescriptorInner do that when it is closed.
+                provider = null;
 
-            return new AssetFileDescriptor(pfd, fd.getStartOffset(),
-                    fd.getDeclaredLength());
-        } catch (RemoteException e) {
-            throw new FileNotFoundException("Dead content provider: " + uri);
-        } catch (FileNotFoundException e) {
-            throw e;
-        } finally {
-            if (provider != null) {
-                releaseProvider(provider);
+                return new AssetFileDescriptor(pfd, fd.getStartOffset(),
+                        fd.getDeclaredLength());
+            } catch (RemoteException e) {
+                // The provider died for some reason.  Since we are
+                // acquiring it unstable, its process could have gotten
+                // killed and need to be restarted.  We'll retry a couple
+                // times and if still can't succeed then fail.
+                if (n <= 2) {
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e1) {
+                    }
+                    continue;
+                }
+                // Whatever, whatever, we'll go away.
+                throw new FileNotFoundException("Dead content provider: " + uri);
+            } catch (FileNotFoundException e) {
+                throw e;
+            } finally {
+                if (provider != null) {
+                    releaseUnstableProvider(provider);
+                }
             }
         }
     }
@@ -1003,6 +1037,34 @@
     }
 
     /**
+     * Returns the content provider for the given content URI.
+     *
+     * @param uri The URI to a content provider
+     * @return The ContentProvider for the given URI, or null if no content provider is found.
+     * @hide
+     */
+    public final IContentProvider acquireUnstableProvider(Uri uri) {
+        if (!SCHEME_CONTENT.equals(uri.getScheme())) {
+            return null;
+        }
+        String auth = uri.getAuthority();
+        if (auth != null) {
+            return acquireUnstableProvider(mContext, uri.getAuthority());
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     */
+    public final IContentProvider acquireUnstableProvider(String name) {
+        if (name == null) {
+            return null;
+        }
+        return acquireProvider(mContext, name);
+    }
+
+    /**
      * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider}
      * that services the content at uri, starting the provider if necessary. Returns
      * null if there is no provider associated wih the uri. The caller must indicate that they are
@@ -1016,7 +1078,7 @@
     public final ContentProviderClient acquireContentProviderClient(Uri uri) {
         IContentProvider provider = acquireProvider(uri);
         if (provider != null) {
-            return new ContentProviderClient(this, provider);
+            return new ContentProviderClient(this, provider, true);
         }
 
         return null;
@@ -1036,7 +1098,47 @@
     public final ContentProviderClient acquireContentProviderClient(String name) {
         IContentProvider provider = acquireProvider(name);
         if (provider != null) {
-            return new ContentProviderClient(this, provider);
+            return new ContentProviderClient(this, provider, true);
+        }
+
+        return null;
+    }
+
+    /**
+     * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do
+     * not trust the stability of the target content provider.  This turns off
+     * the mechanism in the platform clean up processes that are dependent on
+     * a content provider if that content provider's process goes away.  Normally
+     * you can safely assume that once you have acquired a provider, you can freely
+     * use it as needed and it won't disappear, even if your process is in the
+     * background.  If using this method, you need to take care to deal with any
+     * failures when communicating with the provider, and be sure to close it
+     * so that it can be re-opened later.
+     */
+    public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) {
+        IContentProvider provider = acquireProvider(uri);
+        if (provider != null) {
+            return new ContentProviderClient(this, provider, false);
+        }
+
+        return null;
+    }
+
+    /**
+     * Like {@link #acquireContentProviderClient(String)}, but for use when you do
+     * not trust the stability of the target content provider.  This turns off
+     * the mechanism in the platform clean up processes that are dependent on
+     * a content provider if that content provider's process goes away.  Normally
+     * you can safely assume that once you have acquired a provider, you can freely
+     * use it as needed and it won't disappear, even if your process is in the
+     * background.  If using this method, you need to take care to deal with any
+     * failures when communicating with the provider, and be sure to close it
+     * so that it can be re-opened later.
+     */
+    public final ContentProviderClient acquireUnstableContentProviderClient(String name) {
+        IContentProvider provider = acquireProvider(name);
+        if (provider != null) {
+            return new ContentProviderClient(this, provider, false);
         }
 
         return null;
@@ -1690,7 +1792,7 @@
         public void close() throws IOException {
             if(!mReleaseProviderFlag) {
                 super.close();
-                ContentResolver.this.releaseProvider(mContentProvider);
+                ContentResolver.this.releaseUnstableProvider(mContentProvider);
                 mReleaseProviderFlag = true;
             }
         }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 4ed6f25..c791e47 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4573,7 +4573,7 @@
      * <p><em>Note: scheme matching in the Android framework is
      * case-sensitive, unlike the formal RFC. As a result,
      * you should always write your Uri with a lower case scheme,
-     * or use {@link Uri#normalize} or
+     * or use {@link Uri#normalizeScheme} or
      * {@link #setDataAndNormalize}
      * to ensure that the scheme is converted to lower case.</em>
      *
@@ -4599,7 +4599,7 @@
      * previously set (for example, by {@link #setType}).
      *
      * <p>The data Uri is normalized using
-     * {@link android.net.Uri#normalize} before it is set,
+     * {@link android.net.Uri#normalizeScheme} before it is set,
      * so really this is just a convenience method for
      * <pre>
      * setData(data.normalize())
@@ -4612,10 +4612,10 @@
      *
      * @see #getData
      * @see #setType
-     * @see android.net.Uri#normalize
+     * @see android.net.Uri#normalizeScheme
      */
     public Intent setDataAndNormalize(Uri data) {
-        return setData(data.normalize());
+        return setData(data.normalizeScheme());
     }
 
     /**
@@ -4687,7 +4687,7 @@
      * <p><em>Note: MIME type and Uri scheme matching in the
      * Android framework is case-sensitive, unlike the formal RFC definitions.
      * As a result, you should always write these elements with lower case letters,
-     * or use {@link #normalizeMimeType} or {@link android.net.Uri#normalize} or
+     * or use {@link #normalizeMimeType} or {@link android.net.Uri#normalizeScheme} or
      * {@link #setDataAndTypeAndNormalize}
      * to ensure that they are converted to lower case.</em>
      *
@@ -4700,7 +4700,7 @@
      * @see #setType
      * @see #setData
      * @see #normalizeMimeType
-     * @see android.net.Uri#normalize
+     * @see android.net.Uri#normalizeScheme
      * @see #setDataAndTypeAndNormalize
      */
     public Intent setDataAndType(Uri data, String type) {
@@ -4716,7 +4716,7 @@
      * data with your own type given here.
      *
      * <p>The data Uri and the MIME type are normalize using
-     * {@link android.net.Uri#normalize} and {@link #normalizeMimeType}
+     * {@link android.net.Uri#normalizeScheme} and {@link #normalizeMimeType}
      * before they are set, so really this is just a convenience method for
      * <pre>
      * setDataAndType(data.normalize(), Intent.normalizeMimeType(type))
@@ -4732,10 +4732,10 @@
      * @see #setData
      * @see #setDataAndType
      * @see #normalizeMimeType
-     * @see android.net.Uri#normalize
+     * @see android.net.Uri#normalizeScheme
      */
     public Intent setDataAndTypeAndNormalize(Uri data, String type) {
-        return setDataAndType(data.normalize(), normalizeMimeType(type));
+        return setDataAndType(data.normalizeScheme(), normalizeMimeType(type));
     }
 
     /**
diff --git a/core/java/android/content/pm/ContainerEncryptionParams.java b/core/java/android/content/pm/ContainerEncryptionParams.java
index 5b1440d..88112a7 100644
--- a/core/java/android/content/pm/ContainerEncryptionParams.java
+++ b/core/java/android/content/pm/ContainerEncryptionParams.java
@@ -70,16 +70,16 @@
     private final byte[] mMacTag;
 
     /** Offset into file where authenticated (e.g., MAC protected) data begins. */
-    private final int mAuthenticatedDataStart;
+    private final long mAuthenticatedDataStart;
 
     /** Offset into file where encrypted data begins. */
-    private final int mEncryptedDataStart;
+    private final long mEncryptedDataStart;
 
     /**
      * Offset into file for the end of encrypted data (and, by extension,
      * authenticated data) in file.
      */
-    private final int mDataEnd;
+    private final long mDataEnd;
 
     public ContainerEncryptionParams(String encryptionAlgorithm,
             AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey)
@@ -99,6 +99,8 @@
      * @param macAlgorithm MAC algorithm to use; format matches JCE
      * @param macSpec algorithm parameters specification, may be {@code null}
      * @param macKey key used for authentication (i.e., for the MAC tag)
+     * @param macTag message authentication code (MAC) tag for the authenticated
+     *            data
      * @param authenticatedDataStart offset of start of authenticated data in
      *            stream
      * @param encryptedDataStart offset of start of encrypted data in stream
@@ -109,7 +111,7 @@
     public ContainerEncryptionParams(String encryptionAlgorithm,
             AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey, String macAlgorithm,
             AlgorithmParameterSpec macSpec, SecretKey macKey, byte[] macTag,
-            int authenticatedDataStart, int encryptedDataStart, int dataEnd)
+            long authenticatedDataStart, long encryptedDataStart, long dataEnd)
             throws InvalidAlgorithmParameterException {
         if (TextUtils.isEmpty(encryptionAlgorithm)) {
             throw new NullPointerException("algorithm == null");
@@ -172,15 +174,15 @@
         return mMacTag;
     }
 
-    public int getAuthenticatedDataStart() {
+    public long getAuthenticatedDataStart() {
         return mAuthenticatedDataStart;
     }
 
-    public int getEncryptedDataStart() {
+    public long getEncryptedDataStart() {
         return mEncryptedDataStart;
     }
 
-    public int getDataEnd() {
+    public long getDataEnd() {
         return mDataEnd;
     }
 
@@ -315,9 +317,9 @@
 
         dest.writeByteArray(mMacTag);
 
-        dest.writeInt(mAuthenticatedDataStart);
-        dest.writeInt(mEncryptedDataStart);
-        dest.writeInt(mDataEnd);
+        dest.writeLong(mAuthenticatedDataStart);
+        dest.writeLong(mEncryptedDataStart);
+        dest.writeLong(mDataEnd);
     }
 
     private ContainerEncryptionParams(Parcel source) throws InvalidAlgorithmParameterException {
@@ -333,9 +335,9 @@
 
         mMacTag = source.createByteArray();
 
-        mAuthenticatedDataStart = source.readInt();
-        mEncryptedDataStart = source.readInt();
-        mDataEnd = source.readInt();
+        mAuthenticatedDataStart = source.readLong();
+        mEncryptedDataStart = source.readLong();
+        mDataEnd = source.readLong();
 
         switch (encParamType) {
             case ENC_PARAMS_IV_PARAMETERS:
diff --git a/core/java/android/content/pm/LimitedLengthInputStream.java b/core/java/android/content/pm/LimitedLengthInputStream.java
index 25a490f..e787277 100644
--- a/core/java/android/content/pm/LimitedLengthInputStream.java
+++ b/core/java/android/content/pm/LimitedLengthInputStream.java
@@ -3,6 +3,7 @@
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Arrays;
 
 /**
  * A class that limits the amount of data that is read from an InputStream. When
@@ -15,20 +16,20 @@
     /**
      * The end of the stream where we don't want to allow more data to be read.
      */
-    private final int mEnd;
+    private final long mEnd;
 
     /**
      * Current offset in the stream.
      */
-    private int mOffset;
+    private long mOffset;
 
     /**
      * @param in underlying stream to wrap
      * @param offset offset into stream where data starts
      * @param length length of data at offset
-     * @throws IOException if an error occured with the underlying stream
+     * @throws IOException if an error occurred with the underlying stream
      */
-    public LimitedLengthInputStream(InputStream in, int offset, int length) throws IOException {
+    public LimitedLengthInputStream(InputStream in, long offset, long length) throws IOException {
         super(in);
 
         if (in == null) {
@@ -36,11 +37,15 @@
         }
 
         if (offset < 0) {
-            throw new IOException("offset == " + offset);
+            throw new IOException("offset < 0");
         }
 
         if (length < 0) {
-            throw new IOException("length must be non-negative; is " + length);
+            throw new IOException("length < 0");
+        }
+
+        if (length > Long.MAX_VALUE - offset) {
+            throw new IOException("offset + length > Long.MAX_VALUE");
         }
 
         mEnd = offset + length;
@@ -65,8 +70,15 @@
             return -1;
         }
 
+        final int arrayLength = buffer.length;
+        Arrays.checkOffsetAndCount(arrayLength, offset, byteCount);
+
+        if (mOffset > Long.MAX_VALUE - byteCount) {
+            throw new IOException("offset out of bounds: " + mOffset + " + " + byteCount);
+        }
+
         if (mOffset + byteCount > mEnd) {
-            byteCount = mEnd - mOffset;
+            byteCount = (int) (mEnd - mOffset);
         }
 
         final int numRead = super.read(buffer, offset, byteCount);
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index 9893133..7d46710 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -52,6 +52,9 @@
      */
     public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset,
             long length) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
         if (length < 0 && startOffset != 0) {
             throw new IllegalArgumentException(
                     "startOffset must be 0 when using UNKNOWN_LENGTH");
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index dd6692c..fb04817 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -44,14 +44,20 @@
     /**
      * This must be set to the index of the row ID column by any
      * subclass that wishes to support updates.
+     *
+     * @deprecated This field should not be used.
      */
+    @Deprecated
     protected int mRowIdColumnIndex;
 
     /**
      * If {@link #mRowIdColumnIndex} is not -1 this contains contains the value of
      * the column at {@link #mRowIdColumnIndex} for the current row this cursor is
      * pointing at.
+     *
+     * @deprecated This field should not be used.
      */
+    @Deprecated
     protected Long mCurrentRowID;
 
     protected boolean mClosed;
@@ -62,8 +68,8 @@
     private ContentObserver mSelfObserver;
     private boolean mSelfObserverRegistered;
 
-    private DataSetObservable mDataSetObservable = new DataSetObservable();
-    private ContentObservable mContentObservable = new ContentObservable();
+    private final DataSetObservable mDataSetObservable = new DataSetObservable();
+    private final ContentObservable mContentObservable = new ContentObservable();
 
     private Bundle mExtras = Bundle.EMPTY;
 
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 332f40a..33dea6c 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -402,7 +402,7 @@
             mShowInputFlags = 0;
             mShowInputRequested = false;
             mShowInputForced = false;
-            hideWindow();
+            doHideWindow();
             if (resultReceiver != null) {
                 resultReceiver.send(wasVis != isInputViewShown()
                         ? InputMethodManager.RESULT_HIDDEN
@@ -737,7 +737,7 @@
                         onDisplayCompletions(completions);
                     }
                 } else {
-                    hideWindow();
+                    doHideWindow();
                 }
             } else if (mCandidatesVisibility == View.VISIBLE) {
                 // If the candidates are currently visible, make sure the
@@ -745,7 +745,7 @@
                 showWindow(false);
             } else {
                 // Otherwise hide the window.
-                hideWindow();
+                doHideWindow();
             }
             // If user uses hard keyboard, IME button should always be shown.
             boolean showing = onEvaluateInputViewShown();
@@ -1096,7 +1096,7 @@
             if (shown) {
                 showWindow(false);
             } else {
-                hideWindow();
+                doHideWindow();
             }
         }
     }
@@ -1449,9 +1449,13 @@
         mCandidatesViewStarted = false;
     }
 
+    private void doHideWindow() {
+        mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
+        hideWindow();
+    }
+
     public void hideWindow() {
         finishViews();
-        mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
         if (mWindowVisible) {
             mWindow.hide();
             mWindowVisible = false;
@@ -1703,7 +1707,7 @@
                 // If we have the window visible for some other reason --
                 // most likely to show candidates -- then just get rid
                 // of it.  This really shouldn't happen, but just in case...
-                if (doIt) hideWindow();
+                if (doIt) doHideWindow();
             }
             return true;
         }
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index defe7aa..3b990e3 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1718,9 +1718,7 @@
     }
 
     /**
-     * Return a normalized representation of this Uri.
-     *
-     * <p>A normalized Uri has a lowercase scheme component.
+     * Return an equivalent URI with a lowercase scheme component.
      * This aligns the Uri with Android best practices for
      * intent filtering.
      *
@@ -1740,7 +1738,7 @@
      * @see {@link android.content.Intent#setData}
      * @see {@link #setNormalizedData}
      */
-    public Uri normalize() {
+    public Uri normalizeScheme() {
         String scheme = getScheme();
         if (scheme == null) return this;  // give up
         String lowerScheme = scheme.toLowerCase(Locale.US);
diff --git a/core/java/android/net/nsd/DnsSdTxtRecord.java b/core/java/android/net/nsd/DnsSdTxtRecord.java
index ccb9a91..2f20d44 100644
--- a/core/java/android/net/nsd/DnsSdTxtRecord.java
+++ b/core/java/android/net/nsd/DnsSdTxtRecord.java
@@ -36,6 +36,7 @@
  *
  * The DnsSdTxtRecord object stores the entire TXT data as a single byte array, traversing it
  * as need be to implement its various methods.
+ * @hide
  *
  */
 public class DnsSdTxtRecord implements Parcelable {
diff --git a/core/java/android/net/nsd/NetworkServiceInfo.java b/core/java/android/net/nsd/NetworkServiceInfo.java
deleted file mode 100644
index 34d83d1..0000000
--- a/core/java/android/net/nsd/NetworkServiceInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-/**
- * Interface for a network service.
- *
- * {@hide}
- */
-public interface NetworkServiceInfo {
-
-    String getServiceName();
-    void setServiceName(String s);
-
-    String getServiceType();
-    void setServiceType(String s);
-
-}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 77e97e1..08ba728 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -22,12 +22,16 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.Messenger;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.concurrent.CountDownLatch;
 
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
@@ -39,88 +43,73 @@
  * B. Another example use case is an application discovering printers on the network.
  *
  * <p> The API currently supports DNS based service discovery and discovery is currently
- * limited to a local network over Multicast DNS. In future, it will be extended to
- * support wide area discovery and other service discovery mechanisms.
- * DNS service discovery is described at http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
+ * limited to a local network over Multicast DNS. DNS service discovery is described at
+ * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
  *
  * <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks provided by the application. The application must invoke {@link #initialize} before
- * doing any other operation.
+ * callbacks on a seperate thread.
  *
  * <p> There are three main operations the API supports - registration, discovery and resolution.
  * <pre>
  *                          Application start
  *                                 |
- *                                 |         <----------------------------------------------
- *                             initialize()                                                 |
- *                                 |                                                        |
- *                                 | Wait until channel connects                            |
- *                                 | before doing any operation                             |
- *                                 |                                                        |
- *                           onChannelConnected()                    __________             |
- *                                 |                                           |            |
- *                                 |                                           |            |
- *                                 |                  onServiceRegistered()    |            |
- *                     Register any local services  /                          |            |
- *                      to be advertised with       \                          |            | If application needs to
- *                       registerService()            onFailure()              |            | do any further operations
- *                                 |                                           |            | again, it needs to
- *                                 |                                           |            | initialize() connection
- *                          discoverServices()                                 |            | to framework again
- *                                 |                                           |            |
- *                      Maintain a list to track                               |            |
- *                        discovered services                                  |            |
- *                                 |                                           |            |
- *                                 |--------->                                 |-> onChannelDisconnected()
- *                                 |          |                                |
- *                                 |      onServiceFound()                     |
- *                                 |          |                                |
- *                                 |     add service to list                   |
- *                                 |          |                                |
- *                                 |<----------                                |
- *                                 |                                           |
- *                                 |--------->                                 |
- *                                 |          |                                |
- *                                 |      onServiceLost()                      |
- *                                 |          |                                |
- *                                 |   remove service from list                |
- *                                 |          |                                |
- *                                 |<----------                                |
- *                                 |                                           |
- *                                 |                                           |
- *                                 | Connect to a service                      |
- *                                 | from list ?                               |
- *                                 |                                           |
- *                          resolveService()                                   |
- *                                 |                                           |
- *                         onServiceResolved()                                 |
- *                                 |                                           |
- *                     Establish connection to service                         |
- *                     with the host and port information                      |
- *                                 |                                           |
- *                                 |                                ___________|
- *                           deinitialize()
- *                    when done with all operations
- *                          or before quit
+ *                                 |
+ *                                 |                  onServiceRegistered()
+ *                     Register any local services  /
+ *                      to be advertised with       \
+ *                       registerService()            onRegistrationFailed()
+ *                                 |
+ *                                 |
+ *                          discoverServices()
+ *                                 |
+ *                      Maintain a list to track
+ *                        discovered services
+ *                                 |
+ *                                 |--------->
+ *                                 |          |
+ *                                 |      onServiceFound()
+ *                                 |          |
+ *                                 |     add service to list
+ *                                 |          |
+ *                                 |<----------
+ *                                 |
+ *                                 |--------->
+ *                                 |          |
+ *                                 |      onServiceLost()
+ *                                 |          |
+ *                                 |   remove service from list
+ *                                 |          |
+ *                                 |<----------
+ *                                 |
+ *                                 |
+ *                                 | Connect to a service
+ *                                 | from list ?
+ *                                 |
+ *                          resolveService()
+ *                                 |
+ *                         onServiceResolved()
+ *                                 |
+ *                     Establish connection to service
+ *                     with the host and port information
  *
  * </pre>
  * An application that needs to advertise itself over a network for other applications to
  * discover it can do so with a call to {@link #registerService}. If Example is a http based
  * application that can provide HTML data to peer services, it can register a name "Example"
  * with service type "_http._tcp". A successful registration is notified with a callback to
- * {@link DnsSdRegisterListener#onServiceRegistered} and a failure to register is notified
- * over {@link DnsSdRegisterListener#onFailure}
+ * {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
+ * over {@link RegistrationListener#onRegistrationFailed}
  *
  * <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
  * with a call to {@link #discoverServices}. A service found is notified with a callback
- * to {@link DnsSdDiscoveryListener#onServiceFound} and a service lost is notified on
- * {@link DnsSdDiscoveryListener#onServiceLost}.
+ * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
+ * {@link DiscoveryListener#onServiceLost}.
  *
  * <p> Once the peer application discovers the "Example" http srevice, and needs to receive data
  * from the "Example" application, it can initiate a resolve with {@link #resolveService} to
  * resolve the host and port details for the purpose of establishing a connection. A successful
- * resolve is notified on {@link DnsSdResolveListener#onServiceResolved} and a failure is notified
- * on {@link DnsSdResolveListener#onFailure}.
+ * resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified
+ * on {@link ResolveListener#onResolveFailed}.
  *
  * Applications can reserve for a service type at
  * http://www.iana.org/form/ports-service. Existing services can be found at
@@ -129,9 +118,9 @@
  * Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
  * Context.getSystemService(Context.NSD_SERVICE)}.
  *
- * {@see DnsSdServiceInfo}
+ * {@see NsdServiceInfo}
  */
-public class NsdManager {
+public final class NsdManager {
     private static final String TAG = "NsdManager";
     INsdManager mService;
 
@@ -204,13 +193,6 @@
     public static final int UNREGISTER_SERVICE_SUCCEEDED            = BASE + 14;
 
     /** @hide */
-    public static final int UPDATE_SERVICE                          = BASE + 15;
-    /** @hide */
-    public static final int UPDATE_SERVICE_FAILED                   = BASE + 16;
-    /** @hide */
-    public static final int UPDATE_SERVICE_SUCCEEDED                = BASE + 17;
-
-    /** @hide */
     public static final int RESOLVE_SERVICE                         = BASE + 18;
     /** @hide */
     public static final int RESOLVE_SERVICE_FAILED                  = BASE + 19;
@@ -218,17 +200,27 @@
     public static final int RESOLVE_SERVICE_SUCCEEDED               = BASE + 20;
 
     /** @hide */
-    public static final int STOP_RESOLVE                            = BASE + 21;
-    /** @hide */
-    public static final int STOP_RESOLVE_FAILED                     = BASE + 22;
-    /** @hide */
-    public static final int STOP_RESOLVE_SUCCEEDED                  = BASE + 23;
-
-    /** @hide */
     public static final int ENABLE                                  = BASE + 24;
     /** @hide */
     public static final int DISABLE                                 = BASE + 25;
 
+    /** @hide */
+    public static final int NATIVE_DAEMON_EVENT                     = BASE + 26;
+
+    /** Dns based service discovery protocol */
+    public static final int PROTOCOL_DNS_SD = 0x0001;
+
+    private Context mContext;
+
+    private static final int INVALID_LISTENER_KEY = 0;
+    private int mListenerKey = 1;
+    private final SparseArray mListenerMap = new SparseArray();
+    private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>();
+    private final Object mMapLock = new Object();
+
+    private final AsyncChannel mAsyncChannel = new AsyncChannel();
+    private ServiceHandler mHandler;
+    private final CountDownLatch mConnected = new CountDownLatch(1);
 
     /**
      * Create a new Nsd instance. Applications use
@@ -238,271 +230,213 @@
      * @hide - hide this because it takes in a parameter of type INsdManager, which
      * is a system private class.
      */
-    public NsdManager(INsdManager service) {
+    public NsdManager(Context context, INsdManager service) {
         mService = service;
+        mContext = context;
+        init();
     }
 
     /**
-     * Passed with onFailure() calls.
+     * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
+     * {@link RegistrationListener#onUnregistrationFailed},
+     * {@link DiscoveryListener#onStartDiscoveryFailed},
+     * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
+     *
      * Indicates that the operation failed due to an internal error.
      */
-    public static final int ERROR               = 0;
+    public static final int FAILURE_INTERNAL_ERROR               = 0;
 
     /**
-     * Passed with onFailure() calls.
-     * Indicates that the operation failed because service discovery
-     * is unsupported on the device.
-     */
-    public static final int UNSUPPORTED         = 1;
-
-    /**
-     * Passed with onFailure() calls.
-     * Indicates that the operation failed because the framework is
-     * busy and unable to service the request.
-     */
-    public static final int BUSY                = 2;
-
-    /**
-     * Passed with onFailure() calls.
      * Indicates that the operation failed because it is already active.
      */
-    public static final int ALREADY_ACTIVE      = 3;
+    public static final int FAILURE_ALREADY_ACTIVE              = 3;
 
     /**
-     * Passed with onFailure() calls.
-     * Indicates that the operation failed because maximum limit on
-     * service registrations has reached.
+     * Indicates that the operation failed because the maximum outstanding
+     * requests from the applications have reached.
      */
-    public static final int MAX_REGS_REACHED    = 4;
-
-    /** Interface for callback invocation when framework channel is connected or lost */
-    public interface ChannelListener {
-       /**
-         * The channel to the framework is connected.
-         * Application can initiate calls into the framework using the channel instance passed.
-         */
-        public void onChannelConnected(Channel c);
-        /**
-         * The channel to the framework has been disconnected.
-         * Application could try re-initializing using {@link #initialize}
-         */
-        public void onChannelDisconnected();
-    }
-
-    /** Generic interface for callback invocation for a success or failure */
-    public interface ActionListener {
-
-        public void onFailure(int errorCode);
-
-        public void onSuccess();
-    }
+    public static final int FAILURE_MAX_LIMIT                   = 4;
 
     /** Interface for callback invocation for service discovery */
-    public interface DnsSdDiscoveryListener {
+    public interface DiscoveryListener {
 
-        public void onFailure(int errorCode);
+        public void onStartDiscoveryFailed(String serviceType, int errorCode);
 
-        public void onStarted(String serviceType);
+        public void onStopDiscoveryFailed(String serviceType, int errorCode);
 
-        public void onServiceFound(DnsSdServiceInfo serviceInfo);
+        public void onDiscoveryStarted(String serviceType);
 
-        public void onServiceLost(DnsSdServiceInfo serviceInfo);
+        public void onDiscoveryStopped(String serviceType);
+
+        public void onServiceFound(NsdServiceInfo serviceInfo);
+
+        public void onServiceLost(NsdServiceInfo serviceInfo);
 
     }
 
     /** Interface for callback invocation for service registration */
-    public interface DnsSdRegisterListener {
+    public interface RegistrationListener {
 
-        public void onFailure(int errorCode);
+        public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
 
-        public void onServiceRegistered(int registeredId, DnsSdServiceInfo serviceInfo);
-    }
+        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
 
-    /** @hide */
-    public interface DnsSdUpdateRegistrationListener {
+        public void onServiceRegistered(NsdServiceInfo serviceInfo);
 
-        public void onFailure(int errorCode);
-
-        public void onServiceUpdated(int registeredId, DnsSdTxtRecord txtRecord);
+        public void onServiceUnregistered(NsdServiceInfo serviceInfo);
     }
 
     /** Interface for callback invocation for service resolution */
-    public interface DnsSdResolveListener {
+    public interface ResolveListener {
 
-        public void onFailure(int errorCode);
+        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
 
-        public void onServiceResolved(DnsSdServiceInfo serviceInfo);
+        public void onServiceResolved(NsdServiceInfo serviceInfo);
     }
 
-    /**
-     * A channel that connects the application to the NetworkService framework.
-     * Most service operations require a Channel as an argument. An instance of Channel is obtained
-     * by doing a call on {@link #initialize}
-     */
-    public static class Channel {
-        Channel(Looper looper, ChannelListener l) {
-            mAsyncChannel = new AsyncChannel();
-            mHandler = new ServiceHandler(looper);
-            mChannelListener = l;
+    private class ServiceHandler extends Handler {
+        ServiceHandler(Looper looper) {
+            super(looper);
         }
-        private ChannelListener mChannelListener;
-        private DnsSdDiscoveryListener mDnsSdDiscoveryListener;
-        private ActionListener mDnsSdStopDiscoveryListener;
-        private DnsSdRegisterListener mDnsSdRegisterListener;
-        private ActionListener mDnsSdUnregisterListener;
-        private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
-        private DnsSdResolveListener mDnsSdResolveListener;
-        private ActionListener mDnsSdStopResolveListener;
 
-        private AsyncChannel mAsyncChannel;
-        private ServiceHandler mHandler;
-        class ServiceHandler extends Handler {
-            ServiceHandler(Looper looper) {
-                super(looper);
+        @Override
+        public void handleMessage(Message message) {
+            Object listener = getListener(message.arg2);
+            boolean listenerRemove = true;
+            switch (message.what) {
+                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                    mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+                    mConnected.countDown();
+                    break;
+                case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
+                    // Ignore
+                    break;
+                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                    Log.e(TAG, "Channel lost");
+                    break;
+                case DISCOVER_SERVICES_STARTED:
+                    String s = ((NsdServiceInfo) message.obj).getServiceType();
+                    ((DiscoveryListener) listener).onDiscoveryStarted(s);
+                    // Keep listener until stop discovery
+                    listenerRemove = false;
+                    break;
+                case DISCOVER_SERVICES_FAILED:
+                    ((DiscoveryListener) listener).onStartDiscoveryFailed(
+                            getNsdService(message.arg2).getServiceType(), message.arg1);
+                    break;
+                case SERVICE_FOUND:
+                    ((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj);
+                    // Keep listener until stop discovery
+                    listenerRemove = false;
+                    break;
+                case SERVICE_LOST:
+                    ((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj);
+                    // Keep listener until stop discovery
+                    listenerRemove = false;
+                    break;
+                case STOP_DISCOVERY_FAILED:
+                    ((DiscoveryListener) listener).onStopDiscoveryFailed(
+                            getNsdService(message.arg2).getServiceType(), message.arg1);
+                    break;
+                case STOP_DISCOVERY_SUCCEEDED:
+                    ((DiscoveryListener) listener).onDiscoveryStopped(
+                            getNsdService(message.arg2).getServiceType());
+                    break;
+                case REGISTER_SERVICE_FAILED:
+                    ((RegistrationListener) listener).onRegistrationFailed(
+                            getNsdService(message.arg2), message.arg1);
+                    break;
+                case REGISTER_SERVICE_SUCCEEDED:
+                    ((RegistrationListener) listener).onServiceRegistered(
+                            (NsdServiceInfo) message.obj);
+                    // Keep listener until unregister
+                    listenerRemove = false;
+                    break;
+                case UNREGISTER_SERVICE_FAILED:
+                    ((RegistrationListener) listener).onUnregistrationFailed(
+                            getNsdService(message.arg2), message.arg1);
+                    break;
+                case UNREGISTER_SERVICE_SUCCEEDED:
+                    ((RegistrationListener) listener).onServiceUnregistered(
+                            getNsdService(message.arg2));
+                    break;
+                case RESOLVE_SERVICE_FAILED:
+                    ((ResolveListener) listener).onResolveFailed(
+                            getNsdService(message.arg2), message.arg1);
+                    break;
+                case RESOLVE_SERVICE_SUCCEEDED:
+                    ((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);
+                    break;
+                default:
+                    Log.d(TAG, "Ignored " + message);
+                    break;
             }
-
-            @Override
-            public void handleMessage(Message message) {
-                switch (message.what) {
-                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                        mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
-                        if (mChannelListener != null) {
-                            mChannelListener.onChannelConnected(Channel.this);
-                        }
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        if (mChannelListener != null) {
-                            mChannelListener.onChannelDisconnected();
-                            mChannelListener = null;
-                        }
-                        break;
-                    case DISCOVER_SERVICES_STARTED:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onStarted((String) message.obj);
-                        }
-                        break;
-                    case DISCOVER_SERVICES_FAILED:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case SERVICE_FOUND:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onServiceFound(
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case SERVICE_LOST:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onServiceLost(
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case STOP_DISCOVERY_FAILED:
-                        if (mDnsSdStopDiscoveryListener != null) {
-                            mDnsSdStopDiscoveryListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case STOP_DISCOVERY_SUCCEEDED:
-                        if (mDnsSdStopDiscoveryListener != null) {
-                            mDnsSdStopDiscoveryListener.onSuccess();
-                        }
-                        break;
-                    case REGISTER_SERVICE_FAILED:
-                        if (mDnsSdRegisterListener != null) {
-                            mDnsSdRegisterListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case REGISTER_SERVICE_SUCCEEDED:
-                        if (mDnsSdRegisterListener != null) {
-                            mDnsSdRegisterListener.onServiceRegistered(message.arg1,
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case UNREGISTER_SERVICE_FAILED:
-                        if (mDnsSdUnregisterListener != null) {
-                            mDnsSdUnregisterListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case UNREGISTER_SERVICE_SUCCEEDED:
-                        if (mDnsSdUnregisterListener != null) {
-                            mDnsSdUnregisterListener.onSuccess();
-                        }
-                        break;
-                   case UPDATE_SERVICE_FAILED:
-                        if (mDnsSdUpdateListener != null) {
-                            mDnsSdUpdateListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case UPDATE_SERVICE_SUCCEEDED:
-                        if (mDnsSdUpdateListener != null) {
-                            mDnsSdUpdateListener.onServiceUpdated(message.arg1,
-                                    (DnsSdTxtRecord) message.obj);
-                        }
-                        break;
-                    case RESOLVE_SERVICE_FAILED:
-                        if (mDnsSdResolveListener != null) {
-                            mDnsSdResolveListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case RESOLVE_SERVICE_SUCCEEDED:
-                        if (mDnsSdResolveListener != null) {
-                            mDnsSdResolveListener.onServiceResolved(
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case STOP_RESOLVE_FAILED:
-                        if (mDnsSdStopResolveListener!= null) {
-                            mDnsSdStopResolveListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case STOP_RESOLVE_SUCCEEDED:
-                        if (mDnsSdStopResolveListener != null) {
-                            mDnsSdStopResolveListener.onSuccess();
-                        }
-                        break;
-                    default:
-                        Log.d(TAG, "Ignored " + message);
-                        break;
-                }
+            if (listenerRemove) {
+                removeListener(message.arg2);
             }
         }
-   }
-
-    private static void checkChannel(Channel c) {
-        if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
     }
 
+    private int putListener(Object listener, NsdServiceInfo s) {
+        if (listener == null) return INVALID_LISTENER_KEY;
+        int key;
+        synchronized (mMapLock) {
+            do {
+                key = mListenerKey++;
+            } while (key == INVALID_LISTENER_KEY);
+            mListenerMap.put(key, listener);
+            mServiceMap.put(key, s);
+        }
+        return key;
+    }
+
+    private Object getListener(int key) {
+        if (key == INVALID_LISTENER_KEY) return null;
+        synchronized (mMapLock) {
+            return mListenerMap.get(key);
+        }
+    }
+
+    private NsdServiceInfo getNsdService(int key) {
+        synchronized (mMapLock) {
+            return mServiceMap.get(key);
+        }
+    }
+
+    private void removeListener(int key) {
+        if (key == INVALID_LISTENER_KEY) return;
+        synchronized (mMapLock) {
+            mListenerMap.remove(key);
+            mServiceMap.remove(key);
+        }
+    }
+
+    private int getListenerKey(Object listener) {
+        synchronized (mMapLock) {
+            int valueIndex = mListenerMap.indexOfValue(listener);
+            if (valueIndex != -1) {
+                return mListenerMap.keyAt(valueIndex);
+            }
+        }
+        return INVALID_LISTENER_KEY;
+    }
+
+
     /**
-     * Registers the application with the service discovery framework. This function
-     * must be the first to be called before any other operations are performed. No service
-     * discovery operations must be performed until the ChannelListener callback notifies
-     * that the channel is connected
-     *
-     * @param srcContext is the context of the source
-     * @param srcLooper is the Looper on which the callbacks are receivied
-     * @param listener for callback at loss of framework communication. Cannot be null.
+     * Initialize AsyncChannel
      */
-    public void initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
-        Messenger messenger = getMessenger();
+    private void init() {
+        final Messenger messenger = getMessenger();
         if (messenger == null) throw new RuntimeException("Failed to initialize");
-        if (listener == null) throw new IllegalArgumentException("ChannelListener cannot be null");
-
-        Channel c = new Channel(srcLooper, listener);
-        c.mAsyncChannel.connect(srcContext, c.mHandler, messenger);
-    }
-
-    /**
-     * Disconnects application from service discovery framework. No further operations
-     * will succeed until a {@link #initialize} is called again.
-     *
-     * @param c channel initialized with {@link #initialize}
-     */
-    public void deinitialize(Channel c) {
-        checkChannel(c);
-        c.mAsyncChannel.disconnect();
+        HandlerThread t = new HandlerThread("NsdManager");
+        t.start();
+        mHandler = new ServiceHandler(t.getLooper());
+        mAsyncChannel.connect(mContext, mHandler, messenger);
+        try {
+            mConnected.await();
+        } catch (InterruptedException e) {
+            Log.e(TAG, "interrupted wait at init");
+        }
     }
 
     /**
@@ -510,45 +444,51 @@
      *
      * <p> The function call immediately returns after sending a request to register service
      * to the framework. The application is notified of a success to initiate
-     * discovery through the callback {@link DnsSdRegisterListener#onServiceRegistered} or a failure
-     * through {@link DnsSdRegisterListener#onFailure}.
+     * discovery through the callback {@link RegistrationListener#onServiceRegistered} or a failure
+     * through {@link RegistrationListener#onRegistrationFailed}.
      *
-     * @param c is the channel created at {@link #initialize}
-     * @param serviceType The service type being advertised.
-     * @param port on which the service is listenering for incoming connections
-     * @param listener for success or failure callback. Can be null.
+     * @param serviceInfo The service being registered
+     * @param protocolType The service discovery protocol
+     * @param listener The listener notifies of a successful registration and is used to
+     * unregister this service through a call on {@link #unregisterService}. Cannot be null.
      */
-    public void registerService(Channel c, String serviceName, String serviceType, int port,
-            DnsSdRegisterListener listener) {
-        checkChannel(c);
-        if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+    public void registerService(NsdServiceInfo serviceInfo, int protocolType,
+            RegistrationListener listener) {
+        if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+                TextUtils.isEmpty(serviceInfo.getServiceType())) {
             throw new IllegalArgumentException("Service name or type cannot be empty");
         }
-        if (port <= 0) {
+        if (serviceInfo.getPort() <= 0) {
             throw new IllegalArgumentException("Invalid port number");
         }
-        DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
-        serviceInfo.setPort(port);
-        c.mDnsSdRegisterListener = listener;
-        c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo);
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        if (protocolType != PROTOCOL_DNS_SD) {
+            throw new IllegalArgumentException("Unsupported protocol");
+        }
+        mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, putListener(listener, serviceInfo),
+                serviceInfo);
     }
 
     /**
-     * Unregister a service registered through {@link #registerService}
-     * @param c is the channel created at {@link #initialize}
-     * @param registeredId is obtained at {@link DnsSdRegisterListener#onServiceRegistered}
-     * @param listener provides callbacks for success or failure. Can be null.
+     * Unregister a service registered through {@link #registerService}. A successful
+     * unregister is notified to the application with a call to
+     * {@link RegistrationListener#onServiceUnregistered}.
+     *
+     * @param listener This should be the listener object that was passed to
+     * {@link #registerService}. It identifies the service that should be unregistered
+     * and notifies of a successful unregistration.
      */
-    public void unregisterService(Channel c, int registeredId, ActionListener listener) {
-        checkChannel(c);
-        c.mDnsSdUnregisterListener = listener;
-        c.mAsyncChannel.sendMessage(UNREGISTER_SERVICE, registeredId);
-    }
-
-    /** @hide */
-    public void updateService(Channel c, int registeredId, DnsSdTxtRecord txtRecord) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(UPDATE_SERVICE, registeredId, 0, txtRecord);
+    public void unregisterService(RegistrationListener listener) {
+        int id = getListenerKey(listener);
+        if (id == INVALID_LISTENER_KEY) {
+            throw new IllegalArgumentException("listener not registered");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        mAsyncChannel.sendMessage(UNREGISTER_SERVICE, 0, id);
     }
 
     /**
@@ -558,51 +498,61 @@
      *
      * <p> The function call immediately returns after sending a request to start service
      * discovery to the framework. The application is notified of a success to initiate
-     * discovery through the callback {@link DnsSdDiscoveryListener#onStarted} or a failure
-     * through {@link DnsSdDiscoveryListener#onFailure}.
+     * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+     * through {@link DiscoveryListener#onStartDiscoveryFailed}.
      *
      * <p> Upon successful start, application is notified when a service is found with
-     * {@link DnsSdDiscoveryListener#onServiceFound} or when a service is lost with
-     * {@link DnsSdDiscoveryListener#onServiceLost}.
+     * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+     * {@link DiscoveryListener#onServiceLost}.
      *
      * <p> Upon failure to start, service discovery is not active and application does
      * not need to invoke {@link #stopServiceDiscovery}
      *
-     * @param c is the channel created at {@link #initialize}
      * @param serviceType The service type being discovered. Examples include "_http._tcp" for
      * http services or "_ipp._tcp" for printers
-     * @param listener provides callbacks when service is found or lost. Cannot be null.
+     * @param protocolType The service discovery protocol
+     * @param listener  The listener notifies of a successful discovery and is used
+     * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+     * Cannot be null.
      */
-    public void discoverServices(Channel c, String serviceType, DnsSdDiscoveryListener listener) {
-        checkChannel(c);
+    public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
         if (listener == null) {
-            throw new IllegalStateException("Discovery listener needs to be set first");
+            throw new IllegalArgumentException("listener cannot be null");
         }
         if (TextUtils.isEmpty(serviceType)) {
-            throw new IllegalStateException("Service type cannot be empty");
+            throw new IllegalArgumentException("Service type cannot be empty");
         }
-        DnsSdServiceInfo s = new DnsSdServiceInfo();
+
+        if (protocolType != PROTOCOL_DNS_SD) {
+            throw new IllegalArgumentException("Unsupported protocol");
+        }
+
+        NsdServiceInfo s = new NsdServiceInfo();
         s.setServiceType(serviceType);
-        c.mDnsSdDiscoveryListener = listener;
-        c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, s);
+        mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, putListener(listener, s), s);
     }
 
     /**
      * Stop service discovery initiated with {@link #discoverServices}. An active service
-     * discovery is notified to the application with {@link DnsSdDiscoveryListener#onStarted}
-     * and it stays active until the application invokes a stop service discovery.
+     * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
+     * and it stays active until the application invokes a stop service discovery. A successful
+     * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
      *
-     * <p> Upon failure to start service discovery notified through
-     * {@link DnsSdDiscoveryListener#onFailure} service discovery is not active and
-     * application does not need to stop it.
+     * <p> Upon failure to stop service discovery, application is notified through
+     * {@link DiscoveryListener#onStopDiscoveryFailed}.
      *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener notifies success or failure. Can be null.
+     * @param listener This should be the listener object that was passed to {@link #discoverServices}.
+     * It identifies the discovery that should be stopped and notifies of a successful stop.
      */
-    public void stopServiceDiscovery(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mDnsSdStopDiscoveryListener = listener;
-        c.mAsyncChannel.sendMessage(STOP_DISCOVERY);
+    public void stopServiceDiscovery(DiscoveryListener listener) {
+        int id = getListenerKey(listener);
+        if (id == INVALID_LISTENER_KEY) {
+            throw new IllegalArgumentException("service discovery not active on listener");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, id);
     }
 
     /**
@@ -610,30 +560,19 @@
      * establishing a connection to fetch the IP and port details on which to setup
      * the connection.
      *
-     * @param c is the channel created at {@link #initialize}
-     * @param serviceName of the the service
-     * @param serviceType of the service
+     * @param serviceInfo service to be resolved
      * @param listener to receive callback upon success or failure. Cannot be null.
      */
-    public void resolveService(Channel c, String serviceName, String serviceType,
-            DnsSdResolveListener listener) {
-        checkChannel(c);
-        if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+    public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
+        if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+                TextUtils.isEmpty(serviceInfo.getServiceType())) {
             throw new IllegalArgumentException("Service name or type cannot be empty");
         }
-        if (listener == null) throw new
-                IllegalStateException("Resolve listener cannot be null");
-        c.mDnsSdResolveListener = listener;
-        DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
-        c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo);
-    }
-
-    /** @hide */
-    public void stopServiceResolve(Channel c) {
-        checkChannel(c);
-        if (c.mDnsSdResolveListener == null) throw new
-                IllegalStateException("Resolve listener needs to be set first");
-        c.mAsyncChannel.sendMessage(STOP_RESOLVE);
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, putListener(listener, serviceInfo),
+                serviceInfo);
     }
 
     /** Internal use only @hide */
diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/NsdServiceInfo.java
similarity index 86%
rename from core/java/android/net/nsd/DnsSdServiceInfo.java
rename to core/java/android/net/nsd/NsdServiceInfo.java
index 66abd3a..205a21d 100644
--- a/core/java/android/net/nsd/DnsSdServiceInfo.java
+++ b/core/java/android/net/nsd/NsdServiceInfo.java
@@ -25,7 +25,7 @@
  * A class representing service information for network service discovery
  * {@see NsdManager}
  */
-public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
+public final class NsdServiceInfo implements Parcelable {
 
     private String mServiceName;
 
@@ -37,36 +37,32 @@
 
     private int mPort;
 
-    public DnsSdServiceInfo() {
+    public NsdServiceInfo() {
     }
 
     /** @hide */
-    public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
+    public NsdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
         mServiceName = sn;
         mServiceType = rt;
         mTxtRecord = tr;
     }
 
     /** Get the service name */
-    @Override
     public String getServiceName() {
         return mServiceName;
     }
 
     /** Set the service name */
-    @Override
     public void setServiceName(String s) {
         mServiceName = s;
     }
 
     /** Get the service type */
-    @Override
     public String getServiceType() {
         return mServiceType;
     }
 
     /** Set the service type */
-    @Override
     public void setServiceType(String s) {
         mServiceType = s;
     }
@@ -132,10 +128,10 @@
     }
 
     /** Implement the Parcelable interface */
-    public static final Creator<DnsSdServiceInfo> CREATOR =
-        new Creator<DnsSdServiceInfo>() {
-            public DnsSdServiceInfo createFromParcel(Parcel in) {
-                DnsSdServiceInfo info = new DnsSdServiceInfo();
+    public static final Creator<NsdServiceInfo> CREATOR =
+        new Creator<NsdServiceInfo>() {
+            public NsdServiceInfo createFromParcel(Parcel in) {
+                NsdServiceInfo info = new NsdServiceInfo();
                 info.mServiceName = in.readString();
                 info.mServiceType = in.readString();
                 info.mTxtRecord = in.readParcelable(null);
@@ -150,8 +146,8 @@
                 return info;
             }
 
-            public DnsSdServiceInfo[] newArray(int size) {
-                return new DnsSdServiceInfo[size];
+            public NsdServiceInfo[] newArray(int size) {
+                return new NsdServiceInfo[size];
             }
         };
 }
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 0e9e8f4..8872335 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -321,7 +321,7 @@
      * and {@link #RTD_URI}. This is the most efficient encoding
      * of a URI into NDEF.<p>
      * The uri parameter will be normalized with
-     * {@link Uri#normalize} to set the scheme to lower case to
+     * {@link Uri#normalizeScheme} to set the scheme to lower case to
      * follow Android best practices for intent filtering.
      * However the unchecked exception
      * {@link IllegalArgumentException} may be thrown if the uri
@@ -338,7 +338,7 @@
     public static NdefRecord createUri(Uri uri) {
         if (uri == null) throw new NullPointerException("uri is null");
 
-        uri = uri.normalize();
+        uri = uri.normalizeScheme();
         String uriString = uri.toString();
         if (uriString.length() == 0) throw new IllegalArgumentException("uri is empty");
 
@@ -364,7 +364,7 @@
      * and {@link #RTD_URI}. This is the most efficient encoding
      * of a URI into NDEF.<p>
       * The uriString parameter will be normalized with
-     * {@link Uri#normalize} to set the scheme to lower case to
+     * {@link Uri#normalizeScheme} to set the scheme to lower case to
      * follow Android best practices for intent filtering.
      * However the unchecked exception
      * {@link IllegalArgumentException} may be thrown if the uriString
@@ -665,7 +665,7 @@
      * actually valid: it always attempts to create and return a URI if
      * this record appears to be a URI record by the above rules.<p>
      * The returned URI will be normalized to have a lower case scheme
-     * using {@link Uri#normalize}.<p>
+     * using {@link Uri#normalizeScheme}.<p>
      *
      * @return URI, or null if this is not a URI record
      */
@@ -688,13 +688,13 @@
                         }
                     } catch (FormatException e) {  }
                 } else if (Arrays.equals(mType, RTD_URI)) {
-                    return parseWktUri().normalize();
+                    return parseWktUri().normalizeScheme();
                 }
                 break;
 
             case TNF_ABSOLUTE_URI:
                 Uri uri = Uri.parse(new String(mType, Charsets.UTF_8));
-                return uri.normalize();
+                return uri.normalizeScheme();
 
             case TNF_EXTERNAL_TYPE:
                 if (inSmartPoster) {
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 0586d9e..b7bc45f 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -140,6 +140,9 @@
      */
     int LIKE_TRANSACTION   = ('_'<<24)|('L'<<16)|('I'<<8)|'K';
 
+    /** @hide */
+    int SYSPROPS_TRANSACTION = ('_'<<24)|('S'<<16)|('P'<<8)|'R';
+
     /**
      * Flag to {@link #transact}: this is a one-way call, meaning that the
      * caller returns immediately, without waiting for a result from the
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 1df53e8..18fd3cb 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -897,6 +897,9 @@
     public static final native long getFreeMemory();
     
     /** @hide */
+    public static final native long getTotalMemory();
+    
+    /** @hide */
     public static final native void readProcLines(String path,
             String[] reqFields, long[] outSizes);
     
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 43b5128..be24426 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import java.util.ArrayList;
+
 
 /**
  * Native implementation of the service manager.  Most clients will only
@@ -151,14 +153,32 @@
     }
     
     public String[] listServices() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IServiceManager.descriptor);
-        mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
-        String[] list = reply.readStringArray();
-        reply.recycle();
-        data.recycle();
-        return list;
+        ArrayList<String> services = new ArrayList<String>();
+        int n = 0;
+        while (true) {
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInterfaceToken(IServiceManager.descriptor);
+            data.writeInt(n);
+            n++;
+            try {
+                boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
+                if (!res) {
+                    break;
+                }
+            } catch (RuntimeException e) {
+                // The result code that is returned by the C++ code can
+                // cause the call to throw an exception back instead of
+                // returning a nice result...  so eat it here and go on.
+                break;
+            }
+            services.add(reply.readString());
+            reply.recycle();
+            data.recycle();
+        }
+        String[] array = new String[services.size()];
+        services.toArray(array);
+        return array;
     }
 
     public void setPermissionController(IPermissionController controller)
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 619bf8d..156600e 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -16,6 +16,10 @@
 
 package android.os;
 
+import java.util.ArrayList;
+
+import android.util.Log;
+
 
 /**
  * Gives access to the system properties store.  The system properties
@@ -28,12 +32,15 @@
     public static final int PROP_NAME_MAX = 31;
     public static final int PROP_VALUE_MAX = 91;
 
+    private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
+
     private static native String native_get(String key);
     private static native String native_get(String key, String def);
     private static native int native_get_int(String key, int def);
     private static native long native_get_long(String key, long def);
     private static native boolean native_get_boolean(String key, boolean def);
     private static native void native_set(String key, String def);
+    private static native void native_add_change_callback();
 
     /**
      * Get the value for the given key.
@@ -124,4 +131,26 @@
         }
         native_set(key, val);
     }
+
+    public static void addChangeCallback(Runnable callback) {
+        synchronized (sChangeCallbacks) {
+            if (sChangeCallbacks.size() == 0) {
+                native_add_change_callback();
+            }
+            sChangeCallbacks.add(callback);
+        }
+    }
+
+    static void callChangeCallbacks() {
+        synchronized (sChangeCallbacks) {
+            //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
+            if (sChangeCallbacks.size() == 0) {
+                return;
+            }
+            ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
+            for (int i=0; i<callbacks.size(); i++) {
+                callbacks.get(i).run();
+            }
+        }
+    }
 }
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index ac9ee26..911183d 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -39,13 +39,29 @@
     public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
     public static final long TRACE_TAG_AUDIO = 1L << 8;
 
-    private static final long sEnabledTags = nativeGetEnabledTags();
+    public static final int TRACE_FLAGS_START_BIT = 1;
+    public static final String[] TRACE_TAGS = {
+        "Graphics", "Input", "View", "WebView", "Window Manager",
+        "Activity Manager", "Sync Manager", "Audio"
+    };
+
+    public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
+
+    private static long sEnabledTags = nativeGetEnabledTags();
 
     private static native long nativeGetEnabledTags();
     private static native void nativeTraceCounter(long tag, String name, int value);
     private static native void nativeTraceBegin(long tag, String name);
     private static native void nativeTraceEnd(long tag);
 
+    static {
+        SystemProperties.addChangeCallback(new Runnable() {
+            @Override public void run() {
+                sEnabledTags = nativeGetEnabledTags();
+            }
+        });
+    }
+
     private Trace() {
     }
 
diff --git a/core/java/android/preference/MultiCheckPreference.java b/core/java/android/preference/MultiCheckPreference.java
index 735f66ae..6953075 100644
--- a/core/java/android/preference/MultiCheckPreference.java
+++ b/core/java/android/preference/MultiCheckPreference.java
@@ -136,11 +136,25 @@
      * 
      * @return The array of values.
      */
-    public CharSequence[] getEntryValues() {
+    public String[] getEntryValues() {
         return mEntryValues;
     }
 
     /**
+     * Get the boolean state of a given value.
+     */
+    public boolean getValue(int index) {
+        return mSetValues[index];
+    }
+
+    /**
+     * Set the boolean state of a given value.
+     */
+    public void setValue(int index, boolean state) {
+        mSetValues[index] = state;
+    }
+
+    /**
      * Sets the current values.
      */
     public void setValues(boolean[] values) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2f7a9ec..497e66e8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1410,6 +1410,7 @@
         /**
          * Adjustment to auto-brightness to make it generally more (>0.0 <1.0)
          * or less (<0.0 >-1.0) bright.
+         * @hide
          */
         public static final String SCREEN_AUTO_BRIGHTNESS_ADJ = "screen_auto_brightness_adj";
 
@@ -1749,6 +1750,20 @@
         public static final String USER_ROTATION = "user_rotation";
 
         /**
+         * Whether the phone vibrates when it is ringing due to an incoming call. This will
+         * be used by Phone and Setting apps; it shouldn't affect other apps.
+         * The value is boolean (1 or 0).
+         *
+         * Note: this is not same as "vibrate on ring", which had been available until ICS.
+         * It was about AudioManager's setting and thus affected all the applications which
+         * relied on the setting, while this is purely about the vibration setting for incoming
+         * calls.
+         *
+         * @hide
+         */
+        public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+
+        /**
          * Whether the audible DTMF tones are played by the dialer when dialing. The value is
          * boolean (1 or 0).
          */
@@ -2030,6 +2045,7 @@
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
             POINTER_SPEED,
+            VIBRATE_WHEN_RINGING
         };
 
         // Settings moved to Settings.Secure
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 881594d..d42757d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -413,7 +413,7 @@
                         // focus instead fetching all provider nodes to do the search here.
                         AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
                         if (provider != null) {
-                            focused = provider.findAccessibilitiyFocus(virtualDescendantId);
+                            focused = provider.findAccessibilityFocus(virtualDescendantId);
                         } else if (virtualDescendantId == View.NO_ID) {
                             focused = host.createAccessibilityNodeInfo();
                         }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index e1f01db..c5a687a 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -84,7 +84,7 @@
     void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
             int startHeight);
     void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback);
+            IRemoteCallback startedCallback, boolean delayed);
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
             in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 5b371eb..2cb724f 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -386,19 +386,19 @@
      *
      * @param keyCode The key code.
      * @param metaState The meta key modifier state.
-     * @param outFallbackAction The fallback action object to populate.
-     * @return True if a fallback action was found, false otherwise.
+     * @return The fallback action, or null if none.  Remember to recycle the fallback action.
      *
      * @hide
      */
-    public boolean getFallbackAction(int keyCode, int metaState,
-            FallbackAction outFallbackAction) {
-        if (outFallbackAction == null) {
-            throw new IllegalArgumentException("fallbackAction must not be null");
-        }
-
+    public FallbackAction getFallbackAction(int keyCode, int metaState) {
+        FallbackAction action = FallbackAction.obtain();
         metaState = KeyEvent.normalizeMetaState(metaState);
-        return nativeGetFallbackAction(mPtr, keyCode, metaState, outFallbackAction);
+        if (nativeGetFallbackAction(mPtr, keyCode, metaState, action)) {
+            action.metaState = KeyEvent.normalizeMetaState(action.metaState);
+            return action;
+        }
+        action.recycle();
+        return null;
     }
 
     /**
@@ -727,7 +727,44 @@
      * @hide
      */
     public static final class FallbackAction {
+        private static final int MAX_RECYCLED = 10;
+        private static final Object sRecycleLock = new Object();
+        private static FallbackAction sRecycleBin;
+        private static int sRecycledCount;
+
+        private FallbackAction next;
+
         public int keyCode;
         public int metaState;
+
+        private FallbackAction() {
+        }
+
+        public static FallbackAction obtain() {
+            final FallbackAction target;
+            synchronized (sRecycleLock) {
+                if (sRecycleBin == null) {
+                    target = new FallbackAction();
+                } else {
+                    target = sRecycleBin;
+                    sRecycleBin = target.next;
+                    sRecycledCount--;
+                    target.next = null;
+                }
+            }
+            return target;
+        }
+
+        public void recycle() {
+            synchronized (sRecycleLock) {
+                if (sRecycledCount < MAX_RECYCLED) {
+                    next = sRecycleBin;
+                    sRecycleBin = this;
+                    sRecycledCount += 1;
+                } else {
+                    next = null;
+                }
+            }
+        }
     }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2befcce..aad6756 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4676,13 +4676,13 @@
         }
 
         RectF position = mAttachInfo.mTmpTransformRect;
-        position.setEmpty();
+        position.set(0, 0, mRight - mLeft, mBottom - mTop);
 
         if (!hasIdentityMatrix()) {
             getMatrix().mapRect(position);
         }
 
-        position.offset(mLeft, mRight);
+        position.offset(mLeft, mTop);
 
         ViewParent parent = mParent;
         while (parent instanceof View) {
@@ -17250,7 +17250,7 @@
         /**
          * Show where the margins, bounds and layout bounds are for each view.
          */
-        final boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
+        boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
 
         /**
          * Point used to compute visible regions.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5f295cb..b43db14 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -328,8 +328,6 @@
 
     private final int mDensity;
 
-    final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
-
     /**
      * Consistency verifier for debugging purposes.
      */
@@ -408,6 +406,7 @@
 
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mAttachInfo.mScreenOn = powerManager.isScreenOn();
+        loadSystemProperties();
     }
 
     /**
@@ -846,6 +845,16 @@
         scheduleTraversals();
     }
 
+    void invalidateWorld(View view) {
+        view.invalidate();
+        if (view instanceof ViewGroup) {
+            ViewGroup parent = (ViewGroup)view;
+            for (int i=0; i<parent.getChildCount(); i++) {
+                invalidateWorld(parent.getChildAt(i));
+            }
+        }
+    }
+
     public void invalidateChild(View child, Rect dirty) {
         invalidateChildInParent(null, dirty);
     }
@@ -2373,7 +2382,7 @@
             }
         } else {
             if (mAccessibilityFocusedVirtualView == null) {
-                mAccessibilityFocusedVirtualView = provider.findAccessibilitiyFocus(View.NO_ID);
+                mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
             }
             if (mAccessibilityFocusedVirtualView == null) {
                 return;
@@ -2730,6 +2739,7 @@
     private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
     private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
     private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
+    private final static int MSG_INVALIDATE_WORLD = 24;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -2997,6 +3007,9 @@
             case MSG_DISPATCH_DONE_ANIMATING: {
                 handleDispatchDoneAnimating();
             } break;
+            case MSG_INVALIDATE_WORLD: {
+                invalidateWorld(mView);
+            } break;
             }
         }
     }
@@ -4016,6 +4029,17 @@
         mHandler.sendMessage(msg);
     }
 
+    public void loadSystemProperties() {
+        boolean layout = SystemProperties.getBoolean(
+                View.DEBUG_LAYOUT_PROPERTY, false);
+        if (layout != mAttachInfo.mDebugLayout) {
+            mAttachInfo.mDebugLayout = layout;
+            if (!mHandler.hasMessages(MSG_INVALIDATE_WORLD)) {
+                mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_WORLD, 200);
+            }
+        }
+    }
+
     private void destroyHardwareRenderer() {
         AttachInfo attachInfo = mAttachInfo;
         HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer;
@@ -4455,20 +4479,19 @@
             final int keyCode = event.getKeyCode();
             final int metaState = event.getMetaState();
 
-            KeyEvent fallbackEvent = null;
-            synchronized (mFallbackAction) {
-                // Check for fallback actions specified by the key character map.
-                if (kcm.getFallbackAction(keyCode, metaState, mFallbackAction)) {
-                    int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
-                    fallbackEvent = KeyEvent.obtain(
-                            event.getDownTime(), event.getEventTime(),
-                            event.getAction(), mFallbackAction.keyCode,
-                            event.getRepeatCount(), mFallbackAction.metaState,
-                            event.getDeviceId(), event.getScanCode(),
-                            flags, event.getSource(), null);
-                }
-            }
-            if (fallbackEvent != null) {
+            // Check for fallback actions specified by the key character map.
+            KeyCharacterMap.FallbackAction fallbackAction =
+                    kcm.getFallbackAction(keyCode, metaState);
+            if (fallbackAction != null) {
+                final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+                KeyEvent fallbackEvent = KeyEvent.obtain(
+                        event.getDownTime(), event.getEventTime(),
+                        event.getAction(), fallbackAction.keyCode,
+                        event.getRepeatCount(), fallbackAction.metaState,
+                        event.getDeviceId(), event.getScanCode(),
+                        flags, event.getSource(), null);
+                fallbackAction.recycle();
+
                 dispatchKey(fallbackEvent);
             }
         }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index b5690e9..5d33cec 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -23,6 +23,7 @@
 import android.graphics.PixelFormat;
 import android.opengl.ManagedEGLContext;
 import android.os.IBinder;
+import android.os.SystemProperties;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 import android.view.inputmethod.InputMethodManager;
@@ -112,6 +113,8 @@
     private WindowManager.LayoutParams[] mParams;
     private boolean mNeedsEglTerminate;
 
+    private Runnable mSystemPropertyUpdater = null;
+
     private final static Object sLock = new Object();
     private final static WindowManagerImpl sWindowManager = new WindowManagerImpl();
     private final static HashMap<CompatibilityInfo, WindowManager> sCompatWindowManagers
@@ -237,6 +240,22 @@
         View panelParentView = null;
         
         synchronized (this) {
+            // Start watching for system property changes.
+            if (mSystemPropertyUpdater == null) {
+                mSystemPropertyUpdater = new Runnable() {
+                    @Override public void run() {
+                        synchronized (this) {
+                            synchronized (this) {
+                                for (ViewRootImpl root : mRoots) {
+                                    root.loadSystemProperties();
+                                }
+                            }
+                        }
+                    }
+                };
+                SystemProperties.addChangeCallback(mSystemPropertyUpdater);
+            }
+
             // Here's an odd/questionable case: if someone tries to add a
             // view multiple times, then we simply bump up a nesting count
             // and they need to remove the view the corresponding number of
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 6b14ba5..0517d4b 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -205,6 +205,16 @@
     public static final int ACTION_PREVIOUS_HTML_ELEMENT = 0x00000800;
 
     /**
+     * Action to scroll the node content forward.
+     */
+    public static final int ACTION_SCROLL_FORWARD = 0x00001000;
+
+    /**
+     * Action to scroll the node content backward.
+     */
+    public static final int ACTION_SCROLL_BACKWARD = 0x00002000;
+
+    /**
      * Argument for which movement granularity to be used when traversing the node text.
      * <p>
      * <strong>Type:</strong> int<br>
@@ -569,6 +579,16 @@
      * @see AccessibilityNodeInfo#ACTION_CLEAR_FOCUS
      * @see AccessibilityNodeInfo#ACTION_SELECT
      * @see AccessibilityNodeInfo#ACTION_CLEAR_SELECTION
+     * @see AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS
+     * @see AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS
+     * @see AccessibilityNodeInfo#ACTION_CLICK
+     * @see AccessibilityNodeInfo#ACTION_LONG_CLICK
+     * @see AccessibilityNodeInfo#ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+     * @see AccessibilityNodeInfo#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+     * @see AccessibilityNodeInfo#ACTION_NEXT_HTML_ELEMENT
+     * @see AccessibilityNodeInfo#ACTION_PREVIOUS_HTML_ELEMENT
+     * @see AccessibilityNodeInfo#ACTION_SCROLL_FORWARD
+     * @see AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD
      */
     public int getActions() {
         return mActions;
@@ -1578,6 +1598,10 @@
                 return "ACTION_NEXT_HTML_ELEMENT";
             case ACTION_PREVIOUS_HTML_ELEMENT:
                 return "ACTION_PREVIOUS_HTML_ELEMENT";
+            case ACTION_SCROLL_FORWARD:
+                return "ACTION_SCROLL_FORWARD";
+            case ACTION_SCROLL_BACKWARD:
+                return "ACTION_SCROLL_BACKWARD";
             default:
                 throw new IllegalArgumentException("Unknown action: " + action);
         }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index a2e0d88..e60716d 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -151,7 +151,7 @@
      * @see #createAccessibilityNodeInfo(int)
      * @see AccessibilityNodeInfo
      */
-    public AccessibilityNodeInfo findAccessibilitiyFocus(int virtualViewId) {
+    public AccessibilityNodeInfo findAccessibilityFocus(int virtualViewId) {
         return null;
     }
 
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 17e4efb..057c3d1 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -609,6 +609,10 @@
     // The presumed scroll rate for the first scroll of edit text
     static private final long TEXT_SCROLL_FIRST_SCROLL_MS = 16;
 
+    // Buffer pixels of the caret rectangle when moving edit text into view
+    // after resize.
+    static private final int EDIT_RECT_BUFFER = 10;
+
     // true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
     private boolean mAutoRedraw;
 
@@ -3294,7 +3298,8 @@
     }
 
     public int getPageBackgroundColor() {
-        return nativeGetBackgroundColor();
+        if (mNativeClass == 0) return Color.WHITE;
+        return nativeGetBackgroundColor(mNativeClass);
     }
 
     /**
@@ -4451,7 +4456,7 @@
         if (mNativeClass == 0) {
             return 0;
         }
-        return nativeGetBaseLayer();
+        return nativeGetBaseLayer(mNativeClass);
     }
 
     private void onZoomAnimationStart() {
@@ -5574,9 +5579,76 @@
             // However, do not update the base layer as that hasn't changed
             setNewPicture(mLoadedPicture, false);
         }
+        if (mIsEditingText) {
+            scrollEditIntoView();
+        }
         relocateAutoCompletePopup();
     }
 
+    /**
+     * Scrolls the edit field into view using the minimum scrolling necessary.
+     * If the edit field is too large to fit in the visible window, the caret
+     * dimensions are used so that at least the caret is visible.
+     * A buffer of EDIT_RECT_BUFFER in view pixels is used to offset the
+     * edit rectangle to ensure a margin with the edge of the screen.
+     */
+    private void scrollEditIntoView() {
+        Rect visibleRect = new Rect(viewToContentX(getScrollX()),
+                viewToContentY(getScrollY()),
+                viewToContentX(getScrollX() + getWidth()),
+                viewToContentY(getScrollY() + getViewHeightWithTitle()));
+        if (visibleRect.contains(mEditTextContentBounds)) {
+            return; // no need to scroll
+        }
+        syncSelectionCursors();
+        final int buffer = Math.max(1, viewToContentDimension(EDIT_RECT_BUFFER));
+        Rect showRect = new Rect(
+                Math.max(0, mEditTextContentBounds.left - buffer),
+                Math.max(0, mEditTextContentBounds.top - buffer),
+                mEditTextContentBounds.right + buffer,
+                mEditTextContentBounds.bottom + buffer);
+        Point caretTop = calculateCaretTop();
+        if (visibleRect.width() < mEditTextContentBounds.width()) {
+            // The whole edit won't fit in the width, so use the caret rect
+            if (mSelectCursorBase.x < caretTop.x) {
+                showRect.left = Math.max(0, mSelectCursorBase.x - buffer);
+                showRect.right = caretTop.x + buffer;
+            } else {
+                showRect.left = Math.max(0, caretTop.x - buffer);
+                showRect.right = mSelectCursorBase.x + buffer;
+            }
+        }
+        if (visibleRect.height() < mEditTextContentBounds.height()) {
+            // The whole edit won't fit in the height, so use the caret rect
+            if (mSelectCursorBase.y > caretTop.y) {
+                showRect.top = Math.max(0, caretTop.y - buffer);
+                showRect.bottom = mSelectCursorBase.y + buffer;
+            } else {
+                showRect.top = Math.max(0, mSelectCursorBase.y - buffer);
+                showRect.bottom = caretTop.y + buffer;
+            }
+        }
+
+        if (visibleRect.contains(showRect)) {
+            return; // no need to scroll
+        }
+
+        int scrollX = visibleRect.left;
+        if (visibleRect.left > showRect.left) {
+            scrollX = showRect.left;
+        } else if (visibleRect.right < showRect.right) {
+            scrollX = Math.max(0, showRect.right - visibleRect.width());
+        }
+        int scrollY = visibleRect.top;
+        if (visibleRect.top > showRect.top) {
+            scrollY = showRect.top;
+        } else if (visibleRect.bottom < showRect.bottom) {
+            scrollY = Math.max(0, showRect.bottom - visibleRect.height());
+        }
+
+        contentScrollTo(scrollX, scrollY, false);
+    }
+
     @Override
     public void onScrollChanged(int l, int t, int oldl, int oldt) {
         if (!mInOverScrollMode) {
@@ -8586,7 +8658,7 @@
     private native void     nativeSetHeightCanMeasure(boolean measure);
     private native boolean  nativeSetBaseLayer(int nativeInstance,
             int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout);
-    private native int      nativeGetBaseLayer();
+    private native int      nativeGetBaseLayer(int nativeInstance);
     private native void     nativeCopyBaseContentToPicture(Picture pict);
     private native boolean  nativeHasContent();
     private native void     nativeStopGL();
@@ -8614,7 +8686,7 @@
      */
     private native boolean  nativeScrollLayer(int nativeInstance, int layer, int newX, int newY);
     private native void     nativeSetIsScrolling(boolean isScrolling);
-    private native int      nativeGetBackgroundColor();
+    private native int      nativeGetBackgroundColor(int nativeInstance);
     native boolean  nativeSetProperty(String key, String value);
     native String   nativeGetProperty(String key);
     /**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 661bbf8..4adfd6a 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2176,11 +2176,12 @@
 
     DrawData mLastDrawData = null;
 
-    private Boolean m_skipDrawFlag = false;
+    private Object m_skipDrawFlagLock = new Object();
+    private boolean m_skipDrawFlag = false;
     private boolean m_drawWasSkipped = false;
 
     void pauseWebKitDraw() {
-        synchronized (m_skipDrawFlag) {
+        synchronized (m_skipDrawFlagLock) {
             if (!m_skipDrawFlag) {
                 m_skipDrawFlag = true;
             }
@@ -2188,7 +2189,7 @@
     }
 
     void resumeWebKitDraw() {
-        synchronized (m_skipDrawFlag) {
+        synchronized (m_skipDrawFlagLock) {
             if (m_skipDrawFlag && m_drawWasSkipped) {
                 // a draw was dropped, send a retry
                 m_drawWasSkipped = false;
@@ -2199,7 +2200,7 @@
     }
 
     private void webkitDraw() {
-        synchronized (m_skipDrawFlag) {
+        synchronized (m_skipDrawFlagLock) {
             if (m_skipDrawFlag) {
                 m_drawWasSkipped = true;
                 return;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a3b613b..c4e1bf5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -25,6 +25,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.Parcel;
@@ -57,6 +58,7 @@
 import android.view.ViewParent;
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
@@ -648,6 +650,11 @@
     private int mGlowPaddingLeft;
     private int mGlowPaddingRight;
 
+    /**
+     * Used for interacting with list items from an accessibility service.
+     */
+    private ListItemAccessibilityDelegate mAccessibilityDelegate;
+
     private int mLastAccessibilityScrollEventFromIndex;
     private int mLastAccessibilityScrollEventToIndex;
 
@@ -1348,6 +1355,33 @@
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(AbsListView.class.getName());
+        if (getFirstVisiblePosition() > 0) {
+            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+        }
+        if (getLastVisiblePosition() < getCount() - 1) {
+            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+                if (getLastVisiblePosition() < getCount() - 1) {
+                    final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom;
+                    smoothScrollBy(viewportHeight, PositionScroller.SCROLL_DURATION);
+                    return true;
+                }
+            } return false;
+            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+                if (mFirstPosition > 0) {
+                    final int viewportHeight = getHeight() - mListPadding.top - mListPadding.bottom;
+                    smoothScrollBy(-viewportHeight, PositionScroller.SCROLL_DURATION);
+                    return true;
+                }
+            } return false;
+        }
+        return super.performAccessibilityAction(action, arguments);
     }
 
     /**
@@ -2121,9 +2155,77 @@
             child.setLayoutParams(lp);
         }
 
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            if (mAccessibilityDelegate == null) {
+                mAccessibilityDelegate = new ListItemAccessibilityDelegate();
+            }
+            child.setAccessibilityDelegate(mAccessibilityDelegate);
+        }
+
         return child;
     }
 
+    class ListItemAccessibilityDelegate extends AccessibilityDelegate {
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(host, info);
+
+            final int position = getPositionForView(host);
+
+            if (position == INVALID_POSITION) {
+                return;
+            }
+
+            if (isClickable()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+                info.setClickable(true);
+            }
+
+            if (isLongClickable()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
+                info.setLongClickable(true);
+            }
+
+            info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
+
+            if (position == getSelectedItemPosition()) {
+                info.setSelected(true);
+            }
+        }
+
+        @Override
+        public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
+            final int position = getPositionForView(host);
+
+            if (position == INVALID_POSITION) {
+                return false;
+            }
+
+            final long id = getItemIdAtPosition(position);
+
+            switch (action) {
+                case AccessibilityNodeInfo.ACTION_SELECT:
+                    setSelection(position);
+                    return true;
+                case AccessibilityNodeInfo.ACTION_CLICK:
+                    if (!super.performAccessibilityAction(host, action, arguments)) {
+                        return performItemClick(host, position, id);
+                    }
+                    return true;
+                case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+                    if (!super.performAccessibilityAction(host, action, arguments)) {
+                        return performLongPress(host, position, id);
+                    }
+                    return true;
+                case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+                    smoothScrollToPosition(position);
+                    break;
+            }
+
+            return super.performAccessibilityAction(host, action, arguments);
+        }
+    }
+
     void positionSelector(int position, View sel) {
         if (position != INVALID_POSITION) {
             mSelectorPosition = position;
@@ -4009,17 +4111,19 @@
         void start(final int position) {
             stop();
 
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                post(new Runnable() {
+                    @Override public void run() {
+                        start(position);
+                    }
+                });
+                return;
+            }
+
             final int childCount = getChildCount();
             if (childCount == 0) {
                 // Can't scroll without children.
-                if (mDataChanged) {
-                    // But we might have something in a minute.
-                    post(new Runnable() {
-                        @Override public void run() {
-                            start(position);
-                        }
-                    });
-                }
                 return;
             }
 
@@ -4058,17 +4162,19 @@
                 return;
             }
 
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                post(new Runnable() {
+                    @Override public void run() {
+                        start(position, boundPosition);
+                    }
+                });
+                return;
+            }
+
             final int childCount = getChildCount();
             if (childCount == 0) {
                 // Can't scroll without children.
-                if (mDataChanged) {
-                    // But we might have something in a minute.
-                    post(new Runnable() {
-                        @Override public void run() {
-                            start(position, boundPosition);
-                        }
-                    });
-                }
                 return;
             }
 
@@ -4129,9 +4235,26 @@
             startWithOffset(position, offset, SCROLL_DURATION);
         }
 
-        void startWithOffset(int position, int offset, int duration) {
+        void startWithOffset(final int position, int offset, final int duration) {
             stop();
 
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                final int postOffset = offset;
+                post(new Runnable() {
+                    @Override public void run() {
+                        startWithOffset(position, postOffset, duration);
+                    }
+                });
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
             offset += getPaddingTop();
 
             mTargetPos = position;
@@ -4141,7 +4264,6 @@
             mMode = MOVE_OFFSET;
 
             final int firstPos = mFirstPosition;
-            final int childCount = getChildCount();
             final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
@@ -4514,7 +4636,7 @@
 
         if (distance == 0 || mItemCount == 0 || childCount == 0 ||
                 (firstPos == 0 && getChildAt(0).getTop() == topLimit && distance < 0) ||
-                (lastPos == mItemCount - 1 &&
+                (lastPos == mItemCount &&
                         getChildAt(childCount - 1).getBottom() == bottomLimit && distance > 0)) {
             mFlingRunnable.endFling();
             if (mPositionScroller != null) {
@@ -5651,6 +5773,7 @@
             // Don't reclaim header or footer views, or views that should be ignored
             if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
                 views.add(child);
+                child.setAccessibilityDelegate(null);
                 if (listener != null) {
                     // Pretend they went through the scrap heap
                     listener.onMovedToScrapHeap(child);
@@ -6206,6 +6329,7 @@
                 mScrapViews[viewType].add(scrap);
             }
 
+            scrap.setAccessibilityDelegate(null);
             if (mRecyclerListener != null) {
                 mRecyclerListener.onMovedToScrapHeap(scrap);
             }
@@ -6267,6 +6391,7 @@
                     lp.scrappedFromPosition = mFirstActivePosition + i;
                     scrapViews.add(victim);
 
+                    victim.setAccessibilityDelegate(null);
                     if (hasListener) {
                         mRecyclerListener.onMovedToScrapHeap(victim);
                     }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 1986450..ffabd1d9 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -20,6 +20,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.util.AttributeSet;
 import android.view.FocusFinder;
 import android.view.InputDevice;
@@ -737,10 +738,42 @@
     }
 
     @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+                final int viewportWidth = getWidth() - mPaddingLeft - mPaddingRight;
+                final int targetScrollX = Math.min(mScrollX + viewportWidth, getScrollRange());
+                if (targetScrollX != mScrollX) {
+                    smoothScrollTo(targetScrollX, 0);
+                    return true;
+                }
+            } return false;
+            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+                final int viewportWidth = getWidth() - mPaddingLeft - mPaddingRight;
+                final int targetScrollX = Math.max(0, mScrollX - viewportWidth);
+                if (targetScrollX != mScrollX) {
+                    smoothScrollTo(targetScrollX, 0);
+                    return true;
+                }
+            } return false;
+        }
+        return super.performAccessibilityAction(action, arguments);
+    }
+
+    @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(HorizontalScrollView.class.getName());
-        info.setScrollable(getScrollRange() > 0);
+        final int scrollRange = getScrollRange();
+        if (scrollRange > 0) {
+            info.setScrollable(true);
+            if (mScrollX > 0) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+            }
+            if (mScrollX < scrollRange) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+            }
+        }
     }
 
     @Override
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 11d1ed0..6ff924b 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -133,16 +133,6 @@
     private static final int UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE = 48;
 
     /**
-     * The default unscaled minimal distance for a swipe to be considered a fling.
-     */
-    private static final int UNSCALED_DEFAULT_MIN_FLING_DISTANCE = 150;
-
-    /**
-     * Coefficient for adjusting touch scroll distance.
-     */
-    private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.0f;
-
-    /**
      * The resource id for the default layout.
      */
     private static final int DEFAULT_LAYOUT_RESOURCE_ID = R.layout.number_picker;
@@ -233,11 +223,6 @@
     private final int mTextSize;
 
     /**
-     * The minimal distance for a swipe to be considered a fling.
-     */
-    private final int mMinFlingDistance;
-
-    /**
      * The height of the gap between text elements if the selector wheel.
      */
     private int mSelectorTextGapHeight;
@@ -298,6 +283,11 @@
     private final Paint mSelectorWheelPaint;
 
     /**
+     * The {@link Drawable} for pressed virtual (increment/decrement) buttons.
+     */
+    private final Drawable mVirtualButtonPressedDrawable;
+
+    /**
      * The height of a selector element (text + gap).
      */
     private int mSelectorElementHeight;
@@ -435,11 +425,26 @@
     private int mLastHoveredChildVirtualViewId;
 
     /**
+     * Whether the increment virtual button is pressed.
+     */
+    private boolean mIncrementVirtualButtonPressed;
+
+    /**
+     * Whether the decrement virtual button is pressed.
+     */
+    private boolean mDecrementVirtualButtonPressed;
+
+    /**
      * Provider to report to clients the semantic structure of this widget.
      */
     private AccessibilityNodeProviderImpl mAccessibilityNodeProvider;
 
     /**
+     * Helper class for managing pressed state of the virtual buttons.
+     */
+    private final PressedStateHelper mPressedStateHelper;
+
+    /**
      * Interface to listen for changes of the current value.
      */
     public interface OnValueChangeListener {
@@ -553,12 +558,6 @@
         mSelectionDividersDistance = attributesArray.getDimensionPixelSize(
                 R.styleable.NumberPicker_selectionDividersDistance, defSelectionDividerDistance);
 
-        final int defMinFlingDistance = (int) TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_MIN_FLING_DISTANCE,
-                getResources().getDisplayMetrics());
-        mMinFlingDistance = attributesArray.getDimensionPixelSize(
-                R.styleable.NumberPicker_minFlingDistance, defMinFlingDistance);
-
         mMinHeight = attributesArray.getDimensionPixelSize(
                 R.styleable.NumberPicker_internalMinHeight, SIZE_UNSPECIFIED);
 
@@ -581,8 +580,13 @@
 
         mComputeMaxWidth = (mMaxWidth == SIZE_UNSPECIFIED);
 
+        mVirtualButtonPressedDrawable = attributesArray.getDrawable(
+                R.styleable.NumberPicker_virtualButtonPressedDrawable);
+
         attributesArray.recycle();
 
+        mPressedStateHelper = new PressedStateHelper();
+
         // By default Linearlayout that we extend is not drawn. This is
         // its draw() method is not called but dispatchDraw() is called
         // directly (see ViewGroup.drawChild()). However, this class uses
@@ -776,7 +780,19 @@
                 mLastDownEventTime = event.getEventTime();
                 mIngonreMoveEvents = false;
                 mShowSoftInputOnTap = false;
-                // Make sure we wupport flinging inside scrollables.
+                // Handle pressed state before any state change.
+                if (mLastDownEventY < mTopSelectionDividerTop) {
+                    if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
+                        mPressedStateHelper.buttonPressDelayed(
+                                PressedStateHelper.BUTTON_DECREMENT);
+                    }
+                } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
+                    if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
+                        mPressedStateHelper.buttonPressDelayed(
+                                PressedStateHelper.BUTTON_INCREMENT);
+                    }
+                }
+                // Make sure we support flinging inside scrollables.
                 getParent().requestDisallowInterceptTouchEvent(true);
                 if (!mFlingScroller.isFinished()) {
                     mFlingScroller.forceFinished(true);
@@ -826,8 +842,7 @@
                         onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     }
                 } else {
-                    int deltaMoveY = (int) ((currentMoveY - mLastDownOrMoveEventY)
-                            / TOUCH_SCROLL_DECELERATION_COEFFICIENT);
+                    int deltaMoveY = (int) ((currentMoveY - mLastDownOrMoveEventY));
                     scrollBy(0, deltaMoveY);
                     invalidate();
                 }
@@ -836,23 +851,12 @@
             case MotionEvent.ACTION_UP: {
                 removeBeginSoftInputCommand();
                 removeChangeCurrentByOneFromLongPress();
+                mPressedStateHelper.cancel();
                 VelocityTracker velocityTracker = mVelocityTracker;
                 velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
                 int initialVelocity = (int) velocityTracker.getYVelocity();
                 if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
-                    int deltaMove = (int) (event.getY() - mLastDownEventY);
-                    int absDeltaMoveY = Math.abs(deltaMove);
-                    if (absDeltaMoveY > mMinFlingDistance) {
-                        fling(initialVelocity);
-                    } else {
-                        final int normalizedDeltaMove =
-                            (int) (absDeltaMoveY / TOUCH_SCROLL_DECELERATION_COEFFICIENT);
-                        if (normalizedDeltaMove < mSelectorElementHeight) {
-                            snapToNextValue(deltaMove < 0);
-                        } else {
-                            snapToClosestValue();
-                        }
-                    }
+                    fling(initialVelocity);
                     onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
                 } else {
                     int eventY = (int) event.getY();
@@ -867,8 +871,12 @@
                                     - SELECTOR_MIDDLE_ITEM_INDEX;
                             if (selectorIndexOffset > 0) {
                                 changeValueByOne(true);
+                                mPressedStateHelper.buttonTapped(
+                                        PressedStateHelper.BUTTON_INCREMENT);
                             } else if (selectorIndexOffset < 0) {
                                 changeValueByOne(false);
+                                mPressedStateHelper.buttonTapped(
+                                        PressedStateHelper.BUTTON_DECREMENT);
                             }
                         }
                     } else {
@@ -1356,6 +1364,22 @@
         float x = (mRight - mLeft) / 2;
         float y = mCurrentScrollOffset;
 
+        // draw the virtual buttons pressed state if needed
+        if (mVirtualButtonPressedDrawable != null
+                && mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
+            if (mDecrementVirtualButtonPressed) {
+                mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET);
+                mVirtualButtonPressedDrawable.setBounds(0, 0, mRight, mTopSelectionDividerTop);
+                mVirtualButtonPressedDrawable.draw(canvas);
+            }
+            if (mIncrementVirtualButtonPressed) {
+                mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET);
+                mVirtualButtonPressedDrawable.setBounds(0, mBottomSelectionDividerBottom, mRight,
+                        mBottom);
+                mVirtualButtonPressedDrawable.draw(canvas);
+            }
+        }
+
         // draw the selector wheel
         int[] selectorIndices = mSelectorIndices;
         for (int i = 0; i < selectorIndices.length; i++) {
@@ -1465,15 +1489,15 @@
      */
     private void initializeSelectorWheelIndices() {
         mSelectorIndexToStringCache.clear();
-        int[] selectorIdices = mSelectorIndices;
+        int[] selectorIndices = mSelectorIndices;
         int current = getValue();
         for (int i = 0; i < mSelectorIndices.length; i++) {
             int selectorIndex = current + (i - SELECTOR_MIDDLE_ITEM_INDEX);
             if (mWrapSelectorWheel) {
                 selectorIndex = getWrappedSelectorIndex(selectorIndex);
             }
-            mSelectorIndices[i] = selectorIndex;
-            ensureCachedScrollSelectorValue(mSelectorIndices[i]);
+            selectorIndices[i] = selectorIndex;
+            ensureCachedScrollSelectorValue(selectorIndices[i]);
         }
     }
 
@@ -1775,6 +1799,7 @@
         if (mBeginSoftInputOnLongPressCommand != null) {
             removeCallbacks(mBeginSoftInputOnLongPressCommand);
         }
+        mPressedStateHelper.cancel();
     }
 
     /**
@@ -1910,39 +1935,80 @@
         return false;
     }
 
-    private void snapToNextValue(boolean increment) {
-        int deltaY = mCurrentScrollOffset - mInitialScrollOffset;
-        int amountToScroll = 0;
-        if (deltaY != 0) {
-            mPreviousScrollerY = 0;
-            if (deltaY > 0) {
-                if (increment) {
-                    amountToScroll = - deltaY;
-                } else {
-                    amountToScroll = mSelectorElementHeight - deltaY;
-                }
-            } else {
-                if (increment) {
-                    amountToScroll = - mSelectorElementHeight - deltaY;
-                } else {
-                    amountToScroll = - deltaY;
-                }
-            }
-            mFlingScroller.startScroll(0, 0, 0, amountToScroll, SNAP_SCROLL_DURATION);
-            invalidate();
-        }
-    }
+    class PressedStateHelper implements Runnable {
+        public static final int BUTTON_INCREMENT = 1;
+        public static final int BUTTON_DECREMENT = 2;
 
-    private void snapToClosestValue() {
-        // adjust to the closest value
-        int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
-        if (deltaY != 0) {
-            mPreviousScrollerY = 0;
-            if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
-                deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
+        private final int MODE_PRESS = 1;
+        private final int MODE_TAPPED = 2;
+
+        private int mManagedButton;
+        private int mMode;
+
+        public void cancel() {
+            mMode = 0;
+            mManagedButton = 0;
+            NumberPicker.this.removeCallbacks(this);
+            if (mIncrementVirtualButtonPressed) {
+                mIncrementVirtualButtonPressed = false;
+                invalidate(0, mBottomSelectionDividerBottom, mRight, mBottom);
             }
-            mFlingScroller.startScroll(0, 0, 0, deltaY, SNAP_SCROLL_DURATION);
-            invalidate();
+            mDecrementVirtualButtonPressed = false;
+            if (mDecrementVirtualButtonPressed) {
+                invalidate(0, 0, mRight, mTopSelectionDividerTop);
+            }
+        }
+
+        public void buttonPressDelayed(int button) {
+            cancel();
+            mMode = MODE_PRESS;
+            mManagedButton = button;
+            NumberPicker.this.postDelayed(this, ViewConfiguration.getTapTimeout());
+        }
+
+        public void buttonTapped(int button) {
+            cancel();
+            mMode = MODE_TAPPED;
+            mManagedButton = button;
+            NumberPicker.this.post(this);
+        }
+
+        @Override
+        public void run() {
+            switch (mMode) {
+                case MODE_PRESS: {
+                    switch (mManagedButton) {
+                        case BUTTON_INCREMENT: {
+                            mIncrementVirtualButtonPressed = true;
+                            invalidate(0, mBottomSelectionDividerBottom, mRight, mBottom);
+                        } break;
+                        case BUTTON_DECREMENT: {
+                            mDecrementVirtualButtonPressed = true;
+                            invalidate(0, 0, mRight, mTopSelectionDividerTop);
+                        }
+                    }
+                } break;
+                case MODE_TAPPED: {
+                    switch (mManagedButton) {
+                        case BUTTON_INCREMENT: {
+                            if (!mIncrementVirtualButtonPressed) {
+                                NumberPicker.this.postDelayed(this,
+                                        ViewConfiguration.getPressedStateDuration());
+                            }
+                            mIncrementVirtualButtonPressed ^= true;
+                            invalidate(0, mBottomSelectionDividerBottom, mRight, mBottom);
+                        } break;
+                        case BUTTON_DECREMENT: {
+                            if (!mDecrementVirtualButtonPressed) {
+                                NumberPicker.this.postDelayed(this,
+                                        ViewConfiguration.getPressedStateDuration());
+                            }
+                            mDecrementVirtualButtonPressed ^= true;
+                            invalidate(0, 0, mRight, mTopSelectionDividerTop);
+                        }
+                    }
+                } break;
+            }
         }
     }
 
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index f912c66..b398ce4 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -22,6 +22,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.StrictMode;
 import android.util.AttributeSet;
 import android.view.FocusFinder;
@@ -740,10 +741,42 @@
     }
 
     @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+                final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop;
+                final int targetScrollY = Math.min(mScrollY + viewportHeight, getScrollRange());
+                if (targetScrollY != mScrollY) {
+                    smoothScrollTo(0, targetScrollY);
+                    return true;
+                }
+            } return false;
+            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+                final int viewportHeight = getHeight() - mPaddingBottom - mPaddingTop;
+                final int targetScrollY = Math.max(mScrollY - viewportHeight, 0);
+                if (targetScrollY != mScrollY) {
+                    smoothScrollTo(0, targetScrollY);
+                    return true;
+                }
+            } return false;
+        }
+        return super.performAccessibilityAction(action, arguments);
+    }
+
+    @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(ScrollView.class.getName());
-        info.setScrollable(getScrollRange() > 0);
+        final int scrollRange = getScrollRange();
+        if (scrollRange > 0) {
+            info.setScrollable(true);
+            if (mScrollY > 0) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+            }
+            if (mScrollY < scrollRange) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+            }
+        }
     }
 
     @Override
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index e1103dd..ebf8a4a 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -427,12 +427,6 @@
         if (spellCheckSpanStart < 0 || spellCheckSpanEnd <= spellCheckSpanStart)
             return; // span was removed in the meantime
 
-        final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
-        if (suggestionsCount <= 0) {
-            // A negative suggestion count is possible
-            return;
-        }
-
         final int start;
         final int end;
         if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
@@ -443,9 +437,15 @@
             end = spellCheckSpanEnd;
         }
 
-        String[] suggestions = new String[suggestionsCount];
-        for (int i = 0; i < suggestionsCount; i++) {
-            suggestions[i] = suggestionsInfo.getSuggestionAt(i);
+        final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
+        String[] suggestions;
+        if (suggestionsCount > 0) {
+            suggestions = new String[suggestionsCount];
+            for (int i = 0; i < suggestionsCount; i++) {
+                suggestions[i] = suggestionsInfo.getSuggestionAt(i);
+            }
+        } else {
+            suggestions = ArrayUtils.emptyArray(String.class);
         }
 
         SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
@@ -453,7 +453,7 @@
         // TODO: Remove mIsSentenceSpellCheckSupported by extracting an interface
         // to share the logic of word level spell checker and sentence level spell checker
         if (mIsSentenceSpellCheckSupported) {
-            final long key = TextUtils.packRangeInLong(start, end);
+            final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
             final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
             if (tempSuggestionSpan != null) {
                 if (DBG) {
@@ -611,6 +611,9 @@
                     if (spellCheckEnd < start) {
                         break;
                     }
+                    if (spellCheckEnd <= spellCheckStart) {
+                        break;
+                    }
                     if (createSpellCheckSpan) {
                         addSpellCheckSpan(editable, spellCheckStart, spellCheckEnd);
                     }
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 37567fd..89f2187 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -29,64 +29,43 @@
 import android.widget.Toast;
 
 public class PlatLogoActivity extends Activity {
-    Vibrator mZzz;
     Toast mToast;
     ImageView mContent;
     int mCount;
     final Handler mHandler = new Handler();
 
-    Runnable mSuperLongPress = new Runnable() {
-        public void run() {
-            mCount++;
-            mZzz.vibrate(50 * mCount);
-            final float scale = 1f + 0.25f * mCount * mCount;
-            mContent.setScaleX(scale);
-            mContent.setScaleY(scale);
-
-            if (mCount <= 3) {
-                mHandler.postDelayed(mSuperLongPress, ViewConfiguration.getLongPressTimeout());
-            } else {
-                try {
-                    startActivity(new Intent(Intent.ACTION_MAIN)
-                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                            | Intent.FLAG_ACTIVITY_CLEAR_TASK
-                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
-                        .setClassName("com.android.systemui","com.android.systemui.Nyandroid"));
-                } catch (ActivityNotFoundException ex) {
-                    android.util.Log.e("PlatLogoActivity", "Couldn't find platlogo screensaver.");
-                }
-                finish();
-            }
-        }
-    };
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mZzz = (Vibrator)getSystemService(VIBRATOR_SERVICE);
-        mToast = Toast.makeText(this, "Android 4.0: Ice Cream Sandwich", Toast.LENGTH_SHORT);
+        mToast = Toast.makeText(this, "Android X.X: Jelly Bean", Toast.LENGTH_SHORT);
 
         mContent = new ImageView(this);
         mContent.setImageResource(com.android.internal.R.drawable.platlogo);
         mContent.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
-        mContent.setOnTouchListener(new View.OnTouchListener() {
+        mContent.setOnClickListener(new View.OnClickListener() {
             @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                final int action = event.getAction();
-                if (action == MotionEvent.ACTION_DOWN) {
-                    mContent.setPressed(true);
-                    mHandler.removeCallbacks(mSuperLongPress);
-                    mCount = 0;
-                    mHandler.postDelayed(mSuperLongPress, 2*ViewConfiguration.getLongPressTimeout());
-                } else if (action == MotionEvent.ACTION_UP) {
-                    if (mContent.isPressed()) {
-                        mContent.setPressed(false);
-                        mHandler.removeCallbacks(mSuperLongPress);
-                        mToast.show();
-                    }
+            public void onClick(View v) {
+                mToast.show();
+                mContent.setImageResource(com.android.internal.R.drawable.platlogo_alt);
+            }
+        });
+
+        mContent.setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                try {
+                    startActivity(new Intent(Intent.ACTION_MAIN)
+                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                            | Intent.FLAG_ACTIVITY_CLEAR_TASK
+                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                        .addCategory("com.android.internal.category.PLATLOGO"));
+                        //.setClassName("com.android.systemui","com.android.systemui.BeanBag"));
+                } catch (ActivityNotFoundException ex) {
+                    android.util.Log.e("PlatLogoActivity", "Couldn't find a bag of beans.");
                 }
+                finish();
                 return true;
             }
         });
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 48ed561..246b0c9 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -57,25 +57,25 @@
     public static final int APP_INSTALL_INTERNAL = 1;
     public static final int APP_INSTALL_EXTERNAL = 2;
 
-    public static IMountService getMountService() {
+    public static IMountService getMountService() throws RemoteException {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
             return IMountService.Stub.asInterface(service);
         } else {
             Log.e(TAG, "Can't get mount service");
+            throw new RemoteException("Could not contact mount service");
         }
-        return null;
     }
 
     public static String createSdDir(int sizeMb, String cid, String sdEncKey, int uid,
             boolean isExternal) {
         // Create mount point via MountService
-        IMountService mountService = getMountService();
-
-        if (localLOGV)
-            Log.i(TAG, "Size of container " + sizeMb + " MB");
-
         try {
+            IMountService mountService = getMountService();
+
+            if (localLOGV)
+                Log.i(TAG, "Size of container " + sizeMb + " MB");
+
             int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
                     isExternal);
             if (rc != StorageResultCode.OperationSucceeded) {
diff --git a/core/java/com/android/internal/policy/IFaceLockCallback.aidl b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
index a7b01b2..eb902fd 100644
--- a/core/java/com/android/internal/policy/IFaceLockCallback.aidl
+++ b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
@@ -23,5 +23,5 @@
     void cancel();
     void reportFailedAttempt();
     void exposeFallback();
-    void pokeWakelock();
+    void pokeWakelock(int millis);
 }
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 6cfb97d..26235f1 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -19,8 +19,6 @@
 import android.os.FileUtils;
 import android.util.Slog;
 
-import com.android.internal.util.FileRotator.Rewriter;
-
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -29,8 +27,11 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
 import libcore.io.IoUtils;
+import libcore.io.Streams;
 
 /**
  * Utility that rotates files over time, similar to {@code logrotate}. There is
@@ -137,10 +138,38 @@
     public void deleteAll() {
         final FileInfo info = new FileInfo(mPrefix);
         for (String name : mBasePath.list()) {
-            if (!info.parse(name)) continue;
+            if (info.parse(name)) {
+                // delete each file that matches parser
+                new File(mBasePath, name).delete();
+            }
+        }
+    }
 
-            // delete each file that matches parser
-            new File(mBasePath, name).delete();
+    /**
+     * Dump all files managed by this rotator for debugging purposes.
+     */
+    public void dumpAll(OutputStream os) throws IOException {
+        final ZipOutputStream zos = new ZipOutputStream(os);
+        try {
+            final FileInfo info = new FileInfo(mPrefix);
+            for (String name : mBasePath.list()) {
+                if (info.parse(name)) {
+                    final ZipEntry entry = new ZipEntry(name);
+                    zos.putNextEntry(entry);
+
+                    final File file = new File(mBasePath, name);
+                    final FileInputStream is = new FileInputStream(file);
+                    try {
+                        Streams.copy(is, zos);
+                    } finally {
+                        IoUtils.closeQuietly(is);
+                    }
+
+                    zos.closeEntry();
+                }
+            }
+        } finally {
+            IoUtils.closeQuietly(zos);
         }
     }
 
@@ -159,22 +188,22 @@
     public void combineActive(final Reader reader, final Writer writer, long currentTimeMillis)
             throws IOException {
         rewriteActive(new Rewriter() {
-            /** {@inheritDoc} */
+            @Override
             public void reset() {
                 // ignored
             }
 
-            /** {@inheritDoc} */
+            @Override
             public void read(InputStream in) throws IOException {
                 reader.read(in);
             }
 
-            /** {@inheritDoc} */
+            @Override
             public boolean shouldWrite() {
                 return true;
             }
 
-            /** {@inheritDoc} */
+            @Override
             public void write(OutputStream out) throws IOException {
                 writer.write(out);
             }
@@ -224,11 +253,11 @@
 
                 // write success, delete backup
                 backupFile.delete();
-            } catch (IOException e) {
+            } catch (Throwable t) {
                 // write failed, delete file and restore backup
                 file.delete();
                 backupFile.renameTo(file);
-                throw e;
+                throw rethrowAsIoException(t);
             }
 
         } else {
@@ -241,11 +270,11 @@
 
                 // write success, delete empty backup
                 backupFile.delete();
-            } catch (IOException e) {
+            } catch (Throwable t) {
                 // write failed, delete file and empty backup
                 file.delete();
                 backupFile.delete();
-                throw e;
+                throw rethrowAsIoException(t);
             }
         }
     }
@@ -353,6 +382,14 @@
         }
     }
 
+    private static IOException rethrowAsIoException(Throwable t) throws IOException {
+        if (t instanceof IOException) {
+            throw (IOException) t;
+        } else {
+            throw new IOException(t.getMessage(), t);
+        }
+    }
+
     /**
      * Details for a rotated file, either parsed from an existing filename, or
      * ready to be built into a new filename.
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index a331bec..b3e2d27 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -220,7 +220,6 @@
         private int mExpandedIndex = -1;
 
         public MenuAdapter() {
-            registerDataSetObserver(new ExpandedIndexObserver());
             findExpandedIndex();
         }
 
@@ -273,12 +272,11 @@
             }
             mExpandedIndex = -1;
         }
-    }
 
-    private class ExpandedIndexObserver extends DataSetObserver {
         @Override
-        public void onChanged() {
-            mAdapter.findExpandedIndex();
+        public void notifyDataSetChanged() {
+            findExpandedIndex();
+            super.notifyDataSetChanged();
         }
     }
 }
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 329b457..cacc86b 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -307,7 +307,6 @@
 
         public MenuAdapter(MenuBuilder menu) {
             mAdapterMenu = menu;
-            registerDataSetObserver(new ExpandedIndexObserver());
             findExpandedIndex();
         }
 
@@ -363,12 +362,11 @@
             }
             mExpandedIndex = -1;
         }
-    }
 
-    private class ExpandedIndexObserver extends DataSetObserver {
         @Override
-        public void onChanged() {
-            mAdapter.findExpandedIndex();
+        public void notifyDataSetChanged() {
+            findExpandedIndex();
+            super.notifyDataSetChanged();
         }
     }
 }
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
index 1a8e80f..ee285aa 100644
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ b/core/java/com/google/android/mms/pdu/PduPersister.java
@@ -1058,9 +1058,10 @@
                 }
             }
         }
-
-        long threadId = Threads.getOrCreateThreadId(mContext, recipients);
-        values.put(Mms.THREAD_ID, threadId);
+        if (!recipients.isEmpty()) {
+            long threadId = Threads.getOrCreateThreadId(mContext, recipients);
+            values.put(Mms.THREAD_ID, threadId);
+        }
 
         SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
     }
@@ -1299,7 +1300,6 @@
         }
 
         HashSet<String> recipients = new HashSet<String>();
-        long threadId = DUMMY_THREAD_ID;
         int msgType = pdu.getMessageType();
         // Here we only allocate thread ID for M-Notification.ind,
         // M-Retrieve.conf and M-Send.req.
@@ -1326,9 +1326,11 @@
                     }
                 }
             }
-            threadId = Threads.getOrCreateThreadId(mContext, recipients);
+            if (!recipients.isEmpty()) {
+                long threadId = Threads.getOrCreateThreadId(mContext, recipients);
+                values.put(Mms.THREAD_ID, threadId);
+            }
         }
-        values.put(Mms.THREAD_ID, threadId);
 
         // Save parts first to avoid inconsistent message is loaded
         // while saving the parts.
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 3a6c5b0..416370e 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -317,8 +317,6 @@
             env->SetObjectField(javaBitmap, gBitmap_layoutBoundsFieldID, layoutBounds);
         }
     }
-    // detach bitmap from its autodeleter, since we want to own it now
-    adb.detach();
 
     if (willScale) {
         // This is weird so let me explain: we could use the scale parameter
@@ -369,6 +367,9 @@
         pr->setImmutable();
     }
 
+    // detach bitmap from its autodeleter, since we want to own it now
+    adb.detach();
+
     if (javaBitmap != NULL) {
         // If a java bitmap was passed in for reuse, pass it back
         return javaBitmap;
diff --git a/core/jni/android_database_SQLiteCommon.cpp b/core/jni/android_database_SQLiteCommon.cpp
index 3484467..06bff19 100644
--- a/core/jni/android_database_SQLiteCommon.cpp
+++ b/core/jni/android_database_SQLiteCommon.cpp
@@ -110,7 +110,7 @@
             exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
             break;
         case SQLITE_INTERRUPT:
-            exceptionClass = "android/content/OperationCanceledException";
+            exceptionClass = "android/os/OperationCanceledException";
             break;
         default:
             exceptionClass = "android/database/sqlite/SQLiteException";
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 66af965..677396d1 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -15,7 +15,11 @@
 ** limitations under the License.
 */
 
+#define LOG_TAG "SysPropJNI"
+
 #include "cutils/properties.h"
+#include "utils/misc.h"
+#include <utils/Log.h>
 #include "jni.h"
 #include "android_runtime/AndroidRuntime.h"
 #include <nativehelper/JNIHelp.h>
@@ -65,6 +69,7 @@
     int len;
     const char* key;
     char buf[PROPERTY_VALUE_MAX];
+    char* end;
     jint result = defJ;
 
     if (keyJ == NULL) {
@@ -76,9 +81,10 @@
 
     len = property_get(key, buf, "");
     if (len > 0) {
-        jint temp;
-        if (sscanf(buf, "%d", &temp) == 1)
-            result = temp;
+        result = strtol(buf, &end, 0);
+        if (end == buf) {
+            result = defJ;
+        }
     }
 
     env->ReleaseStringUTFChars(keyJ, key);
@@ -93,6 +99,7 @@
     int len;
     const char* key;
     char buf[PROPERTY_VALUE_MAX];
+    char* end;
     jlong result = defJ;
 
     if (keyJ == NULL) {
@@ -104,9 +111,10 @@
 
     len = property_get(key, buf, "");
     if (len > 0) {
-        jlong temp;
-        if (sscanf(buf, "%lld", &temp) == 1)
-            result = temp;
+        result = strtoll(buf, &end, 0);
+        if (end == buf) {
+            result = defJ;
+        }
     }
 
     env->ReleaseStringUTFChars(keyJ, key);
@@ -184,6 +192,34 @@
     }
 }
 
+static JavaVM* sVM = NULL;
+static jclass sClazz = NULL;
+static jmethodID sCallChangeCallbacks;
+
+static void do_report_sysprop_change() {
+    //ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz);
+    if (sVM != NULL && sClazz != NULL) {
+        JNIEnv* env;
+        if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
+            //ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
+            env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks);
+        }
+    }
+}
+
+static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
+{
+    // This is called with the Java lock held.
+    if (sVM == NULL) {
+        env->GetJavaVM(&sVM);
+    }
+    if (sClazz == NULL) {
+        sClazz = (jclass) env->NewGlobalRef(clazz);
+        sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
+        add_sysprop_change_callback(do_report_sysprop_change, -10000);
+    }
+}
+
 static JNINativeMethod method_table[] = {
     { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
       (void*) SystemProperties_getS },
@@ -197,6 +233,8 @@
       (void*) SystemProperties_get_boolean },
     { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
       (void*) SystemProperties_set },
+    { "native_add_change_callback", "()V",
+      (void*) SystemProperties_add_change_callback },
 };
 
 int register_android_os_SystemProperties(JNIEnv *env)
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 0f99fb2..04dc49f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -308,6 +308,12 @@
             env->DeleteLocalRef(excep2);
         }
 
+        // Need to always call through the native implementation of
+        // SYSPROPS_TRANSACTION.
+        if (code == SYSPROPS_TRANSACTION) {
+            BBinder::onTransact(code, data, reply, flags);
+        }
+
         //aout << "onTransact to Java code; result=" << res << endl
         //    << "Transact from " << this << " to Java code returning "
         //    << reply << ": " << *reply << endl;
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index d20cc9e..027ed16 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -402,7 +402,7 @@
     return *((const jint*)v1) - *((const jint*)v2);
 }
 
-static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz)
+static jlong getFreeMemoryImpl(const char* const sums[], const int sumsLen[], int num)
 {
     int fd = open("/proc/meminfo", O_RDONLY);
 
@@ -424,11 +424,8 @@
     int numFound = 0;
     jlong mem = 0;
 
-    static const char* const sums[] = { "MemFree:", "Cached:", NULL };
-    static const int sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 };
-
     char* p = buffer;
-    while (*p && numFound < 2) {
+    while (*p && numFound < num) {
         int i = 0;
         while (sums[i]) {
             if (strncmp(p, sums[i], sumsLen[i]) == 0) {
@@ -453,6 +450,20 @@
     return numFound > 0 ? mem : -1;
 }
 
+static jlong android_os_Process_getFreeMemory(JNIEnv* env, jobject clazz)
+{
+    static const char* const sums[] = { "MemFree:", "Cached:", NULL };
+    static const int sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 };
+    return getFreeMemoryImpl(sums, sumsLen, 2);
+}
+
+static jlong android_os_Process_getTotalMemory(JNIEnv* env, jobject clazz)
+{
+    static const char* const sums[] = { "MemTotal:", NULL };
+    static const int sumsLen[] = { strlen("MemTotal:"), 0 };
+    return getFreeMemoryImpl(sums, sumsLen, 1);
+}
+
 void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileStr,
                                       jobjectArray reqFields, jlongArray outFields)
 {
@@ -901,6 +912,7 @@
     {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
     {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},
     {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
+    {"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory},
     {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines},
     {"getPids", "(Ljava/lang/String;[I)[I", (void*)android_os_Process_getPids},
     {"readProcFile", "(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z", (void*)android_os_Process_readProcFile},
diff --git a/core/res/res/drawable-hdpi/notification_bg_low_normal.9.png b/core/res/res/drawable-hdpi/notification_bg_low_normal.9.png
new file mode 100644
index 0000000..af91f5e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/notification_bg_low_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/notification_bg_low_pressed.9.png b/core/res/res/drawable-hdpi/notification_bg_low_pressed.9.png
new file mode 100644
index 0000000..1602ab87
--- /dev/null
+++ b/core/res/res/drawable-hdpi/notification_bg_low_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/notification_bg_normal.9.png b/core/res/res/drawable-hdpi/notification_bg_normal.9.png
new file mode 100644
index 0000000..6ebed8b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/notification_bg_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/notification_bg_normal_pressed.9.png b/core/res/res/drawable-hdpi/notification_bg_normal_pressed.9.png
new file mode 100644
index 0000000..6193822
--- /dev/null
+++ b/core/res/res/drawable-hdpi/notification_bg_normal_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
index e7e1d8d..cfbbd8d 100644
--- a/core/res/res/drawable-hdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-hdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_adb.png b/core/res/res/drawable-ldpi/stat_sys_adb.png
index 86b945b..0171adb 100644
--- a/core/res/res/drawable-ldpi/stat_sys_adb.png
+++ b/core/res/res/drawable-ldpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/notification_bg_low_normal.9.png b/core/res/res/drawable-mdpi/notification_bg_low_normal.9.png
new file mode 100644
index 0000000..62de9d7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/notification_bg_low_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/notification_bg_low_pressed.9.png b/core/res/res/drawable-mdpi/notification_bg_low_pressed.9.png
new file mode 100644
index 0000000..eaabd93
--- /dev/null
+++ b/core/res/res/drawable-mdpi/notification_bg_low_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/notification_bg_normal.9.png b/core/res/res/drawable-mdpi/notification_bg_normal.9.png
new file mode 100644
index 0000000..aa239b3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/notification_bg_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/notification_bg_normal_pressed.9.png b/core/res/res/drawable-mdpi/notification_bg_normal_pressed.9.png
new file mode 100644
index 0000000..62d8622
--- /dev/null
+++ b/core/res/res/drawable-mdpi/notification_bg_normal_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
index 86d113f..4862919 100644
--- a/core/res/res/drawable-mdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-mdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index 8aa3b9e..f46c6c6 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo_alt.png b/core/res/res/drawable-nodpi/platlogo_alt.png
new file mode 100644
index 0000000..63b53b8
--- /dev/null
+++ b/core/res/res/drawable-nodpi/platlogo_alt.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/notification_bg_low_normal.9.png b/core/res/res/drawable-xhdpi/notification_bg_low_normal.9.png
new file mode 100644
index 0000000..8c884de
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/notification_bg_low_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/notification_bg_low_pressed.9.png b/core/res/res/drawable-xhdpi/notification_bg_low_pressed.9.png
new file mode 100644
index 0000000..32e00be
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/notification_bg_low_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/notification_bg_normal.9.png b/core/res/res/drawable-xhdpi/notification_bg_normal.9.png
new file mode 100644
index 0000000..bdf477b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/notification_bg_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/notification_bg_normal_pressed.9.png b/core/res/res/drawable-xhdpi/notification_bg_normal_pressed.9.png
new file mode 100644
index 0000000..5c4da74
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/notification_bg_normal_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb.png b/core/res/res/drawable-xhdpi/stat_sys_adb.png
index 684d57a..576ae24 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_adb.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable/notification_bg.xml b/core/res/res/drawable/notification_bg.xml
index 1bb2172..362a524 100644
--- a/core/res/res/drawable/notification_bg.xml
+++ b/core/res/res/drawable/notification_bg.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
         android:exitFadeDuration="@android:integer/config_mediumAnimTime">
 
-    <item android:state_pressed="true"  android:drawable="@drawable/notification_item_background_color_pressed" />
-    <item android:state_pressed="false" android:drawable="@drawable/notification_item_background_color" />
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_bg_normal_pressed" />
+    <item android:state_pressed="false" android:drawable="@drawable/notification_bg_normal" />
 </selector>
diff --git a/core/res/res/drawable/notification_bg_low.xml b/core/res/res/drawable/notification_bg_low.xml
new file mode 100644
index 0000000..466a885
--- /dev/null
+++ b/core/res/res/drawable/notification_bg_low.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_bg_low_pressed" />
+    <item android:state_pressed="false" android:drawable="@drawable/notification_bg_low_normal" />
+</selector>
diff --git a/core/res/res/layout/date_picker_holo.xml b/core/res/res/layout/date_picker_holo.xml
index 122a61a..8008682 100644
--- a/core/res/res/layout/date_picker_holo.xml
+++ b/core/res/res/layout/date_picker_holo.xml
@@ -41,10 +41,10 @@
             android:id="@+id/month"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="10dip"
-            android:layout_marginBottom="10dip"
-            android:layout_marginLeft="16dip"
-            android:layout_marginRight="16dip"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:layout_marginLeft="8dip"
+            android:layout_marginRight="8dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -54,10 +54,10 @@
             android:id="@+id/day"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="10dip"
-            android:layout_marginBottom="10dip"
-            android:layout_marginLeft="16dip"
-            android:layout_marginRight="16dip"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:layout_marginLeft="8dip"
+            android:layout_marginRight="8dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -67,9 +67,9 @@
             android:id="@+id/year"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="10dip"
-            android:layout_marginBottom="10dip"
-            android:layout_marginLeft="16dip"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:layout_marginLeft="8dip"
             android:layout_marginRight="16dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
diff --git a/core/res/res/layout/notification_action.xml b/core/res/res/layout/notification_action.xml
index 785da7c..36982ca 100644
--- a/core/res/res/layout/notification_action.xml
+++ b/core/res/res/layout/notification_action.xml
@@ -17,7 +17,10 @@
 <Button xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/action0"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    style="@android:style/Widget.Holo.Button.Small"
+    android:layout_height="48dp"
     android:gravity="left|center_vertical"
-    />
\ No newline at end of file
+    android:drawablePadding="8dp"
+    android:paddingLeft="8dp"
+    android:textColor="#ccc"
+    android:textSize="14dp"
+    />
diff --git a/core/res/res/layout/notification_action_tombstone.xml b/core/res/res/layout/notification_action_tombstone.xml
new file mode 100644
index 0000000..e61e15f
--- /dev/null
+++ b/core/res/res/layout/notification_action_tombstone.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/action0"
+    android:layout_width="match_parent"
+    android:layout_height="48dp"
+    android:gravity="left|center_vertical"
+    android:drawablePadding="8dp"
+    android:paddingLeft="8dp"
+    android:textColor="#666"
+    android:textSize="14dp"
+    />
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index 63d20e4..3692a4d 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -26,7 +26,7 @@
     <ImageView android:id="@+id/icon"
         android:layout_width="@dimen/notification_large_icon_width"
         android:layout_height="@dimen/notification_large_icon_height"
-        android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+        android:background="@android:drawable/notification_template_icon_bg"
         android:scaleType="center"
         />
     <LinearLayout
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
index f8b24e2..378161c 100644
--- a/core/res/res/layout/notification_template_big_base.xml
+++ b/core/res/res/layout/notification_template_big_base.xml
@@ -26,7 +26,7 @@
     <ImageView android:id="@+id/icon"
         android:layout_width="@dimen/notification_large_icon_width"
         android:layout_height="@dimen/notification_large_icon_height"
-        android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+        android:background="@android:drawable/notification_template_icon_bg"
         android:scaleType="center"
         />
     <LinearLayout
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
index a225ab1..d0549cf 100644
--- a/core/res/res/layout/notification_template_big_text.xml
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -25,7 +25,7 @@
     <ImageView android:id="@+id/icon"
         android:layout_width="@dimen/notification_large_icon_width"
         android:layout_height="@dimen/notification_large_icon_height"
-        android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+        android:background="@android:drawable/notification_template_icon_bg"
         android:scaleType="center"
         />
     <LinearLayout
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
index 05a3d62..7b63ac5 100644
--- a/core/res/res/layout/notification_template_inbox.xml
+++ b/core/res/res/layout/notification_template_inbox.xml
@@ -15,14 +15,18 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/status_bar_latest_event_content"
+    android:background="@android:drawable/notification_bg"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    internal:layout_minHeight="65dp"
+    internal:layout_maxHeight="unbounded"
     >
     <ImageView android:id="@+id/icon"
         android:layout_width="@dimen/notification_large_icon_width"
         android:layout_height="@dimen/notification_large_icon_height"
-        android:background="@android:drawable/notify_panel_notification_icon_bg_tile"
+        android:background="@android:drawable/notification_template_icon_bg"
         android:scaleType="center"
         />
     <LinearLayout
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
index 24b6194..91e66bc 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -30,10 +30,10 @@
         android:id="@+id/hour"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="10dip"
-        android:layout_marginBottom="10dip"
+        android:layout_marginTop="16dip"
+        android:layout_marginBottom="16dip"
         android:layout_marginLeft="16dip"
-        android:layout_marginRight="14dip"
+        android:layout_marginRight="6dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
         />
@@ -51,10 +51,10 @@
         android:id="@+id/minute"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="10dip"
-        android:layout_marginBottom="10dip"
-        android:layout_marginLeft="14dip"
-        android:layout_marginRight="16dip"
+        android:layout_marginTop="16dip"
+        android:layout_marginBottom="16dip"
+        android:layout_marginLeft="6dip"
+        android:layout_marginRight="8dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
         />
@@ -64,9 +64,9 @@
         android:id="@+id/amPm"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="10dip"
-        android:layout_marginBottom="10dip"
-        android:layout_marginLeft="16dip"
+        android:layout_marginTop="16dip"
+        android:layout_marginBottom="16dip"
+        android:layout_marginLeft="8dip"
         android:layout_marginRight="16dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7fa95c9..ad7a228 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -168,12 +168,9 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Jou boodskappe"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"Lees en skryf jou SMS, e-pos en ander boodskappe."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Jou persoonlike inligting"</string>
-    <!-- no translation found for permgroupdesc_personalInfo (8426453129788861338) -->
-    <skip />
-    <!-- no translation found for permgrouplab_socialInfo (5799096623412043791) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_socialInfo (7129842457611643493) -->
-    <skip />
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Direkte toegang tot inligting oor jou, gestoor in jou kontakkaart."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Jou sosiale inligting"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte toegang tot inligting oor jou kontakte en sosiale verbindings."</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"Jou ligging"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Monitor jou fisiese ligging."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Netwerkkommunikasie"</string>
@@ -186,18 +183,12 @@
     <skip />
     <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
     <skip />
-    <!-- no translation found for permgrouplab_audioSettings (8329261670151871235) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_audioSettings (2641515403347568130) -->
-    <skip />
-    <!-- no translation found for permgrouplab_affectsBattery (6209246653424798033) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_affectsBattery (6441275320638916947) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (5777534316982184416) -->
-    <skip />
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Oudio-instellings"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Verander oudio-instellings."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Affekteer battery"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Gebruik kenmerke wat vinnig die battery opgebruik."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Direkte toegang tot kalender en gebeurtenisse."</string>
     <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
     <skip />
     <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
@@ -206,46 +197,26 @@
     <skip />
     <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
     <skip />
-    <!-- no translation found for permgrouplab_bookmarks (1949519673103968229) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bookmarks (4169771606257963028) -->
-    <skip />
-    <!-- no translation found for permgrouplab_deviceAlarms (6117704629728824101) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_deviceAlarms (4769356362251641175) -->
-    <skip />
-    <!-- no translation found for permgrouplab_voicemail (4162237145027592133) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_voicemail (2498403969862951393) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (7106618286905738408) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (2933667372289567714) -->
-    <skip />
-    <!-- no translation found for permgrouplab_appInfo (8028789762634147725) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_appInfo (3950378538049625907) -->
-    <skip />
-    <!-- no translation found for permgrouplab_wallpaper (3850280158041175998) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_wallpaper (5630417854750540154) -->
-    <skip />
-    <!-- no translation found for permgrouplab_systemClock (406535759236612992) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_systemClock (3944359833624094992) -->
-    <skip />
-    <!-- no translation found for permgrouplab_statusBar (2095862568113945398) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_statusBar (6242593432226807171) -->
-    <skip />
-    <!-- no translation found for permgrouplab_syncSettings (3341990986147826541) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_syncSettings (7603195265129031797) -->
-    <skip />
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Boekmerke en geskiedenis"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte toegang tot boekmerke en blaaiergeskiedenis."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Wekker"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Stel die wekker."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Stemboodskapdiens"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Direkte toegang tot stemboodskapdiens."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Direkte toegang tot die mikrofoon om oudio op te neem."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Direkte toegang tot kamera vir die neem van foto of video."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Jou programme-inligting"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Vermoë om die gedrag van ander programme op jou toestel te beïnvloed."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Muurpapier"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Verander die toestel se muurpapier-instellings."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Klok"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Verander die toestel se tyd of tydsone."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Statusbalk"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Verander die toestel se statusbalk-instellings."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Sinkronisasie-instellings"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Gaan in by die sinkronisasie-instellings."</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"Jou rekeninge"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Kry toegang tot beskikbare rekeninge."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardewarekontroles"</string>
@@ -256,10 +227,8 @@
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Laervlak-toegang en -beheer van die stelsel."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Ontwikkelingshulpmiddels"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Kenmerke net nodig vir programontwikkelaars."</string>
-    <!-- no translation found for permgrouplab_display (4279909676036402636) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_display (6051002031933013714) -->
-    <skip />
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Ander program-UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Affekteer ander programme se UI"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Stoor"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Gebruik die USB-berging."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Lees die SD-kaart."</string>
@@ -779,8 +748,7 @@
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Geen SIM-kaart in foon nie."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Steek \'n SIM-kaart in."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Die SIM-kaart is weg of nie leesbaar nie. Steek \'n SIM-kaart in."</string>
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Onbruikbare SIM-kaart."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Jou SIM-kaart is permanent gedeaktiveer."\n" Kontak jou draadlose diensverskaffer vir \'n ander SIM-kaart."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Vorigesnit-knoppie"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Volgendesnit-knoppie"</string>
@@ -1353,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Stuur tans…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Begin webblaaier?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aanvaar oproep?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 42c88ae..c0c0c9c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -201,16 +201,16 @@
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ወደ ዕልባቶችና የአሳሽ ታሪክ ቀጥተኛ መዳረሻ።"</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"ማንቂያ"</string>
     <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"የማንቂያ ሰዓቱን አዘጋጅ።"</string>
-    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"የድምፅ ፖስታ"</string>
-    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"ወደ የድምጽ ፖስታ ቀጥተኛ መዳረሻ።"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"የድምጽ መልዕክት"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"ወደ የድምጽ መልዕክት ቀጥተኛ መዳረሻ።"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"ማይክሮፎን"</string>
     <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ድምጽ ለመቅረጽ ወደ ማይክሮፎኑ ቀጥተኛ መዳረሻ።"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"ካሜራ"</string>
-    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ለምስል ወይም ቪዲዮ ለመቅረጽ ቀጥተና መዳረሻ ለካሜራ።"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ለካሜራ ምስል ወይም ቪዲዮ ለመቅረጽ ቀጥተኛ መዳረሻ።"</string>
     <string name="permgrouplab_appInfo" msgid="8028789762634147725">"የመተግበሪያዎችህ መረጃ"</string>
     <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"በመሣሪያህ ላይ ያሉ የሌሎች መተግበሪያዎች ባህሪዎች ላይ ተፅዕኖ የማሳረፍ ችሎታ።"</string>
     <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ልጣፍ"</string>
-    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"የመሣሪያው ልጣፍ ቅንብሮቹን ቀይር።"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"የመሣሪያውን ልጣፍ ቅንብሮች ቀይር።"</string>
     <string name="permgrouplab_systemClock" msgid="406535759236612992">"ሰዓት"</string>
     <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"የመሣሪያውን ሰዓት ወይም የሰዓት ሰቁን ቀይር።"</string>
     <string name="permgrouplab_statusBar" msgid="2095862568113945398">"የሁኔታ አሞሌ"</string>
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"በመላክ ላይ…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ማሰሺያን አስነሳ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ጥሪ ተቀበል?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 35123de..4196052 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"يمكنك مراقبة موقعك الفعلي."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"اتصال الشبكة"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"يمكنك الدخول إلى ميزات متعددة عبر الشبكة."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"بلوتوث"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"الدخول إلى الأجهزة والشبكات من خلال البلوتوث."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"الشبكات قصيرة المدى"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"الدخول إلى الأجهزة من خلال الشبكات قصيرة المدى مثل الاتصالات قريبة المدى (NFC)."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"إعدادات الصوت"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"تغيير إعدادات الصوت"</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"التأثير على البطارية"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"استخدم الميزات التي يمكن أن تؤدي إلى نفاد طاقة البطارية بسرعة."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"التقويم"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"الدخول المباشر إلى التقويم والأحداث."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"قراءة قاموس المستخدم"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"قراءة الكلمات في قاموس المستخدم."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"كتابة قاموس المستخدم"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"إضافة الكلمات إلى قاموس المستخدم."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"الإشارات المرجعية والسجل"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"الدخول المباشر إلى الإشارات المرجعية وسجل المتصفح."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"المنبه"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"يسمح للتطبيق بقراءة محتويات وحدة تخزين USB، والتي قد تتضمن صورًا ووسائط."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"يسمح للتطبيق بقراءة محتويات بطاقة SD، والتي قد تتضمن صورًا ووسائط."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"تعديل محتويات وحدة تخزين USB أو حذفها"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"تعديل محتويات بطاقة SD أو حذفها"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"للسماح للتطبيق بالكتابة إلى وحدة تخزين USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"للسماح للتطبيق بالكتابة إلى بطاقة SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تعديل/حذف محتويات وحدة تخزين الوسائط الداخلية"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"تعيين"</string>
     <string name="date_time_done" msgid="2507683751759308828">"تم"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"جديد: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"يقدمه <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"لا أذونات مطلوبة"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"تخزين USB كبير السعة"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB متصل"</string>
@@ -1321,8 +1311,7 @@
     <string name="sending" msgid="3245653681008218030">"جارٍ الإرسال..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"هل تريد قبول المكالمة؟"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"مرة واحدة فقط"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index bc50211..446f113 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Адпраўка..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Прыняць выклік?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 90462b3..b35eae5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Изпраща се..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Да се стартира ли браузърът?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Да се приеме ли обаждането?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 69d982b..5766f15f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Supervisa la teva ubicació física."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicació de xarxa"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Accedeix a diverses funcions de xarxa."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Accés a dispositius i a xarxes mitjançant Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Xarxes de poc abast"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Accés a dispositius mitjançant xarxes de poc abast, com ara NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Configuració d\'àudio"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Canviar la configuració de l\'àudio."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Afectar la bateria"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Fer servir funcions que poden consumir bateria ràpidament."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendari"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Accés directe a calendaris i a esdeveniments."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Llegeix el diccionari de l\'usuari"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Llegeix paraules al diccionari de l\'usuari."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Escriu al diccionari de l\'usuari"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Afegeix paraules al diccionari de l\'usuari."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadors i historial"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accés directe a l\'historial de marcadors i de navegació."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarma"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Permet que l\'aplicació llegeixi el contingut de l\'emmagatzematge USB, incloses les fotos i els fitxers multimèdia."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Permet que l\'aplicació llegeixi el contingut de la targeta SD, incloses les fotos i els fitxers multimèdia."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modificació o supressió del contingut de l\'emmagatzematge USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifica o suprimeix el contingut de la targeta SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permet que l\'aplicació escrigui a l\'emmagatzematge USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet a l\'aplicació escriure a la targeta SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Canvia/esborra emmagatz. intern"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Fet"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NOU: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Proporcionat per <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Emmagatzematge massiu USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB connectat"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"S\'està enviant…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vols iniciar el navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vols acceptar la trucada?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Només una vegada"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c77a21a..dd6d0b1 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Odesílání..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Přijmout hovor?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 5a5cda3..e46ff7c 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1321,8 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Sender..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte browseren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare opkaldet?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Altid"</string>
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 398313b..9145263 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1321,8 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Wird gesendet..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Anruf annehmen?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Immer"</string>
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 05dcf69..08e2389 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Παρακολούθηση της φυσικής τοποθεσίας σας."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Επικοινωνία δικτύου"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Πρόσβαση σε διάφορες λειτουργίες δικτύου."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Πρόσβαση σε συσκευές και δίκτυα μέσω Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Δίκτυα μικρού εύρους"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Πρόσβαση σε συσκευές μέσω δικτύων μικρού εύρους όπως NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Ρυθμίσεις ήχου"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Αλλαγή ρυθμίσεων ήχου."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Επηρεάζει την μπαταρία"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Χρήση λειτουργιών που μπορούν να εξαντλήσουν γρήγορα την μπαταρία."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Ημερολόγιο"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Άμεση πρόσβαση σε ημερολόγιο και συμβάντα."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Ανάγνωση λεξικού χρήστη"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Ανάγνωση λέξεων στο λεξικό χρήστη."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Εγγραφή στο λεξικό χρήστη"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Προσθήκη λέξεων στο λεξικό χρήστη."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Σελιδοδείκτες και ιστορικό"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Άμεση πρόσβαση σε σελιδοδείκτες και ιστορικού προγράμματος περιήγησης."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Ξυπνητήρι"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Επιτρ. η ανάγν. περ. αποθ. χώρ. USB, με φωτ. και μέσα"</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Επιτρέπει στην εφαρμογή την ανάγνωση του περιεχομένου της κάρτας SD, το οποίο μπορεί να περιλαμβάνει φωτογραφίες και μέσα."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"τροπ. ή διαγρ. περιεχ. αποθ. χώρ. USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"τροποποίηση ή διαγραφή των περιεχομένων της κάρτας SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Επιτρέπει στην εφαρμογή την εγγραφή στον αποθηκευτικό χώρο USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"τροπ./διαγ. περ. απ. εσ. μνήμ."</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Ορισμός"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Τέλος"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"ΝΕΟ: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Παρέχεται από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"Δεν απαιτούνται άδειες"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Μαζική αποθήκευση USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"Το USB είναι συνδεδεμένο"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"Γίνεται αποστολή…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Αποδοχή κλήσης;"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Πάντα"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Μόνο μία φορά"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 4af21ed..c991437 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Monitor your physical location."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Network communication"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Access various network features."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Access devices and networks through Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Short-range Networks"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Access devices through short-range networks such as NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Audio Settings"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Change audio settings."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Affects Battery"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Use features that can quickly drain battery."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Direct access to calendar and events."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Read User Dictionary"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Read words in user dictionary."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Write User Dictionary"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Add words to the user dictionary."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Allows the app to read contents of USB storage, which may include photos and media."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Allows the app to read contents of SD card, which may include photos and media."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modify or delete the contents of your USB storage"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modify or delete the contents of your SD card"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Allows the app to write to the USB storage."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modify/delete internal media storage contents"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Set"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Done"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NEW: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Provided by <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB mass storage"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB connected"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"Sending…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Just Once"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a3eb0f9..94d7a4b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Deseas iniciar el navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index fd28787..ea1f3c4 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Controlar tu ubicación física"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicación de red"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Acceder a distintas funciones de red"</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Acceder a dispositivos y redes a través de Bluetooth"</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Redes de corto alcance"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Acceder a dispositivos a través de redes de corto alcance, como NFC"</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Ajustes de audio"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Modificar ajustes de audio"</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Afectar a la batería"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Usar funciones que agotan la batería rápidamente"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Acceder directamente al calendario y a los eventos"</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Leer el diccionario del usuario"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Leer palabras del diccionario del usuario"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Escribir en el diccionario del usuario"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Añadir palabras al diccionario del usuario"</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e historial"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceder directamente a los marcadores y al historial del navegador"</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarma"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Permite que la aplicación lea el contenido del almacenamiento USB que puede incluir fotos y archivos multimedia."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Permite que la aplicación lea el contenido de la tarjeta SD que puede incluir fotos y archivos multimedia."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"editar o borrar contenido de USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modificar o eliminar el contenido de la tarjeta SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite escribir en el almacenamiento USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que la aplicación escriba en la tarjeta SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar o eliminar el contenido del almacenamiento de medios interno"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Listo"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NUEVO:"</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Proporcionado por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="no_permissions" msgid="7283357728219338112">"No es necesario ningún permiso"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Almacenamiento USB masivo"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"Conexión por USB"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Siempre"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Solo una vez"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 82e76e0..c87b0cc 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Saatmine ..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Kas käivitada brauser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Kas vastata kõnele?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1c0ef97..77bba4d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -168,84 +168,47 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"پیام های شما"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"پیام کوتاه، ایمیل و دیگر پیامها را بخوانید."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"اطلاعات شخصی شما"</string>
-    <!-- no translation found for permgroupdesc_personalInfo (8426453129788861338) -->
-    <skip />
-    <!-- no translation found for permgrouplab_socialInfo (5799096623412043791) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_socialInfo (7129842457611643493) -->
-    <skip />
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"مستقیم به اطلاعات مربوط به خود، ذخیره شده در روی کارت تماس خود دسترسی داشته باشید."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"اطلاعات اجتماعی شما"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"مستقیم به اطلاعات مخاطبین و روابط اجتماعی دسترسی داشته باشید."</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"موقعیت مکانی شما"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"بر موقعیت مکانی فیزیکی خود نظارت داشته باشید."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"ارتباط شبکه"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"به ویژگی‎های مختلف شبکه دسترسی داشته باشید."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
-    <!-- no translation found for permgrouplab_audioSettings (8329261670151871235) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_audioSettings (2641515403347568130) -->
-    <skip />
-    <!-- no translation found for permgrouplab_affectsBattery (6209246653424798033) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_affectsBattery (6441275320638916947) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (5777534316982184416) -->
-    <skip />
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
-    <!-- no translation found for permgrouplab_bookmarks (1949519673103968229) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bookmarks (4169771606257963028) -->
-    <skip />
-    <!-- no translation found for permgrouplab_deviceAlarms (6117704629728824101) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_deviceAlarms (4769356362251641175) -->
-    <skip />
-    <!-- no translation found for permgrouplab_voicemail (4162237145027592133) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_voicemail (2498403969862951393) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (7106618286905738408) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (2933667372289567714) -->
-    <skip />
-    <!-- no translation found for permgrouplab_appInfo (8028789762634147725) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_appInfo (3950378538049625907) -->
-    <skip />
-    <!-- no translation found for permgrouplab_wallpaper (3850280158041175998) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_wallpaper (5630417854750540154) -->
-    <skip />
-    <!-- no translation found for permgrouplab_systemClock (406535759236612992) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_systemClock (3944359833624094992) -->
-    <skip />
-    <!-- no translation found for permgrouplab_statusBar (2095862568113945398) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_statusBar (6242593432226807171) -->
-    <skip />
-    <!-- no translation found for permgrouplab_syncSettings (3341990986147826541) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_syncSettings (7603195265129031797) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"بلوتوث"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"از طریق بلوتوث به دستگاه‌ها و شبکه‌ها دسترسی داشته باشد."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"شبکه‌های نزدیک"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"از طریق شبکه‌های نزدیک مانند NFC، به دستگاه‌ها دسترسی داشته باشد."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"تنظیمات صدا"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"تنظیمات صوتی را تغییر دهید."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"روی باتری اثر دارد"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"از ویژگی‌هایی استفاده کنید که باتری را سریع خالی می‌کند."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"تقویم"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"مستقیم به رویدادها و تقویم دسترسی داشته باشید."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"خواندن فرهنگ لغت کاربر"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"کلمات را در فرهنگ لغت کاربر بخواند."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"نوشتن فرهنگ لغت کاربر"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"کلمات را به فرهنگ لغت کاربر اضافه کند."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"نشانک‌ها و سابقه"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"مستقیم به نشانک‌ها و سابقه مرور دسترسی داشته باشید."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"زنگ هشدار"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"ساعت زنگ دار را تنظیم کنید."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"پست صوتی"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"به پست صوتی مستقیم دسترسی داشته باشید."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"میکروفن"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"مستقیم به میکروفن برای ضبط صدا دسترسی داشته باشید."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"دوربین"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"مستقیم به دوربین برای عکس گرفتن یا ضبط فیلم دسترسی داشته باشید."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"اطلاعات برنامه‌های شما"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"می‌تواند بر عملکرد برنامه‌های دیگر روی دستگاه اثر بگذارد."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"تصویر زمینه"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"تنظیمات تصویر زمینه دستگاه را تغییر دهید."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"ساعت"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"زمان یا منطقه زمانی دستگاه را تغییر دهید."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"نوار وضعیت"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"تنظیمات نوار وضعیت دستگاه را تغییر دهید."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"تنظیمات همگام‌سازی"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"به تنظیمات همگام‌سازی دسترسی داشته باشید."</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"حساب های شما"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"به حساب های موجود دسترسی داشته باشید."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"کنترل های سخت افزار"</string>
@@ -256,10 +219,8 @@
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"دسترسی سطح پایین و کنترل سیستم."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"ابزارهای توسعه"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"ویژگیهایی که فقط مورد نیاز برنامه نویسان است."</string>
-    <!-- no translation found for permgrouplab_display (4279909676036402636) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_display (6051002031933013714) -->
-    <skip />
+    <string name="permgrouplab_display" msgid="4279909676036402636">"رابط برنامه دیگر"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"روی رابط برنامه‌های دیگر اثر دارد."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ذخیره سازی"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"به حافظه USB دسترسی پیدا کنید."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"به کارت SD دسترسی داشته باشید."</string>
@@ -600,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"به برنامه امکان می‌دهد محتویات حافظه USB را بخواند که ممکن است حاوی عکس و رسانه باشد."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"به برنامه اجازه می‌دهد محتویات کارت SD را بخواند که ممکن است حاوی عکس و رسانه باشد."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"اصلاح یا حذف محتویات حافظه USB شما"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"محتوای کارت SD شما را اصلاح کرده یا تغییر دهد"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"به برنامه اجازه می‎دهد تا در حافظه USB بنویسد."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"به برنامه اجازه می‎دهد تا در کارت SD بنویسد."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تغییر/حذف محتواهای حافظه رسانه داخلی"</string>
@@ -779,8 +739,7 @@
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"سیم کارت درون تلفن نیست."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"سیم کارت را وارد کنید."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"سیم کارت موجود نیست یا قابل خواندن نیست. یک سیم کارت وارد کنید."</string>
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"سیم کارت غیرقابل استفاده است."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"سیم کارت شما به طور دائم غیر فعال شده است. "\n"برای داشتن سیم کارت دیگر با ارائه‎دهنده سرویس بی‎سیم خود تماس بگیرید."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"دکمه تراک قبلی"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"دکمه تراک بعدی"</string>
@@ -1122,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"تنظیم"</string>
     <string name="date_time_done" msgid="2507683751759308828">"انجام شد"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"جدید: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"ارائه شده توسط <xliff:g id="APP_NAME">%1$s</xliff:g> ."</string>
     <string name="no_permissions" msgid="7283357728219338112">"مجوزی لازم نیست"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"حافظه انبوه USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB متصل شد"</string>
@@ -1353,8 +1311,7 @@
     <string name="sending" msgid="3245653681008218030">"درحال ارسال..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"مرورگر راه‌اندازی شود؟"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"تماس را می‌پذیرید؟"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"فقط یکبار"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index ac72b4e..8f244c0 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Lähetetään…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vastataanko puheluun?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1622284..c1c3e84 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1321,8 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Envoi en cours…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel ?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index ea6447f..3726b6c 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"भेजा जा रहा है…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"कॉल स्वीकार करें?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index b1c95aa..8e03743 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Slanje..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 89aedcc..a00ae69 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Küldés…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Fogadja a hívást?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 7dc51e4..753e7fd 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -168,12 +168,9 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Pesan Anda"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"Membaca dan menulis SMS, email, dan pesan Anda lainnya."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Informasi pribadi Anda"</string>
-    <!-- no translation found for permgroupdesc_personalInfo (8426453129788861338) -->
-    <skip />
-    <!-- no translation found for permgrouplab_socialInfo (5799096623412043791) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_socialInfo (7129842457611643493) -->
-    <skip />
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Akses langsung ke informasi tentang Anda, yang tersimpan dalam kartu kontak Anda."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informasi sosial Anda"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke informasi tentang kontak dan hubungan sosial Anda."</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"Lokasi Anda"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Memonitor lokasi fisik Anda."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Komunikasi jaringan"</string>
@@ -186,18 +183,12 @@
     <skip />
     <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
     <skip />
-    <!-- no translation found for permgrouplab_audioSettings (8329261670151871235) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_audioSettings (2641515403347568130) -->
-    <skip />
-    <!-- no translation found for permgrouplab_affectsBattery (6209246653424798033) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_affectsBattery (6441275320638916947) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (5777534316982184416) -->
-    <skip />
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Setelan Audio"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Mengubah setelan audio."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Memengaruhi Baterai"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Menggunakan fitur yang dapat menguras baterai dengan cepat."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Akses langsung ke kalender dan acara."</string>
     <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
     <skip />
     <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
@@ -206,46 +197,26 @@
     <skip />
     <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
     <skip />
-    <!-- no translation found for permgrouplab_bookmarks (1949519673103968229) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bookmarks (4169771606257963028) -->
-    <skip />
-    <!-- no translation found for permgrouplab_deviceAlarms (6117704629728824101) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_deviceAlarms (4769356362251641175) -->
-    <skip />
-    <!-- no translation found for permgrouplab_voicemail (4162237145027592133) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_voicemail (2498403969862951393) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (7106618286905738408) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (2933667372289567714) -->
-    <skip />
-    <!-- no translation found for permgrouplab_appInfo (8028789762634147725) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_appInfo (3950378538049625907) -->
-    <skip />
-    <!-- no translation found for permgrouplab_wallpaper (3850280158041175998) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_wallpaper (5630417854750540154) -->
-    <skip />
-    <!-- no translation found for permgrouplab_systemClock (406535759236612992) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_systemClock (3944359833624094992) -->
-    <skip />
-    <!-- no translation found for permgrouplab_statusBar (2095862568113945398) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_statusBar (6242593432226807171) -->
-    <skip />
-    <!-- no translation found for permgrouplab_syncSettings (3341990986147826541) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_syncSettings (7603195265129031797) -->
-    <skip />
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmark dan Riwayat"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke bookmark dan riwayat browser."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Menyetel jam alarm."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Pesan Suara"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Akses langsung ke pesan suara."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Akses langsung ke mikrofon untuk merekam audio."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Akses langsung ke kamera untuk gambar atau tangkapan video."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Informasi aplikasi Anda"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Kemampuan untuk memengaruhi perilaku aplikasi lain pada perangkat Anda."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Wallpaper"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Mengubah setelan wallpaper perangkat."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Jam"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Mengubah zona waktu atau waktu perangkat."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Bilah Status"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Mengubah setelan bilah status perangkat."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Setelan Sinkronisasi"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Akses ke setelan sinkronisasi."</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akun-akun Anda"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Akses akun yang tersedia."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Kontrol perangkat keras"</string>
@@ -256,10 +227,8 @@
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Akses tingkat rendah dan kontrol sistem."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Peralatan pengembangan"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Fitur hanya diperlukan oleh pengembang apl."</string>
-    <!-- no translation found for permgrouplab_display (4279909676036402636) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_display (6051002031933013714) -->
-    <skip />
+    <string name="permgrouplab_display" msgid="4279909676036402636">"UI Aplikasi Lainnya"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Memengaruhi UI aplikasi lain."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Penyimpanan"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Akses penyimpanan USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Akses kartu SD."</string>
@@ -779,8 +748,7 @@
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Tidak ada Kartu SIM di dalam ponsel."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Masukkan kartu SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kartu SIM tidak ada atau tidak dapat dibaca. Masukkan kartu SIM."</string>
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kartu SIM tidak dapat digunakan."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kartu SIM Anda telah dinonaktifkan secara permanen."\n" Hubungi penyedia layanan nirkabel Anda untuk kartu SIM lain."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tombol trek sebelumnya"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tombol trek berikutnya"</string>
@@ -1353,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Mengirim..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ce93389..0764284 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Monitoraggio della posizione fisica dell\'utente."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicazione di rete"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Accesso a varie funzioni di rete."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"È possibile accedere a dispositivi e reti tramite Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Reti a corto raggio"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"È possibile accedere ai dispositivi tramite reti a corto raggio come le NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Impostazioni audio"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Modifica delle impostazioni audio."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Influenza sulla batteria"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Uso di funzioni che possono consumare rapidamente la batteria."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Accesso diretto al calendario e agli eventi."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Lettura del dizionario utente"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"È possibile leggere le parole nel dizionario utente."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Scrittura nel dizionario utente"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"È possibile aggiungere parole al dizionario utente."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Segnalibri e cronologia"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accesso diretto ai segnalibri e alla cronologia del browser."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Sveglia"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Consente all\'applicazione di leggere i contenuti dell\'archivio USB, che possono includere foto e contenuti multimediali."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Consente all\'applicazione di leggere i contenuti della scheda SD, che possono includere foto e contenuti multimediali."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"mod./elimin. cont. archivio USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifica o eliminazione dei contenuti della scheda SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Consente all\'applicazione di scrivere nell\'archivio USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Consente all\'applicazione di scrivere sulla scheda SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifica/eliminaz. contenuti archivio media int."</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Fine"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NUOVA: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Fornito da <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"Nessuna autorizzazione richiesta"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Archivio di massa USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB collegata"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"Invio..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accettare la chiamata?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Solo una volta"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 020686e..a111f5a 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"עקוב אחר המיקום הפיזי שלך."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"תקשורת רשת"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"הרשאת גישה לתכונות רשת שונות."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"גישה למכשירים ולרשתות באמצעות Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"רשתות לטווח קצר"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"גישה למכשירים באמצעות רשתות קצרות-טווח, כגון רשתות NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"הגדרות אודיו"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"שינוי הגדרות האודיו."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"השפעה על הסוללה"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"שימוש בתכונות שיכולות לרוקן את הסוללה במהירות."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"לוח שנה"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"גישה ישירה ללוח השנה ולאירועים."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"קריאת מילון משתמש"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"קריאת מילים במילון משתמש."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"כתיבת מילון משתמש"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"הוספת מילים למילון משתמש."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"סימניות והיסטוריה"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"גישה ישירה אל סימניות והיסטוריית דפדפן."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"שעון מעורר"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"הרשאה זו מאפשרת ליישום לקרוא את התוכן של אחסון USB, העשוי לכלול תמונות ומדיה."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"הרשאה זו מאפשרת ליישום לקרוא תוכן של כרטיס SD, העשוי לכלול תמונות ומדיה."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"שינוי או מחיקה של תוכן אחסון ה-USB שלך"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"שינוי או מחיקה של תוכן כרטיס ה-SD שלך"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"מאפשר ליישום לכתוב להתקן האחסון מסוג USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"מאפשר ליישום לכתוב לכרטיס ה-SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"שנה/מחק תוכן של אחסון מדיה פנימי"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"הגדר"</string>
     <string name="date_time_done" msgid="2507683751759308828">"בוצע"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"חדש: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"מטעם <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"לא דרושים אישורים"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"אמצעי מסוג USB לאחסון בנפח גדול"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB מחובר"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"שולח…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"להפעיל את הדפדפן?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"האם לקבל את השיחה?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"תמיד"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"רק פעם אחת"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index b45d6cb..d05be0c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"送信中..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"通話を受けますか?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index adafd25..964816e 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"전송 중..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"통화를 수락하시겠습니까?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1819172..f90907e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Siunčiama…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Paleisti naršyklę?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Priimti skambutį?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8231db1..8d0ed36 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Notiek sūtīšana…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vai palaist pārlūkprogrammu?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vai atbildēt uz zvanu?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 0bc4262..1b479a4 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -168,12 +168,9 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Mesej anda"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"Membaca dan menulis SMS, e-mel, dan mesej lain."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Maklumat peribadi anda"</string>
-    <!-- no translation found for permgroupdesc_personalInfo (8426453129788861338) -->
-    <skip />
-    <!-- no translation found for permgrouplab_socialInfo (5799096623412043791) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_socialInfo (7129842457611643493) -->
-    <skip />
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Akses langsung ke maklumat tentang anda, yang disimpan pada kad kenalan anda."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Maklumat sosial anda"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke maklumat tentang kenalan anda dan sambungan sosial."</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"Lokasi anda"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Pantau lokasi fizikal anda."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Komunikasi rangkaian"</string>
@@ -186,18 +183,12 @@
     <skip />
     <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
     <skip />
-    <!-- no translation found for permgrouplab_audioSettings (8329261670151871235) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_audioSettings (2641515403347568130) -->
-    <skip />
-    <!-- no translation found for permgrouplab_affectsBattery (6209246653424798033) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_affectsBattery (6441275320638916947) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (5777534316982184416) -->
-    <skip />
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Tetapan Audio"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Tukar tetapan audio."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Menjejaskan Bateri"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Gunakan ciri yang boleh menghabiskan bateri dengan cepat."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Akses langsung ke kalendar dan acara."</string>
     <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
     <skip />
     <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
@@ -206,46 +197,26 @@
     <skip />
     <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
     <skip />
-    <!-- no translation found for permgrouplab_bookmarks (1949519673103968229) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bookmarks (4169771606257963028) -->
-    <skip />
-    <!-- no translation found for permgrouplab_deviceAlarms (6117704629728824101) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_deviceAlarms (4769356362251641175) -->
-    <skip />
-    <!-- no translation found for permgrouplab_voicemail (4162237145027592133) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_voicemail (2498403969862951393) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (7106618286905738408) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (2933667372289567714) -->
-    <skip />
-    <!-- no translation found for permgrouplab_appInfo (8028789762634147725) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_appInfo (3950378538049625907) -->
-    <skip />
-    <!-- no translation found for permgrouplab_wallpaper (3850280158041175998) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_wallpaper (5630417854750540154) -->
-    <skip />
-    <!-- no translation found for permgrouplab_systemClock (406535759236612992) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_systemClock (3944359833624094992) -->
-    <skip />
-    <!-- no translation found for permgrouplab_statusBar (2095862568113945398) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_statusBar (6242593432226807171) -->
-    <skip />
-    <!-- no translation found for permgrouplab_syncSettings (3341990986147826541) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_syncSettings (7603195265129031797) -->
-    <skip />
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Penanda halaman dan Sejarah"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke penanda halaman dan sejarah penyemak imbas."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Penggera"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Tetapkan jam penggera."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Mel suara"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Akses langsung ke mel suara."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Akses langsung ke mikrofon untuk merakam audio."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Akses langsung ke kamera untuk merakam imej atau video."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Maklumat aplikasi anda"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Keupayaan untuk mempengaruhi tingkah laku aplikasi lain pada peranti anda."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Kertas dinding"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Tukar tetapan kertas dinding peranti."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Jam"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Tukar masa peranti atau zon masa."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Bar Status"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Tukar tetapan bar status peranti."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Tetapan Penyegerakan"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Akses ke tetapan segerakan."</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akaun anda"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Akses akaun yang tersedia."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Kawalan perkakasan"</string>
@@ -256,10 +227,8 @@
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Akses dan kawalan peringkat lebih rendah bagi sistem."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Alatan pembangunan"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Ciri hanya diperlukan untuk pembangun apl."</string>
-    <!-- no translation found for permgrouplab_display (4279909676036402636) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_display (6051002031933013714) -->
-    <skip />
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Aplikasi UI Lain"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Mempengaruhi UI aplikasi lain."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Storan"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Akses storan USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Akses kad SD."</string>
@@ -779,8 +748,7 @@
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Kad SIM tiada dalam telefon."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Masukkan kad SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kad SIM tiada atau tidak boleh dibaca. Sila masukkan kad SIM."</string>
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kad SIM tidak boleh digunakan."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kad SIM anda telah dilumpuhkan secara kekal."\n" Hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Butang lagu sebelumnya"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Butang lagu seterusnya"</string>
@@ -1353,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Menghantar…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancarkan Penyemak Imbas?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3427829..88db9f4 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Sender …"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare anropet?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ef85ec4..dfd67ff 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Uw fysieke locatie bijhouden."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Netwerkcommunicatie"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Toegang tot verschillende netwerkfuncties."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Toegang tot apparaten en netwerken via Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Netwerken op korte afstand"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Toegang tot apparaten via netwerken op korte afstand zoals NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Audio-instellingen"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Audio-instellingen wijzigen."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"De accu beïnvloeden"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Functies gebruiken waardoor de accu snel leeg kan raken."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Rechtstreeks toegang krijgen tot agenda en afspraken."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Gebruikerswoordenboek lezen"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Woorden lezen in het gebruikerswoordenboek."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Gebruikerswoordenboek schrijven"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Woorden toevoegen aan het gebruikerswoordenboek."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bladwijzers en geschiedenis"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Rechtstreeks toegang krijgen tot bladwijzers en browsergeschiedenis."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Toestaan dat de app inhoud in de USB-opslag, waaronder foto\'s en media, leest."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Toestaan dat de app inhoud op de SD-kaart, waaronder foto\'s en media, leest."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"de inhoud van uw USB-opslag aanpassen of verwijderen"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"de inhoud van uw SD-kaart aanpassen of verwijderen"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Hiermee kan de app schrijven naar de USB-opslag."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Hiermee kan de app schrijven naar de SD-kaart."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"inh. mediaopsl. wijz./verw."</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Gereed"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NIEUW: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Geleverd door <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"Geen machtigingen vereist"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB-massaopslag"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB-verbinding"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"Verzenden..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Oproep accepteren?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Altijd"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Alleen nu gebruiken"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 022b8c5..62c839b1 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -168,12 +168,9 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Twoje wiadomości"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"Czytanie i zapisywanie wiadomości SMS, e-mail i innych"</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Informacje osobiste"</string>
-    <!-- no translation found for permgroupdesc_personalInfo (8426453129788861338) -->
-    <skip />
-    <!-- no translation found for permgrouplab_socialInfo (5799096623412043791) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_socialInfo (7129842457611643493) -->
-    <skip />
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Bezpośredni dostęp do informacji o Tobie zapisanych na wizytówce."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Twoje informacje społecznościowe"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Bezpośredni dostęp do informacji o Twoich kontaktach i powiązaniach społecznościowych."</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"Twoja lokalizacja"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Monitorowanie fizycznej lokalizacji"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Połączenia sieciowe"</string>
@@ -186,18 +183,12 @@
     <skip />
     <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
     <skip />
-    <!-- no translation found for permgrouplab_audioSettings (8329261670151871235) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_audioSettings (2641515403347568130) -->
-    <skip />
-    <!-- no translation found for permgrouplab_affectsBattery (6209246653424798033) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_affectsBattery (6441275320638916947) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (5777534316982184416) -->
-    <skip />
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Ustawienia dźwięku"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Zmiana ustawień dźwięku."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Użycie baterii"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Korzystanie z funkcji, które mogą szybko rozładować baterię."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendarz"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Bezpośredni dostęp do kalendarza i wydarzeń."</string>
     <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
     <skip />
     <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
@@ -206,46 +197,26 @@
     <skip />
     <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
     <skip />
-    <!-- no translation found for permgrouplab_bookmarks (1949519673103968229) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bookmarks (4169771606257963028) -->
-    <skip />
-    <!-- no translation found for permgrouplab_deviceAlarms (6117704629728824101) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_deviceAlarms (4769356362251641175) -->
-    <skip />
-    <!-- no translation found for permgrouplab_voicemail (4162237145027592133) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_voicemail (2498403969862951393) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (7106618286905738408) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (2933667372289567714) -->
-    <skip />
-    <!-- no translation found for permgrouplab_appInfo (8028789762634147725) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_appInfo (3950378538049625907) -->
-    <skip />
-    <!-- no translation found for permgrouplab_wallpaper (3850280158041175998) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_wallpaper (5630417854750540154) -->
-    <skip />
-    <!-- no translation found for permgrouplab_systemClock (406535759236612992) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_systemClock (3944359833624094992) -->
-    <skip />
-    <!-- no translation found for permgrouplab_statusBar (2095862568113945398) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_statusBar (6242593432226807171) -->
-    <skip />
-    <!-- no translation found for permgrouplab_syncSettings (3341990986147826541) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_syncSettings (7603195265129031797) -->
-    <skip />
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Zakładki i historia"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Bezpośredni dostęp do zakładek i historii przeglądarki."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Ustawianie budzika."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Poczta głosowa"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Bezpośredni dostęp do poczty głosowej."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Bezpośredni dostęp do mikrofonu i nagrywanie dźwięku."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Aparat"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Bezpośredni dostęp do aparatu – robienie zdjęć i nagrywanie filmów."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Informacje o aplikacjach"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Możliwość zmiany działania innych aplikacji na urządzeniu."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Tapeta"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Zmiana ustawień tapety urządzenia."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Zegar"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Zmiana czasu i strefy czasowej na urządzeniu."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Pasek stanu"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Zmiana ustawień paska stanu urządzenia."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Ustawienia synchronizacji"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Dostęp do ustawień synchronizacji."</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"Twoje konta"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Dostęp do udostępnionych kont."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Sterowanie sprzętowe"</string>
@@ -256,10 +227,8 @@
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Dostęp i kontrola systemu niższego poziomu."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Narzędzia programistyczne"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Funkcje potrzebne jedynie programistom."</string>
-    <!-- no translation found for permgrouplab_display (4279909676036402636) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_display (6051002031933013714) -->
-    <skip />
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Interfejsy innych aplikacji"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Możliwość wpływania na interfejsy innych aplikacji."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Pamięć"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Dostęp do nośnika USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Dostęp do karty SD."</string>
@@ -779,8 +748,7 @@
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Brak karty SIM w telefonie."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Włóż kartę SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Brak karty SIM lub nie można jej odczytać. Włóż kartę SIM."</string>
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Karta SIM bezużyteczna."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Karta SIM jest trwale wyłączona."\n" Skontaktuj się z dostawcą usług bezprzewodowych, aby uzyskać inną kartę SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Przycisk poprzedniego utworu"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Przycisk następnego utworu"</string>
@@ -1353,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Wysyłanie..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Odebrać połączenie?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e785c7c..1825346 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"A enviar..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar Navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c7b6746..2e00b29 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 3ca7f9c..e22bb14 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -2069,7 +2069,7 @@
     <skip />
     <!-- no translation found for SetupCallDefault (5834948469253758575) -->
     <skip />
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 963b676..61428cd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Se trimite..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Acceptaţi apelul?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 04163ee..1fcd393 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Отправка..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Ответить?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index fff419d..db562c7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Odosielanie..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prijať hovor?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index df0ddea..570bb59 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Pošiljanje ..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Ali želite sprejeti klic?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 5573607..11a733d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Слање..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Желите ли да прихватите позив?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 5bce25a..251d487 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1321,8 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Skickar ..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vill du öppna webbläsaren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vill du ta emot samtal?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 05732dc..1904de4 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Fuatilia eneo lako halisi."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Mawasiliano ya mtandao"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Fikia vipengele mbalimbali vya mtandao."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Fikia vifaa na mitandao kupitia Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Mitandao ya Masafa mafupi"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Fikia vifaa kupitia mitandao ya masafa mafupi kama vile NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Mipangilio ya Sauti"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Badilisha mipangilio ya sauti."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Huathiri Betri"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Tumia vipengele vinaweza kumaliza betri haraka."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenda"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Kufikia moja kwa moja kalenda na matukio."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Soma Kamuzi ya Mtumiaji"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Soma maneno katika kamusi ya mtumiaji."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Andika Kamusi ya Mtumiaji"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Ongeza maneno katika kamusi mtumiaji."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Vialamisho na Historia"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Kufikia moja kwa moja vialamisho na historia ya kivinjari"</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Kengele"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Huruhusu programu kusoma maudhui ya hifadhi ya USB, ambayo huenda ikajumuisha picha na midia."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Huruhusu programu kusoma maudhui ya kadi ya SD, ambayo huenda yakajumuisha picha na midia."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"rekebisha au ufute maudhui ya hifadhi yako ya USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"rekebisha au ufute maudhui ya kadi yako ya SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Inaruhusu programu kuandikia hifadhi ya USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Inaruhusu programu kuandikia kadi ya SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"badilisha/futa maudhui ya hifadhi ya media ya ndani."</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Weka"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Imekamilika"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">" MPYA: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Zinatolewa na <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"Hakuna vibali vinavyohitajika"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Hifadhi kubwa ya USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB imeunganishwa"</string>
@@ -1321,8 +1311,6 @@
     <string name="sending" msgid="3245653681008218030">"Inatuma…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Zindua Kivinjari?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Kubali simu?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Kila mara"</string>
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Mara Moja tu"</string>
 </resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 61136e3..c5727ea 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -18,6 +18,10 @@
 */
 -->
 <resources>
+    <!-- The width that is used when creating thumbnails of applications. -->
+    <dimen name="thumbnail_width">200dp</dimen>
+    <!-- The height that is used when creating thumbnails of applications. -->
+    <dimen name="thumbnail_height">177dp</dimen>
     <!-- The maximum number of action buttons that should be permitted within
          an action bar/action mode. This will be used to determine how many
          showAsAction="ifRoom" items can fit. "always" items can override this. -->
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c47a3ac..46c58e3 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"กำลังส่ง…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"รับสายหรือไม่"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 006fa63..946c0e7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Ipinapadala..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ilunsad ang Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Tanggapin ang tawag?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c13c520..9aa2df3 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Gönderiliyor…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Çağrı kabul edilsin mi?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 0ad2da2..4a1a0bc 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"Надсилання…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустити веб-переглядач?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Прийняти виклик?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 192c1dc..148713237 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Giám sát vị trí thực của bạn."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Kết nối mạng"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Truy cập các tính năng mạng khác nhau."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Truy cập vào các thiết bị và mạng thông qua Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Mạng tầm ngắn"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Truy cập vào các thiết bị thông qua mạng tầm ngắn như NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Cài đặt âm thanh"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Thay đổi cài đặt âm thanh."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Ảnh hưởng tới pin"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Sử dụng các tính năng có thể làm nhanh hết pin."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Lịch"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Truy cập trực tiếp vào lịch và sự kiện."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Đọc từ điển người dùng"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Đọc các từ trong từ điển người dùng."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Ghi từ điển người dùng"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Thêm từ vào từ điển người dùng."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Dấu trang và lịch sử"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Truy cập trực tiếp vào dấu trang và lịch sử trình duyệt."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Báo thức"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Cho phép ứng dụng đọc nội dung của bộ lưu trữ USB, bộ lưu trữ này có thể bao gồm ảnh và đa phương tiện."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Cho phép ứng dụng đọc nội dung của thẻ SD, thẻ này có thể bao gồm ảnh và đa phương tiện."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"sửa đổi hoặc xóa nội dung của bộ lưu trữ USB của bạn"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"sửa đổi hoặc xóa nội dung của thẻ SD của bạn"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Cho phép ứng dụng ghi vào bộ lưu trữ USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Cho phép ứng dụng ghi vào thẻ SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Xong"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"MỚI: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Được cung cấp bởi <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Bộ nhớ dung lượng lớn USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB đã kết nối"</string>
@@ -1321,8 +1311,7 @@
     <string name="sending" msgid="3245653681008218030">"Đang gửi…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Khởi chạy trình duyệt?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Chấp nhận cuộc gọi?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Chỉ một lần"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index d61d513..85f83f7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -168,12 +168,9 @@
     <string name="permgrouplab_messages" msgid="7521249148445456662">"您的信息"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"读写短信、电子邮件和其他消息。"</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"您的个人信息"</string>
-    <!-- no translation found for permgroupdesc_personalInfo (8426453129788861338) -->
-    <skip />
-    <!-- no translation found for permgrouplab_socialInfo (5799096623412043791) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_socialInfo (7129842457611643493) -->
-    <skip />
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"直接访问您存储在名片上的信息。"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交信息"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接访问与您的联系人和社交关系相关的信息。"</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"您的位置"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"监视您的实际位置。"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"网络通信"</string>
@@ -186,18 +183,12 @@
     <skip />
     <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
     <skip />
-    <!-- no translation found for permgrouplab_audioSettings (8329261670151871235) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_audioSettings (2641515403347568130) -->
-    <skip />
-    <!-- no translation found for permgrouplab_affectsBattery (6209246653424798033) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_affectsBattery (6441275320638916947) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (5777534316982184416) -->
-    <skip />
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"音频设置"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"更改音频设置。"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"影响电池的使用"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"使用耗电量较大的功能。"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"直接访问日历和活动。"</string>
     <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
     <skip />
     <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
@@ -206,46 +197,26 @@
     <skip />
     <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
     <skip />
-    <!-- no translation found for permgrouplab_bookmarks (1949519673103968229) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bookmarks (4169771606257963028) -->
-    <skip />
-    <!-- no translation found for permgrouplab_deviceAlarms (6117704629728824101) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_deviceAlarms (4769356362251641175) -->
-    <skip />
-    <!-- no translation found for permgrouplab_voicemail (4162237145027592133) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_voicemail (2498403969862951393) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (7106618286905738408) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (2933667372289567714) -->
-    <skip />
-    <!-- no translation found for permgrouplab_appInfo (8028789762634147725) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_appInfo (3950378538049625907) -->
-    <skip />
-    <!-- no translation found for permgrouplab_wallpaper (3850280158041175998) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_wallpaper (5630417854750540154) -->
-    <skip />
-    <!-- no translation found for permgrouplab_systemClock (406535759236612992) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_systemClock (3944359833624094992) -->
-    <skip />
-    <!-- no translation found for permgrouplab_statusBar (2095862568113945398) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_statusBar (6242593432226807171) -->
-    <skip />
-    <!-- no translation found for permgrouplab_syncSettings (3341990986147826541) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_syncSettings (7603195265129031797) -->
-    <skip />
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"书签和历史记录"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接访问书签和浏览器历史记录。"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"闹钟"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"设置闹钟。"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"语音信箱"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"直接访问语音信箱。"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"麦克风"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"直接访问麦克风以录制音频。"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"相机"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"直接访问相机以拍摄图片或视频。"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"您的应用信息"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"能够影响设备上其他应用的行为。"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"壁纸"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"更改设备的壁纸设置。"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"时钟"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"更改设备的时间或时区。"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"状态栏"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"更改设备的状态栏设置。"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"同步设置"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"访问同步设置。"</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帐户"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"访问可用的帐户。"</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"硬件控件"</string>
@@ -256,10 +227,8 @@
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"对系统进行低级访问和控制。"</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"开发工具"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"只有应用开发人员才需要的功能。"</string>
-    <!-- no translation found for permgrouplab_display (4279909676036402636) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_display (6051002031933013714) -->
-    <skip />
+    <string name="permgrouplab_display" msgid="4279909676036402636">"其他应用的用户界面"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"影响其他应用的用户界面。"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"存储"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"访问 USB 存储设备。"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"访问 SD 卡。"</string>
@@ -779,8 +748,7 @@
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"手机中无 SIM 卡"</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"请插入 SIM 卡"</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM 卡缺失或无法读取。请插入 SIM 卡。"</string>
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM 卡无法使用。"</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"您的 SIM 卡已永久停用。"\n"请与您的无线服务提供商联系,以便重新获取一张 SIM 卡。"</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"“上一曲目”按钮"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"“下一曲目”按钮"</string>
@@ -1353,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"正在发送..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"要接听电话吗?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 28d7cab..8d1a950 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1321,7 +1321,7 @@
     <string name="sending" msgid="3245653681008218030">"傳送中..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"接聽電話嗎?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
     <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
     <skip />
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 8010962..4edb7b2 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -175,28 +175,20 @@
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Gada indawo yakho yokuhlala"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Uxhumano lwenethiwekhi"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Finyelela kokuqukethwe inethiwekhi okuhlukahlukee."</string>
-    <!-- no translation found for permgrouplab_bluetoothNetwork (1585403544162128109) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_bluetoothNetwork (5625288577164282391) -->
-    <skip />
-    <!-- no translation found for permgrouplab_shortrangeNetwork (130808676377486118) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_shortrangeNetwork (1884069062653436007) -->
-    <skip />
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"I-Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Finyelela amadivayisi namanethiwekhi nge-Bluetooth."</string>
+    <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Amanethiwekhi ebanga elifushane"</string>
+    <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Finyelela amadivayisi ngamanethiwekhi ebanga elifushane njenge-NFC."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Izilungiselelo zomsindo"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Shintsha izilungiselelo zomsindo."</string>
     <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Ithinta ibhethri"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Sebenzisa izici ezingakhipha ngokushesha ibhethri."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Ikhalenda"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Ukufinyelela okuqondile kukhalenda nezehlakalo."</string>
-    <!-- no translation found for permgrouplab_dictionary (4148597128843641379) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_dictionary (7921166355964764490) -->
-    <skip />
-    <!-- no translation found for permgrouplab_writeDictionary (8090237702432576788) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_writeDictionary (2711561994497361646) -->
-    <skip />
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Funda isichzamazwi somsebenzisi"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Funda amagama kusichazamazwi somsebenzisi."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Bhala isichazamazwi somsebenzisi"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Engeza amagama kusichazamazwi somsebenzisi."</string>
     <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Amabhukhimakhi nomlando"</string>
     <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ukufinyelela okuqondile kumlando wamabhukimakhi nesiphequluli."</string>
     <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"I-alamu"</string>
@@ -569,8 +561,7 @@
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3530894470637667917">"Ivumela uhlelo lokusebenza ukuthi lufunde okuqukethwe kwi-USB, okungabandakanya izithombe kanye nezingosi yezindaba."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2555811422562526606">"Ivumela uhlelo lokusebenza ukuthi lufunde okuqukethwe ikhadi le-SD, okungabandakanya izithombe kanye nengosi yezindaba."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"guqula noma ususe okuqukethwe kwakho okugciniwe okufinyeleleka nge-USB"</string>
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"shintsha noma ususe okuqukethwe ekhadini lakho le-SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Ivumela insiza ukuthi ibhalele ekulondolozweni kwe-USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ivumela insiza ukuthi ibhalele ekhadini le-SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"guqula/susa okuqukethwe kwisitoreji semidiya yangaphakathi"</string>
@@ -1090,8 +1081,7 @@
     <string name="date_time_set" msgid="5777075614321087758">"Hlela"</string>
     <string name="date_time_done" msgid="2507683751759308828">"Kwenziwe"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"OKUSHA: "</font></string>
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
+    <string name="perms_description_app" msgid="5139836143293299417">"Inikelwe yi-<xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="no_permissions" msgid="7283357728219338112">"Ayikho imvume edingekayo"</string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Isitoreji Esikhulu se-USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"I-USB ixhunyiwe"</string>
@@ -1321,8 +1311,7 @@
     <string name="sending" msgid="3245653681008218030">"Iyathumela..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Qala Isiphequluli?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Amukela ucingo?"</string>
-    <!-- no translation found for activity_resolver_use_always (4167356512478150080) -->
+    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
     <skip />
-    <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
-    <skip />
+    <string name="activity_resolver_use_once" msgid="405646673463328329">"Kanye nje"</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 484de0d..a4d9e14 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2461,8 +2461,10 @@
         <attr name="accessibilityFlags">
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#DEFAULT} -->
             <flag name="flagDefault" value="0x00000001" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#INCLUDE_NOT_IMPORTANT_VIEWS} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} -->
             <flag name="flagIncludeNotImportantViews" value="0x00000002" />
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} -->
+            <flag name="flagRequestTouchExplorationMode" value="0x00000004" />
         </attr>
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. This setting cannot be changed at runtime. -->
@@ -2470,8 +2472,6 @@
         <!-- Flag whether the accessibility service wants to be able to retrieve the
              active window content. This setting cannot be changed at runtime. -->
         <attr name="canRetrieveWindowContent" format="boolean" />
-        <!-- Flag whether the accessibility service can handle gesrures and wants such. -->
-        <attr name="canHandleGestures" format="boolean" />
         <!-- Short description of the accessibility serivce purpose or behavior.-->
         <attr name="description" />
     </declare-styleable>
@@ -3685,8 +3685,8 @@
         <attr name="internalMaxWidth" format="dimension" />
         <!-- @hide The layout of the number picker. -->
         <attr name="internalLayout" />
-        <!-- @hide The minimal move distance of a swipe to be considered a fling. -->
-       <attr name="minFlingDistance" format="dimension" />
+        <!-- @hide The drawable for pressed virtual (increment/decrement) buttons. -->
+        <attr name="virtualButtonPressedDrawable" format="reference"/>
     </declare-styleable>
 
     <declare-styleable name="TimePicker">
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index e23e3c6..41f902f 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -181,5 +181,8 @@
     <!-- A really bright Holo shade of blue -->
     <color name="holo_blue_bright">#ff00ddff</color>
 
+    <drawable name="notification_template_icon_bg">#3333B5E5</drawable>
+    <drawable name="notification_template_icon_low_bg">#0cffffff</drawable>
+
 </resources>
 
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f812822..734151b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -19,9 +19,9 @@
 -->
 <resources>
     <!-- The width that is used when creating thumbnails of applications. -->
-    <dimen name="thumbnail_width">120dp</dimen>
+    <dimen name="thumbnail_width">164dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
-    <dimen name="thumbnail_height">120dp</dimen>
+    <dimen name="thumbnail_height">145dp</dimen>
     <!-- The standard size (both width and height) of an application icon that
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 98c19cf..1d17cd8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -208,6 +208,7 @@
   <java-symbol type="id" name="inbox_text2" />
   <java-symbol type="id" name="inbox_text3" />
   <java-symbol type="id" name="inbox_text4" />
+  <java-symbol type="id" name="status_bar_latest_event_content" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -979,6 +980,7 @@
   <java-symbol type="drawable" name="jog_tab_target_gray" />
   <java-symbol type="drawable" name="picture_emergency" />
   <java-symbol type="drawable" name="platlogo" />
+  <java-symbol type="drawable" name="platlogo_alt" />
   <java-symbol type="drawable" name="stat_notify_sync_error" />
   <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
   <java-symbol type="drawable" name="stat_sys_gps_on" />
@@ -1004,6 +1006,9 @@
   <java-symbol type="drawable" name="ic_lockscreen_unlock" />
   <java-symbol type="drawable" name="ic_lockscreen_search" />
   <java-symbol type="drawable" name="notification_bg" />
+  <java-symbol type="drawable" name="notification_bg_low" />
+  <java-symbol type="drawable" name="notification_template_icon_bg" />
+  <java-symbol type="drawable" name="notification_template_icon_low_bg" />
 
   <java-symbol type="layout" name="action_bar_home" />
   <java-symbol type="layout" name="action_bar_title_item" />
@@ -1091,6 +1096,7 @@
   <java-symbol type="layout" name="zoom_controls" />
   <java-symbol type="layout" name="zoom_magnify" />
   <java-symbol type="layout" name="notification_action" />
+  <java-symbol type="layout" name="notification_action_tombstone" />
   <java-symbol type="layout" name="notification_intruder_content" />
   <java-symbol type="layout" name="notification_template_base" />
   <java-symbol type="layout" name="notification_template_big_base" />
@@ -3600,7 +3606,6 @@
   <public type="attr" name="parentActivityName" />
 
   <public type="attr" name="importantForAccessibility"/>
-  <public type="attr" name="canHandleGestures"/>
 
   <public type="attr" name="permissionGroupFlags"/>
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 18ee2f8..2b34dab 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1649,9 +1649,9 @@
         <item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
         <item name="android:selectionDividerHeight">2dip</item>
         <item name="android:selectionDividersDistance">48dip</item>
-        <item name="android:internalMinWidth">48dip</item>
+        <item name="android:internalMinWidth">64dip</item>
         <item name="android:internalMaxHeight">180dip</item>
-        <item name="android:minFlingDistance">150dip</item>
+        <item name="virtualButtonPressedDrawable">?android:attr/selectableItemBackground</item>
     </style>
 
     <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 19aa77b..f7b0cd0 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -246,9 +246,7 @@
 
         initializeNetworkStates();
 
-        mWifiManager.setWifiEnabled(true);
         log("Clear Wifi before we start the test.");
-        sleep(SHORT_TIMEOUT);
         removeConfiguredNetworksAndDisableWifi();
         mWifiRegexs = mCM.getTetherableWifiRegexs();
      }
@@ -645,6 +643,11 @@
      */
     public boolean disconnectAP() {
         // remove saved networks
+        if (!mWifiManager.isWifiEnabled()) {
+            log("Enabled wifi before remove configured networks");
+            mWifiManager.setWifiEnabled(true);
+            sleep(SHORT_TIMEOUT);
+        }
         List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
         log("size of wifiConfigList: " + wifiConfigList.size());
         for (WifiConfiguration wifiConfig: wifiConfigList) {
diff --git a/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java b/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java
index 0a0152b..1f762fd 100644
--- a/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java
+++ b/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java
@@ -66,6 +66,17 @@
         }
     }
 
+    @MediumTest
+    public void testConstructor_OffsetLengthOverflow_Fail() throws Exception {
+        try {
+        InputStream is = new LimitedLengthInputStream(mTestStream1, Long.MAX_VALUE - 1,
+                Long.MAX_VALUE - 1);
+            fail("Should fail when offset + length is > Long.MAX_VALUE");
+        } catch (IOException e) {
+            // success
+        }
+    }
+
     private void checkReadBytesWithOffsetAndLength_WithString1(int offset, int length)
             throws Exception {
         byte[] temp = new byte[TEST_STRING1.length];
@@ -182,5 +193,4 @@
     public void testSingleByteRead_NonZeroOffset_FullLength_Success() throws Exception {
         checkSingleByteRead_WithString1(3, TEST_STRING1.length - 3);
     }
-
 }
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
index 94d1cb6..95f0e67 100644
--- a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
@@ -187,12 +187,12 @@
             rotate.combineActive(reader, new Writer() {
                 public void write(OutputStream out) throws IOException {
                     new DataOutputStream(out).writeUTF("bar");
-                    throw new ProtocolException("yikes");
+                    throw new NullPointerException("yikes");
                 }
             }, currentTime);
 
             fail("woah, somehow able to write exception");
-        } catch (ProtocolException e) {
+        } catch (IOException e) {
             // expected from above
         }
 
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 13f2480..16a98d3 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -142,6 +142,8 @@
     Roboto-Bold.ttf \
     Roboto-Italic.ttf \
     Roboto-BoldItalic.ttf \
+    Roboto-Light.ttf \
+    Roboto-LightItalic.ttf \
     DroidNaskh-Regular.ttf \
     DroidNaskh-Regular-SystemUI.ttf \
     DroidSansDevanagari-Regular.ttf \
diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf
new file mode 100644
index 0000000..b50399e
--- /dev/null
+++ b/data/fonts/Roboto-Light.ttf
Binary files differ
diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf
new file mode 100644
index 0000000..a1fdc8d
--- /dev/null
+++ b/data/fonts/Roboto-LightItalic.ttf
Binary files differ
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 7a84df6..397ccda 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -24,6 +24,8 @@
     Roboto-Bold.ttf \
     Roboto-Italic.ttf \
     Roboto-BoldItalic.ttf \
+    Roboto-Light.ttf \
+    Roboto-LightItalic.ttf \
     DroidNaskh-Regular.ttf \
     DroidNaskh-Regular-SystemUI.ttf \
     DroidSansDevanagari-Regular.ttf \
diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml
index d2fe546..95c4f70 100644
--- a/data/fonts/system_fonts.xml
+++ b/data/fonts/system_fonts.xml
@@ -36,6 +36,16 @@
 
     <family>
         <nameset>
+            <name>sans-serif-light</name>
+        </nameset>
+        <fileset>
+            <file>Roboto-Light.ttf</file>
+            <file>Roboto-LightItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
             <name>serif</name>
             <name>times</name>
             <name>times new roman</name>
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 28914ce..060f526 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -724,6 +724,9 @@
         }
         return rs.mElement_MATRIX_4X4;
     }
+
+    /** @deprecated use MATRIX_4X4
+    */
     public static Element MATRIX4X4(RenderScript rs) {
         return MATRIX_4X4(rs);
     }
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index 61793171..42b508b 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
 import android.util.TypedValue;
 
 /**
+ * @deprecated in API 16
  * FileA3D allows users to load Renderscript objects from files
  * or resources stored on disk. It could be used to load items
  * such as 3D geometry data converted to a Renderscript format from
@@ -41,16 +42,19 @@
 public class FileA3D extends BaseObj {
 
     /**
+    * @deprecated in API 16
     * Specifies what renderscript object type is contained within
     * the FileA3D IndexEntry
     **/
     public enum EntryType {
 
         /**
+        * @deprecated in API 16
         * Unknown or or invalid object, nothing will be loaded
         **/
         UNKNOWN (0),
         /**
+        * @deprecated in API 16
         * Renderscript Mesh object
         **/
         MESH (1);
@@ -66,6 +70,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * IndexEntry contains information about one of the Renderscript
     * objects inside the file's index. It could be used to query the
     * object's type and also name and load the object itself if
@@ -80,6 +85,7 @@
         BaseObj mLoadedObj;
 
         /**
+        * @deprecated in API 16
         * Returns the name of a renderscript object the index entry
         * describes
         *
@@ -92,6 +98,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Returns the type of a renderscript object the index entry
         * describes
         * @return type of a renderscript object the index entry
@@ -102,6 +109,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Used to load the object described by the index entry
         * @return base renderscript object described by the entry
         */
@@ -112,6 +120,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Used to load the mesh described by the index entry, object
         * described by the index entry must be a renderscript mesh
         *
@@ -182,6 +191,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Returns the number of objects stored inside the a3d file
     *
     * @return the number of objects stored inside the a3d file
@@ -194,6 +204,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Returns an index entry from the list of all objects inside
     * FileA3D
     *
@@ -209,6 +220,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Creates a FileA3D object from an asset stored on disk
     *
     * @param rs Context to which the object will belong.
@@ -230,6 +242,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Creates a FileA3D object from a file stored on disk
     *
     * @param rs Context to which the object will belong.
@@ -249,6 +262,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Creates a FileA3D object from a file stored on disk
     *
     * @param rs Context to which the object will belong.
@@ -261,6 +275,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Creates a FileA3D object from an application resource
     *
     * @param rs Context to which the object will belong.
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index 18dacac..8a49abb 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
 import android.util.TypedValue;
 
 /**
+ * @deprecated in API 16
  * <p>This class gives users a simple way to draw hardware accelerated text. 
  * Internally, the glyphs are rendered using the Freetype library and an internal cache of
  * rendered glyph bitmaps is maintained. Each font object represents a combination of a typeface,
@@ -71,10 +72,25 @@
 
     private static Map<String, FontFamily> sFontFamilyMap;
 
+    /**
+     * @deprecated in API 16
+     */
     public enum Style {
+        /**
+         * @deprecated in API 16
+         */
         NORMAL,
+        /**
+         * @deprecated in API 16
+         */
         BOLD,
+        /**
+         * @deprecated in API 16
+         */
         ITALIC,
+        /**
+         * @deprecated in API 16
+         */
         BOLD_ITALIC;
     }
 
@@ -139,6 +155,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Takes a specific file name as an argument
      */
     static public Font createFromFile(RenderScript rs, Resources res, String path, float pointSize) {
@@ -154,10 +171,16 @@
         return rsFont;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     static public Font createFromFile(RenderScript rs, Resources res, File path, float pointSize) {
         return createFromFile(rs, res, path.getAbsolutePath(), pointSize);
     }
 
+    /**
+     * @deprecated in API 16
+     */
     static public Font createFromAsset(RenderScript rs, Resources res, String path, float pointSize) {
         rs.validate();
         AssetManager mgr = res.getAssets();
@@ -171,6 +194,9 @@
         return rsFont;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     static public Font createFromResource(RenderScript rs, Resources res, int id, float pointSize) {
         String name = "R." + Integer.toString(id);
 
@@ -200,6 +226,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Accepts one of the following family names as an argument
      * and will attempt to produce the best match with a system font:
      *
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index ffbb41d..7210513 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 import android.util.Log;
 
 /**
+ * @deprecated in API 16
  * <p>This class is a container for geometric data displayed with
  * Renderscript. Internally, a mesh is a collection of allocations that
  * represent vertex data (positions, normals, texture
@@ -40,33 +41,40 @@
 public class Mesh extends BaseObj {
 
     /**
+    * @deprecated in API 16
     * Describes the way mesh vertex data is interpreted when rendering
     *
     **/
     public enum Primitive {
         /**
+        * @deprecated in API 16
         * Vertex data will be rendered as a series of points
         */
         POINT (0),
         /**
+        * @deprecated in API 16
         * Vertex pairs will be rendered as lines
         */
         LINE (1),
         /**
+        * @deprecated in API 16
         * Vertex data will be rendered as a connected line strip
         */
         LINE_STRIP (2),
         /**
+        * @deprecated in API 16
         * Vertices will be rendered as individual triangles
         */
         TRIANGLE (3),
         /**
+        * @deprecated in API 16
         * Vertices will be rendered as a connected triangle strip
         * defined by the first three vertices with each additional
         * triangle defined by a new vertex
         */
         TRIANGLE_STRIP (4),
         /**
+        * @deprecated in API 16
         * Vertices will be rendered as a sequence of triangles that all
         * share first vertex as the origin
         */
@@ -87,6 +95,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * @return number of allocations containing vertex data
     *
     **/
@@ -97,6 +106,7 @@
         return mVertexBuffers.length;
     }
     /**
+    * @deprecated in API 16
     * @param slot index in the list of allocations to return
     * @return vertex data allocation at the given index
     *
@@ -106,6 +116,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * @return number of primitives or index sets in the mesh
     *
     **/
@@ -117,6 +128,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * @param slot locaton within the list of index set allocation
     * @return allocation containing primtive index data or null if
     *         the index data is not specified explicitly
@@ -126,6 +138,7 @@
         return mIndexBuffers[slot];
     }
     /**
+    * @deprecated in API 16
     * @param slot locaiton within the list of index set primitives
     * @return index set primitive type
     *
@@ -168,6 +181,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Mesh builder object. It starts empty and requires you to
     * add the types necessary to create vertex and index
     * allocations.
@@ -190,6 +204,7 @@
         Vector mIndexTypes;
 
         /**
+        * @deprecated in API 16
         * Creates builder object
         * @param rs Context to which the mesh will belong.
         * @param usage specifies how the mesh allocations are to be
@@ -205,6 +220,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * @return internal index of the last vertex buffer type added to
         *         builder
         **/
@@ -213,6 +229,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * @return internal index of the last index set added to the
         *         builder
         **/
@@ -221,6 +238,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds a vertex data type to the builder object
         *
         * @param t type of the vertex data allocation to be created
@@ -240,6 +258,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds a vertex data type to the builder object
         *
         * @param e element describing the vertex data layout
@@ -261,6 +280,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds an index set data type to the builder object
         *
         * @param t type of the index set data, could be null
@@ -279,6 +299,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds an index set primitive type to the builder object
         *
         * @param p primitive type
@@ -296,6 +317,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds an index set data type to the builder object
         *
         * @param e element describing the index set data layout
@@ -321,6 +343,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Create a Mesh object from the current state of the builder
         *
         **/
@@ -373,6 +396,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Mesh builder object. It starts empty and requires the user to
     * add all the vertex and index allocations that comprise the
     * mesh
@@ -391,6 +415,9 @@
 
         Vector mIndexTypes;
 
+        /**
+        * @deprecated in API 16
+        **/
         public AllocationBuilder(RenderScript rs) {
             mRS = rs;
             mVertexTypeCount = 0;
@@ -399,6 +426,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * @return internal index of the last vertex buffer type added to
         *         builder
         **/
@@ -407,6 +435,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * @return internal index of the last index set added to the
         *         builder
         **/
@@ -415,6 +444,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds an allocation containing vertex buffer data to the
         * builder
         *
@@ -434,6 +464,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds an allocation containing index buffer data and index type
         * to the builder
         *
@@ -451,6 +482,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds an index set type to the builder
         *
         * @param p index set primitive type
@@ -466,6 +498,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Create a Mesh object from the current state of the builder
         *
         **/
@@ -507,6 +540,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Builder that allows creation of a mesh object point by point
     * and triangle by triangle
     *
@@ -533,11 +567,21 @@
         int mVtxSize;
         int mFlags;
 
+        /**
+        * @deprecated in API 16
+        **/
         public static final int COLOR = 0x0001;
+        /**
+        * @deprecated in API 16
+        **/
         public static final int NORMAL = 0x0002;
+        /**
+        * @deprecated in API 16
+        **/
         public static final int TEXTURE_0 = 0x0100;
 
         /**
+        * @deprecated in API 16
         * @param rs Context to which the mesh will belong.
         * @param vtxSize specifies whether the vertex is a float2 or
         *                float3
@@ -593,6 +637,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds a float2 vertex to the mesh
         *
         * @param x position x
@@ -613,6 +658,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds a float3 vertex to the mesh
         *
         * @param x position x
@@ -636,6 +682,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Sets the texture coordinate for the vertices that are added after this method call.
         *
         * @param s texture coordinate s
@@ -653,6 +700,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Sets the normal vector for the vertices that are added after this method call.
         *
         * @param x normal vector x
@@ -672,6 +720,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Sets the color for the vertices that are added after this method call.
         *
         * @param r red component
@@ -693,6 +742,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Adds a new triangle to the mesh builder
         *
         * @param idx1 index of the first vertex in the triangle
@@ -719,6 +769,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Creates the mesh object from the current state of the builder
         *
         * @param uploadToBufferObject specifies whether the vertex data
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index fa6e2d4..69968ac 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -21,6 +21,7 @@
 
 
 /**
+ * @deprecated in API 16
  * <p>The Renderscript fragment program, also known as fragment shader is responsible
  * for manipulating pixel data in a user defined way. It's constructed from a GLSL
  * shader string containing the program body, textures inputs, and a Type object
@@ -41,8 +42,12 @@
         super(id, rs);
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static class Builder extends BaseProgramBuilder {
         /**
+         * @deprecated in API 16
          * Create a builder object.
          *
          * @param rs Context to which the program will belong.
@@ -52,6 +57,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Creates ProgramFragment from the current state of the builder
          *
          * @return  ProgramFragment
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
index 14f10f1..848c5a3 100644
--- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 
 
 /**
+ * @deprecated in API 16
  * <p>ProgramFragmentFixedFunction is a helper class that provides
  * a way to make a simple fragment shader without writing any
  * GLSL code. This class allows for display of constant color, interpolated
@@ -34,11 +35,15 @@
     }
 
     static class InternalBuilder extends BaseProgramBuilder {
+        /**
+         * @deprecated in API 16
+         */
         public InternalBuilder(RenderScript rs) {
             super(rs);
         }
 
         /**
+         * @deprecated in API 16
          * Creates ProgramFragmentFixedFunction from the current state
          * of the builder
          *
@@ -75,7 +80,13 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static class Builder {
+        /**
+         * @deprecated in API 16
+         */
         public static final int MAX_TEXTURE = 2;
         int mNumTextures;
         boolean mPointSpriteEnable;
@@ -84,13 +95,23 @@
         RenderScript mRS;
 
         /**
+         * @deprecated in API 16
          * EnvMode describes how textures are combined with the existing
          * color in the fixed function fragment shader
          *
          **/
         public enum EnvMode {
+            /**
+             * @deprecated in API 16
+             **/
             REPLACE (1),
+            /**
+             * @deprecated in API 16
+             **/
             MODULATE (2),
+            /**
+             * @deprecated in API 16
+             **/
             DECAL (3);
 
             int mID;
@@ -100,14 +121,27 @@
         }
 
         /**
+         * @deprecated in API 16
          * Format describes the pixel format of textures in the fixed
          * function fragment shader and how they are sampled
          *
          **/
         public enum Format {
+            /**
+             * @deprecated in API 16
+             **/
             ALPHA (1),
+            /**
+             * @deprecated in API 16
+             **/
             LUMINANCE_ALPHA (2),
+            /**
+             * @deprecated in API 16
+             **/
             RGB (3),
+            /**
+             * @deprecated in API 16
+             **/
             RGBA (4);
 
             int mID;
@@ -191,6 +225,7 @@
         }
 
         /**
+         * @deprecated
          * Creates a builder for fixed function fragment program
          *
          * @param rs Context to which the program will belong.
@@ -202,6 +237,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Adds a texture to be fetched as part of the fixed function
          * fragment program
          *
@@ -224,6 +260,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Specifies whether the texture coordinate passed from the
          * vertex program is replaced with an openGL internal point
          * sprite texture coordinate
@@ -235,6 +272,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Specifies whether the varying color passed from the vertex
          * program or the constant color set on the fragment program is
          * used in the final color calculation in the fixed function
@@ -247,6 +285,7 @@
         }
 
         /**
+         * @deprecated in API 16
         * Creates the fixed function fragment program from the current
         * state of the builder.
         *
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index e40751f..c44521b 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -21,14 +21,27 @@
 
 
 /**
+ * @deprecated in API 16
  * Program raster is primarily used to specify whether point sprites are enabled and to control
  * the culling mode. By default, back faces are culled.
  **/
 public class ProgramRaster extends BaseObj {
 
+    /**
+     * @deprecated in API 16
+     **/
     public enum CullMode {
+        /**
+         * @deprecated in API 16
+         **/
         BACK (0),
+        /**
+         * @deprecated in API 16
+         **/
         FRONT (1),
+        /**
+         * @deprecated in API 16
+         **/
         NONE (2);
 
         int mID;
@@ -48,6 +61,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Specifies whether vertices are rendered as screen aligned
      * elements of a specified size
      * @return whether point sprites are enabled
@@ -57,6 +71,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Specifies how triangles are culled based on their orientation
      * @return cull mode
      */
@@ -64,6 +79,9 @@
         return mCullMode;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static ProgramRaster CULL_BACK(RenderScript rs) {
         if(rs.mProgramRaster_CULL_BACK == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -73,6 +91,9 @@
         return rs.mProgramRaster_CULL_BACK;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static ProgramRaster CULL_FRONT(RenderScript rs) {
         if(rs.mProgramRaster_CULL_FRONT == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -82,6 +103,9 @@
         return rs.mProgramRaster_CULL_FRONT;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static ProgramRaster CULL_NONE(RenderScript rs) {
         if(rs.mProgramRaster_CULL_NONE == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -91,27 +115,42 @@
         return rs.mProgramRaster_CULL_NONE;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static class Builder {
         RenderScript mRS;
         boolean mPointSprite;
         CullMode mCullMode;
 
+        /**
+         * @deprecated in API 16
+         */
         public Builder(RenderScript rs) {
             mRS = rs;
             mPointSprite = false;
             mCullMode = CullMode.BACK;
         }
 
+        /**
+         * @deprecated in API 16
+         */
         public Builder setPointSpriteEnabled(boolean enable) {
             mPointSprite = enable;
             return this;
         }
 
+        /**
+         * @deprecated in API 16
+         */
         public Builder setCullMode(CullMode m) {
             mCullMode = m;
             return this;
         }
 
+        /**
+         * @deprecated in API 16
+         */
         public ProgramRaster create() {
             mRS.validate();
             int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 74d666b..2bd5124 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -43,6 +43,7 @@
 
 
 /**
+ * @deprecated in API 16
  * ProgramVertex, also know as a vertex shader, describes a
  * stage in the graphics pipeline responsible for manipulating
  * geometric data in a user-defined way.
@@ -55,6 +56,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * @return number of input attribute elements
      */
     public int getInputCount() {
@@ -62,6 +64,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * @param slot location of the input to return
      * @return input attribute element
      */
@@ -73,6 +76,7 @@
     }
 
     /**
+    * @deprecated in API 16
     * Builder class for creating ProgramVertex objects.
     * The builder starts empty and the user must minimally provide
     * the GLSL shader code, and the varying inputs. Constant, or
@@ -82,6 +86,7 @@
     **/
     public static class Builder extends BaseProgramBuilder {
         /**
+         * @deprecated in API 16
          * Create a builder object.
          *
          * @param rs Context to which the program will belong.
@@ -91,6 +96,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Add varying inputs to the program
          *
          * @param e element describing the layout of the varying input
@@ -110,6 +116,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Creates ProgramVertex from the current state of the builder
          *
          * @return  ProgramVertex
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
index 54f21b8..88cade4 100644
--- a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
 
 
 /**
+ * @deprecated in API 16
  * ProgramVertexFixedFunction is a helper class that provides a
  * simple way to create a fixed function emulation vertex shader
  * without writing any GLSL code.
@@ -34,6 +35,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Binds the constant buffer containing fixed function emulation
      * matrices
      *
@@ -45,10 +47,16 @@
     }
 
     static class InternalBuilder extends BaseProgramBuilder {
+        /**
+         * @deprecated in API 16
+         */
         public InternalBuilder(RenderScript rs) {
             super(rs);
         }
 
+        /**
+         * @deprecated in API 16
+         */
         public InternalBuilder addInput(Element e) throws IllegalStateException {
             // Should check for consistant and non-conflicting names...
             if(mInputCount >= MAX_INPUT) {
@@ -62,6 +70,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Creates ProgramVertexFixedFunction from the current state of
          * the builder
          *
@@ -98,12 +107,16 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static class Builder {
         boolean mTextureMatrixEnable;
         String mShader;
         RenderScript mRS;
 
         /**
+         * @deprecated in API 16
          * Creates a builder for fixed function vertex program
          *
          * @param rs Context to which the program will belong.
@@ -113,6 +126,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Specifies whether texture matrix calculations are to be added
          * to the shader
          *
@@ -153,6 +167,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Creates ProgramVertexFixedFunction from the current state of
          * the builder
          *
@@ -177,6 +192,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Helper class to store modelview, projection and texture
      * matrices for ProgramVertexFixedFunction
      *
@@ -197,6 +213,7 @@
         private FieldPacker mIOBuffer;
 
         /**
+        * @deprecated in API 16
         * Creates a buffer to store fixed function emulation matrices
         *
         * @param rs Context to which the allocation will belong.
@@ -216,6 +233,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Forces deallocation of memory backing the contant matrices.
         * Normally, this is unnecessary and will be garbage collected
         *
@@ -234,6 +252,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Sets the modelview matrix in the fixed function matrix buffer
         *
         * @param m modelview matrix
@@ -244,6 +263,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Sets the projection matrix in the fixed function matrix buffer
         *
         * @param m projection matrix
@@ -254,6 +274,7 @@
         }
 
         /**
+        * @deprecated in API 16
         * Sets the texture matrix in the fixed function matrix buffer.
         * Texture matrix must be enabled in the
         * ProgramVertexFixedFunction builder for the shader to utilize
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 6756fd0..506f1af 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
 import android.view.SurfaceView;
 
 /**
+ * @deprecated in API 16
  * The Surface View for a graphics renderscript (RenderScriptGL) to draw on.
  *
  * <div class="special reference">
@@ -43,6 +44,7 @@
     private RenderScriptGL mRS;
 
     /**
+     * @deprecated in API 16
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -54,6 +56,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -72,6 +75,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * This method is part of the SurfaceHolder.Callback interface, and is
      * not normally called or subclassed by clients of RSSurfaceView.
      */
@@ -80,6 +84,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * This method is part of the SurfaceHolder.Callback interface, and is
      * not normally called or subclassed by clients of RSSurfaceView.
      */
@@ -93,6 +98,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * This method is part of the SurfaceHolder.Callback interface, and is
      * not normally called or subclassed by clients of RSSurfaceView.
      */
@@ -105,6 +111,7 @@
     }
 
    /**
+     * @deprecated in API 16
      * Inform the view that the activity is paused. The owner of this view must
      * call this method when the activity is paused. Calling this method will
      * pause the rendering thread.
@@ -117,6 +124,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Inform the view that the activity is resumed. The owner of this view must
      * call this method when the activity is resumed. Calling this method will
      * recreate the OpenGL display and resume the rendering
@@ -129,12 +137,18 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public RenderScriptGL createRenderScriptGL(RenderScriptGL.SurfaceConfig sc) {
       RenderScriptGL rs = new RenderScriptGL(this.getContext(), sc);
         setRenderScriptGL(rs);
         return rs;
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public void destroyRenderScriptGL() {
         synchronized (this) {
             mRS.destroy();
@@ -142,10 +156,16 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public void setRenderScriptGL(RenderScriptGL rs) {
         mRS = rs;
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public RenderScriptGL getRenderScriptGL() {
         return mRS;
     }
diff --git a/graphics/java/android/renderscript/RSTextureView.java b/graphics/java/android/renderscript/RSTextureView.java
index 30b2f99..ed04000 100644
--- a/graphics/java/android/renderscript/RSTextureView.java
+++ b/graphics/java/android/renderscript/RSTextureView.java
@@ -29,6 +29,7 @@
 import android.view.TextureView;
 
 /**
+ * @deprecated in API 16
  * The Texture View for a graphics renderscript (RenderScriptGL)
  * to draw on.
  *
@@ -38,6 +39,7 @@
     private SurfaceTexture mSurfaceTexture;
 
     /**
+     * @deprecated in API 16
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -49,6 +51,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -64,6 +67,9 @@
         //android.util.Log.e("rs", "getSurfaceTextureListerner " + getSurfaceTextureListener());
     }
 
+    /**
+     * @deprecated in API 16
+     */
     @Override
     public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
         //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureAvailable");
@@ -74,6 +80,9 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     */
     @Override
     public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
         //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureSizeChanged");
@@ -84,6 +93,9 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     */
     @Override
     public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
         //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureDestroyed");
@@ -96,6 +108,9 @@
         return true;
     }
 
+    /**
+     * @deprecated in API 16
+     */
     @Override
     public void onSurfaceTextureUpdated(SurfaceTexture surface) {
         //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureUpdated");
@@ -103,6 +118,7 @@
     }
 
    /**
+     * @deprecated in API 16
      * Inform the view that the activity is paused. The owner of this view must
      * call this method when the activity is paused. Calling this method will
      * pause the rendering thread.
@@ -115,6 +131,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Inform the view that the activity is resumed. The owner of this view must
      * call this method when the activity is resumed. Calling this method will
      * recreate the OpenGL display and resume the rendering
@@ -128,6 +145,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Create a new RenderScriptGL object and attach it to the
      * TextureView if present.
      *
@@ -146,6 +164,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Destroy the RenderScriptGL object associated with this
      * TextureView.
      */
@@ -155,6 +174,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Set a new RenderScriptGL object.  This also will attach the
      * new object to the TextureView if present.
      *
@@ -168,6 +188,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Returns the previously set RenderScriptGL object.
      *
      * @return RenderScriptGL
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 1b2ac90..12c8102 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -29,6 +29,7 @@
 import android.view.SurfaceView;
 
 /**
+ * @deprecated in API 16
  * The Graphics derivitive of Renderscript.  Extends the basic context to add a
  * root script which is the display window for graphical output.  When the
  * system needs to update the display the currently bound root script will be
@@ -46,6 +47,7 @@
     int mHeight;
 
     /**
+     * @deprecated in API 16
      * Class which is used to describe a pixel format for a graphical buffer.
      * This is used to describe the intended format of the display surface.
      *
@@ -66,9 +68,15 @@
         int mSamplesPref    = 1;
         float mSamplesQ     = 1.f;
 
+        /**
+         * @deprecated in API 16
+         */
         public SurfaceConfig() {
         }
 
+        /**
+         * @deprecated in API 16
+         */
         public SurfaceConfig(SurfaceConfig sc) {
             mDepthMin = sc.mDepthMin;
             mDepthPref = sc.mDepthPref;
@@ -93,6 +101,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Set the per-component bit depth for color (red, green, blue).  This
          * configures the surface for an unsigned integer buffer type.
          *
@@ -106,6 +115,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Set the bit depth for alpha. This configures the surface for
          * an unsigned integer buffer type.
          *
@@ -119,6 +129,7 @@
         }
 
          /**
+         * @deprecated in API 16
          * Set the bit depth for the depth buffer. This configures the
          * surface for an unsigned integer buffer type.  If a minimum of 0
          * is specified then its possible no depth buffer will be
@@ -134,6 +145,7 @@
         }
 
         /**
+         * @deprecated in API 16
          * Configure the multisample rendering.
          *
          * @param minimum The required number of samples, must be at least 1.
@@ -157,6 +169,7 @@
     SurfaceConfig mSurfaceConfig;
 
     /**
+     * @deprecated in API 16
      * Construct a new RenderScriptGL context.
      *
      * @param ctx The context.
@@ -187,6 +200,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Bind an os surface
      *
      *
@@ -206,6 +220,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Bind an os surface
      *
      * @param w
@@ -222,6 +237,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * return the height of the last set surface.
      *
      * @return int
@@ -231,6 +247,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * return the width of the last set surface.
      *
      * @return int
@@ -240,6 +257,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Temporarly halt calls to the root rendering script.
      *
      */
@@ -249,6 +267,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Resume calls to the root rendering script.
      *
      */
@@ -259,6 +278,7 @@
 
 
     /**
+     * @deprecated in API 16
      * Set the script to handle calls to render the primary surface.
      *
      * @param s Graphics script to process rendering requests.
@@ -269,6 +289,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Set the default ProgramStore object seen as the parent state by the root
      * rendering script.
      *
@@ -280,6 +301,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Set the default ProgramFragment object seen as the parent state by the
      * root rendering script.
      *
@@ -291,6 +313,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Set the default ProgramRaster object seen as the parent state by the
      * root rendering script.
      *
@@ -302,6 +325,7 @@
     }
 
     /**
+     * @deprecated in API 16
      * Set the default ProgramVertex object seen as the parent state by the
      * root rendering script.
      *
diff --git a/include/androidfw/Input.h b/include/androidfw/Input.h
index 601a169..6d03fd6 100644
--- a/include/androidfw/Input.h
+++ b/include/androidfw/Input.h
@@ -262,6 +262,8 @@
 
     inline int32_t getFlags() const { return mFlags; }
 
+    inline void setFlags(int32_t flags) { mFlags = flags; }
+
     inline int32_t getKeyCode() const { return mKeyCode; }
 
     inline int32_t getScanCode() const { return mScanCode; }
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 58b30db..d3a00c2 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -225,11 +225,6 @@
      * If possible, seek to the sync sample closest to the specified time
      */
     public static final int SEEK_TO_CLOSEST_SYNC        = 2;
-    /**
-     * If possible, seek to a sample closest to the specified time, which may
-     * NOT be a sync sample!
-     */
-    public static final int SEEK_TO_CLOSEST             = 3;
 
     /**
      * All selected tracks seek near the requested time according to the
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index df77c9e..4414191 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -53,6 +53,7 @@
  * <tr><td>{@link #KEY_IS_ADTS}</td><td>Integer</td><td>optional, if content is AAC audio, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header.</td></tr>
  * <tr><td>{@link #KEY_AAC_PROFILE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired profile.</td></tr>
  * <tr><td>{@link #KEY_CHANNEL_MASK}</td><td>Integer</td><td>A mask of audio channel assignments</td></tr>
+ * <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
  * </table>
  *
  */
@@ -155,6 +156,13 @@
      */
     public static final String KEY_AAC_PROFILE = "aac-profile";
 
+    /**
+     * A key describing the FLAC compression level to be used (FLAC audio format only).
+     * The associated value is an integer ranging from 0 (fastest, least compression)
+     * to 8 (slowest, most compression).
+     */
+    public static final String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
+
     /* package private */ MediaFormat(Map<String, Object> map) {
         mMap = map;
     }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 7540c6f..9f0fd48 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -743,9 +743,14 @@
         }
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
-        invoke(request, reply);
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
     /**
@@ -1642,11 +1647,16 @@
     public TrackInfo[] getTrackInfo() throws IllegalStateException {
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(INVOKE_ID_GET_TRACK_INFO);
-        invoke(request, reply);
-        TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
-        return trackInfo;
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_GET_TRACK_INFO);
+            invoke(request, reply);
+            TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
+            return trackInfo;
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
     /* Do not change these values without updating their counterparts
@@ -1791,13 +1801,18 @@
 
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD);
-        request.writeFileDescriptor(fd);
-        request.writeLong(offset);
-        request.writeLong(length);
-        request.writeString(mimeType);
-        invoke(request, reply);
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD);
+            request.writeFileDescriptor(fd);
+            request.writeLong(offset);
+            request.writeLong(length);
+            request.writeString(mimeType);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
     /**
@@ -1854,10 +1869,15 @@
             throws IllegalStateException {
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
-        request.writeInt(index);
-        invoke(request, reply);
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
+            request.writeInt(index);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
 
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index c93baf1..351ff04 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -313,7 +313,7 @@
     }
 
     if (mode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC
-            || mode > MediaSource::ReadOptions::SEEK_CLOSEST) {
+            || mode >= MediaSource::ReadOptions::SEEK_CLOSEST) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return;
     }
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index a4d88ff..e35ace3 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -125,6 +125,19 @@
     return byteBufObj;
 }
 
+static void SetMapInt32(
+        JNIEnv *env, jobject hashMapObj, jmethodID hashMapPutID,
+        const char *key, int32_t value) {
+    jstring keyObj = env->NewStringUTF(key);
+    jobject valueObj = makeIntegerObject(env, value);
+
+    jobject res = env->CallObjectMethod(
+            hashMapObj, hashMapPutID, keyObj, valueObj);
+
+    env->DeleteLocalRef(valueObj); valueObj = NULL;
+    env->DeleteLocalRef(keyObj); keyObj = NULL;
+}
+
 status_t ConvertMessageToMap(
         JNIEnv *env, const sp<AMessage> &msg, jobject *map) {
     jclass hashMapClazz = env->FindClass("java/util/HashMap");
@@ -205,6 +218,41 @@
                 break;
             }
 
+            case AMessage::kTypeRect:
+            {
+                int32_t left, top, right, bottom;
+                CHECK(msg->findRect(key, &left, &top, &right, &bottom));
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        StringPrintf("%s-left", key).c_str(),
+                        left);
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        StringPrintf("%s-top", key).c_str(),
+                        top);
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        StringPrintf("%s-right", key).c_str(),
+                        right);
+
+                SetMapInt32(
+                        env,
+                        hashMap,
+                        hashMapPutID,
+                        StringPrintf("%s-bottom", key).c_str(),
+                        bottom);
+                break;
+            }
+
             default:
                 break;
         }
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
index d4c901f..e4bb6cf 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
@@ -46,8 +46,6 @@
     private Program mProgram;
     private Frame mFrame;
 
-    private int mWidth = 0;
-    private int mHeight = 0;
     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
 
     private final String mOverlayShader =
@@ -113,18 +111,17 @@
             initProgram(context, inputFormat.getTarget());
         }
 
-        // Check if the frame size has changed
-        if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) {
-            mWidth = inputFormat.getWidth();
-            mHeight = inputFormat.getHeight();
+        if (mBitmap != null) {
+            Frame frame = createBitmapFrame(context);
+            // Process
+            Frame[] inputs = {input, frame};
+            mProgram.process(inputs, output);
 
-            createBitmapFrame(context);
+            frame.release();
+        } else {
+            output.setDataFromFrame(input);
         }
 
-        // Process
-        Frame[] inputs = {input, mFrame};
-        mProgram.process(inputs, output);
-
         // Push output
         pushOutput("image", output);
 
@@ -132,22 +129,18 @@
         output.release();
     }
 
-    private void createBitmapFrame(FilterContext context) {
-        if (mBitmap != null) {
-            FrameFormat format = ImageFormat.create(mBitmap.getWidth(),
-                                                    mBitmap.getHeight(),
-                                                    ImageFormat.COLORSPACE_RGBA,
-                                                    FrameFormat.TARGET_GPU);
+    private Frame createBitmapFrame(FilterContext context) {
+        FrameFormat format = ImageFormat.create(mBitmap.getWidth(),
+                                                mBitmap.getHeight(),
+                                                ImageFormat.COLORSPACE_RGBA,
+                                                FrameFormat.TARGET_GPU);
 
-            if (mFrame != null) {
-                mFrame.release();
-            }
+        Frame frame = context.getFrameManager().newFrame(format);
+        frame.setBitmap(mBitmap);
 
-            mFrame = context.getFrameManager().newFrame(format);
-            mFrame.setBitmap(mBitmap);
+        mBitmap.recycle();
+        mBitmap = null;
 
-            mBitmap.recycle();
-            mBitmap = null;
-        }
+        return frame;
     }
 }
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
index 9e40d37..dd7f5e0 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
@@ -28,6 +28,7 @@
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
+import java.util.Date;
 import java.util.Random;
 
 public class BlackWhiteFilter extends Filter {
@@ -42,24 +43,30 @@
     private int mTileSize = 640;
 
     private Program mProgram;
+    private Random mRandom;
 
-    private int mWidth = 0;
-    private int mHeight = 0;
     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
 
     private final String mBlackWhiteShader =
             "precision mediump float;\n" +
             "uniform sampler2D tex_sampler_0;\n" +
+            "uniform vec2 seed;\n" +
             "uniform float black;\n" +
             "uniform float scale;\n" +
             "uniform float stepsize;\n" +
             "varying vec2 v_texcoord;\n" +
             "float rand(vec2 loc) {\n" +
-            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "  const float divide = 0.00048828125;\n" +
+            "  const float factor = 2048.0;\n" +
+            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
+            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
+            "  float part2 = mod(value, divide);\n" +
+            "  float part1 = value - part2;\n" +
+            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
             "}\n" +
             "void main() {\n" +
             "  vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" +
-            "  float dither = rand(v_texcoord);\n" +
+            "  float dither = rand(v_texcoord + seed);\n" +
             "  vec3 xform = clamp((color.rgb - black) * scale, 0.0, 1.0);\n" +
             "  vec3 temp = clamp((color.rgb + stepsize - black) * scale, 0.0, 1.0);\n" +
             "  vec3 new_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" +
@@ -68,6 +75,7 @@
 
     public BlackWhiteFilter(String name) {
         super(name);
+        mRandom = new Random(new Date().getTime());
     }
 
     @Override
@@ -100,10 +108,12 @@
     private void updateParameters() {
         float scale = (mBlack != mWhite) ? 1.0f / (mWhite - mBlack) : 2000f;
         float stepsize = 1.0f / 255.0f;
-
         mProgram.setHostValue("black", mBlack);
         mProgram.setHostValue("scale", scale);
         mProgram.setHostValue("stepsize", stepsize);
+
+        float seed[] = { mRandom.nextFloat(), mRandom.nextFloat() };
+        mProgram.setHostValue("seed", seed);
     }
 
     @Override
@@ -124,12 +134,6 @@
             initProgram(context, inputFormat.getTarget());
         }
 
-        // Check if the frame size has changed
-        if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) {
-            mWidth = inputFormat.getWidth();
-            mHeight = inputFormat.getHeight();
-        }
-
         // Create output frame
         Frame output = context.getFrameManager().newFrame(inputFormat);
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
index 0144d4e..377e49d5 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
@@ -28,6 +28,7 @@
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
+import java.util.Date;
 import java.util.Random;
 
 public class DocumentaryFilter extends Filter {
@@ -36,6 +37,7 @@
     private int mTileSize = 640;
 
     private Program mProgram;
+    private Random mRandom;
 
     private int mWidth = 0;
     private int mHeight = 0;
@@ -44,17 +46,24 @@
     private final String mDocumentaryShader =
             "precision mediump float;\n" +
             "uniform sampler2D tex_sampler_0;\n" +
+            "uniform vec2 seed;\n" +
             "uniform float stepsize;\n" +
             "uniform float inv_max_dist;\n" +
             "uniform vec2 center;\n" +
             "varying vec2 v_texcoord;\n" +
             "float rand(vec2 loc) {\n" +
-            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "  const float divide = 0.00048828125;\n" +
+            "  const float factor = 2048.0;\n" +
+            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
+            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
+            "  float part2 = mod(value, divide);\n" +
+            "  float part1 = value - part2;\n" +
+            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
             "}\n" +
             "void main() {\n" +
             // black white
             "  vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" +
-            "  float dither = rand(v_texcoord);\n" +
+            "  float dither = rand(v_texcoord + seed);\n" +
             "  vec3 xform = clamp(2.0 * color.rgb, 0.0, 1.0);\n" +
             "  vec3 temp = clamp(2.0 * (color.rgb + stepsize), 0.0, 1.0);\n" +
             "  vec3 new_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" +
@@ -69,6 +78,8 @@
 
     public DocumentaryFilter(String name) {
         super(name);
+        Date date = new Date();
+        mRandom = new Random(new Date().getTime());
     }
 
     @Override
@@ -138,7 +149,9 @@
             mProgram.setHostValue("center", center);
             mProgram.setHostValue("inv_max_dist", 1.0f / max_dist);
             mProgram.setHostValue("stepsize", 1.0f / 255.0f);
+
+            float seed[] = { mRandom.nextFloat(), mRandom.nextFloat() };
+            mProgram.setHostValue("seed", seed);
         }
     }
-
 }
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
index 31855460..f236856 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
@@ -30,6 +30,7 @@
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
 
+import java.util.Date;
 import java.util.Random;
 
 public class GrainFilter extends Filter {
@@ -49,14 +50,20 @@
     private int mHeight = 0;
     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
 
-    private Random mRandom = new Random();
+    private Random mRandom;
 
     private final String mNoiseShader =
             "precision mediump float;\n" +
             "uniform vec2 seed;\n" +
             "varying vec2 v_texcoord;\n" +
             "float rand(vec2 loc) {\n" +
-            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "  const float divide = 0.00048828125;\n" +
+            "  const float factor = 2048.0;\n" +
+            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
+            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
+            "  float part2 = mod(value, divide);\n" +
+            "  float part1 = value - part2;\n" +
+            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
             "}\n" +
             "void main() {\n" +
             "  gl_FragColor = vec4(rand(v_texcoord + seed), 0.0, 0.0, 1.0);\n" +
@@ -86,6 +93,7 @@
 
     public GrainFilter(String name) {
         super(name);
+        mRandom = new Random(new Date().getTime());
     }
 
     @Override
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
index 0814ba5..22a2ec8 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
@@ -28,12 +28,16 @@
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
+import java.util.Date;
+import java.util.Random;
+
 public class LomoishFilter extends Filter {
 
     @GenerateFieldPort(name = "tile_size", hasDefault = true)
     private int mTileSize = 640;
 
     private Program mProgram;
+    private Random mRandom;
 
     private int mWidth = 0;
     private int mHeight = 0;
@@ -42,6 +46,7 @@
     private final String mLomoishShader =
             "precision mediump float;\n" +
             "uniform sampler2D tex_sampler_0;\n" +
+            "uniform vec2 seed;\n" +
             "uniform float stepsizeX;\n" +
             "uniform float stepsizeY;\n" +
             "uniform float stepsize;\n" +
@@ -49,7 +54,13 @@
             "uniform float inv_max_dist;\n" +
             "varying vec2 v_texcoord;\n" +
             "float rand(vec2 loc) {\n" +
-            "  return fract(sin(dot(loc, vec2(12.9898, 78.233))) * 43758.5453);\n" +
+            "  const float divide = 0.00048828125;\n" +
+            "  const float factor = 2048.0;\n" +
+            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
+            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
+            "  float part2 = mod(value, divide);\n" +
+            "  float part1 = value - part2;\n" +
+            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
             "}\n" +
             "void main() {\n" +
             // sharpen
@@ -96,7 +107,7 @@
             "  }\n" +
             "  c_color.b = s_color.b * 0.5 + 0.25;\n" +
             // blackwhite
-            "  float dither = rand(v_texcoord);\n" +
+            "  float dither = rand(v_texcoord + seed);\n" +
             "  vec3 xform = clamp((c_color.rgb - 0.15) * 1.53846, 0.0, 1.0);\n" +
             "  vec3 temp = clamp((color.rgb + stepsize - 0.15) * 1.53846, 0.0, 1.0);\n" +
             "  vec3 bw_color = clamp(xform + (temp - xform) * (dither - 0.5), 0.0, 1.0);\n" +
@@ -108,6 +119,7 @@
 
     public LomoishFilter(String name) {
         super(name);
+        mRandom = new Random(new Date().getTime());
     }
 
     @Override
@@ -149,6 +161,9 @@
             mProgram.setHostValue("stepsize", 1.0f / 255.0f);
             mProgram.setHostValue("stepsizeX", 1.0f / mWidth);
             mProgram.setHostValue("stepsizeY", 1.0f / mHeight);
+
+            float seed[] = { mRandom.nextFloat(), mRandom.nextFloat() };
+            mProgram.setHostValue("seed", seed);
         }
     }
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
index 5632a5e..3450ef1 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
@@ -115,14 +115,6 @@
     }
 
     @Override
-    public void tearDown(FilterContext context) {
-        if (mRedEyeBitmap != null) {
-            mRedEyeBitmap.recycle();
-            mRedEyeBitmap = null;
-        }
-    }
-
-    @Override
     public void process(FilterContext context) {
         // Get input frame
         Frame input = pullInput("image");
@@ -140,10 +132,7 @@
         if (inputFormat.getWidth() != mWidth || inputFormat.getHeight() != mHeight) {
             mWidth = inputFormat.getWidth();
             mHeight = inputFormat.getHeight();
-
-            createRedEyeBitmap();
         }
-
         createRedEyeFrame(context);
 
         // Process
@@ -168,29 +157,26 @@
         }
     }
 
-    private void createRedEyeBitmap() {
-        if (mRedEyeBitmap != null) {
-            mRedEyeBitmap.recycle();
-        }
-
+    private void createRedEyeFrame(FilterContext context) {
         int bitmapWidth = mWidth / 2;
         int bitmapHeight = mHeight / 2;
 
-        mRedEyeBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
-        mCanvas.setBitmap(mRedEyeBitmap);
+        Bitmap redEyeBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
+        mCanvas.setBitmap(redEyeBitmap);
         mPaint.setColor(Color.WHITE);
         mRadius = Math.max(MIN_RADIUS, RADIUS_RATIO * Math.min(bitmapWidth, bitmapHeight));
 
-        updateProgramParams();
-    }
+        for (int i = 0; i < mCenters.length; i += 2) {
+            mCanvas.drawCircle(mCenters[i] * bitmapWidth, mCenters[i + 1] * bitmapHeight,
+                               mRadius, mPaint);
+        }
 
-    private void createRedEyeFrame(FilterContext context) {
-        FrameFormat format = ImageFormat.create(mRedEyeBitmap.getWidth() ,
-                                                mRedEyeBitmap.getHeight(),
+        FrameFormat format = ImageFormat.create(bitmapWidth, bitmapHeight,
                                                 ImageFormat.COLORSPACE_RGBA,
                                                 FrameFormat.TARGET_GPU);
         mRedEyeFrame = context.getFrameManager().newFrame(format);
-        mRedEyeFrame.setBitmap(mRedEyeBitmap);
+        mRedEyeFrame.setBitmap(redEyeBitmap);
+        redEyeBitmap.recycle();
     }
 
     private void updateProgramParams() {
@@ -199,13 +185,5 @@
         if ( mCenters.length % 2 == 1) {
             throw new RuntimeException("The size of center array must be even.");
         }
-
-        if (mRedEyeBitmap != null) {
-            for (int i = 0; i < mCenters.length; i += 2) {
-                mCanvas.drawCircle(mCenters[i] * mRedEyeBitmap.getWidth(),
-                                   mCenters[i + 1] * mRedEyeBitmap.getHeight(),
-                                   mRadius, mPaint);
-            }
-        }
     }
 }
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
index 20e4b32..b023e42 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
@@ -110,7 +110,7 @@
     }
 
     @Override
-    public void setupPorts() {
+    public synchronized void setupPorts() {
         // Make sure we have a SurfaceView
         if (mSurfaceTexture == null) {
             throw new RuntimeException("Null SurfaceTexture passed to SurfaceTextureTarget");
@@ -158,7 +158,7 @@
     }
 
     @Override
-    public void open(FilterContext context) {
+    public synchronized void open(FilterContext context) {
         // Set up SurfaceTexture internals
         mSurfaceId = context.getGLEnvironment().registerSurfaceTexture(
             mSurfaceTexture, mScreenWidth, mScreenHeight);
@@ -169,17 +169,42 @@
 
 
     @Override
-    public void close(FilterContext context) {
+    public synchronized void close(FilterContext context) {
         if (mSurfaceId > 0) {
             context.getGLEnvironment().unregisterSurfaceId(mSurfaceId);
+            mSurfaceId = -1;
+            // Once the surface is unregistered, remove the surfacetexture reference.
+            // The surfaceId could not have been valid without a valid surfacetexture.
+            mSurfaceTexture = null;
         }
     }
 
+    // This should be called from the client side when the surfacetexture is no longer
+    // valid. e.g. from onPause() in the application using the filter graph.
+    public synchronized void disconnect(FilterContext context) {
+        if (mLogVerbose) Log.v(TAG, "disconnect");
+        if (mSurfaceTexture == null) {
+            Log.d(TAG, "SurfaceTexture is already null. Nothing to disconnect.");
+            return;
+        }
+        mSurfaceTexture = null;
+        // Make sure we unregister the surface as well if a surface was registered.
+        // There can be a situation where the surface was not registered but the
+        // surfacetexture was valid. For example, the disconnect can be called before
+        // the filter was opened. Hence, the surfaceId may not be a valid one here,
+        // and need to check for its validity.
+        if (mSurfaceId > 0) {
+            context.getGLEnvironment().unregisterSurfaceId(mSurfaceId);
+            mSurfaceId = -1;
+        }
+    }
 
     @Override
-    public void process(FilterContext context) {
-        if (mLogVerbose) Log.v(TAG, "Starting frame processing");
-
+    public synchronized void process(FilterContext context) {
+        // Surface is not registered. Nothing to render into.
+        if (mSurfaceId <= 0) {
+            return;
+        }
         GLEnvironment glEnv = context.getGLEnvironment();
 
         // Get input frame
@@ -197,8 +222,6 @@
 
         // See if we need to copy to GPU
         Frame gpuFrame = null;
-        if (mLogVerbose) Log.v("SurfaceTextureTarget", "Got input format: " + input.getFormat());
-
         int target = input.getFormat().getTarget();
         if (target != FrameFormat.TARGET_GPU) {
             gpuFrame = context.getFrameManager().duplicateFrameToTarget(input,
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 17e5f4e..3b87b96 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -473,6 +473,8 @@
     }
 
     private static class ApkContainer {
+        private static final int MAX_AUTHENTICATED_DATA_SIZE = 16384;
+
         private final InputStream mInStream;
 
         private MacAuthenticatedInputStream mAuthenticatedStream;
@@ -540,26 +542,35 @@
                 throw new IOException(e);
             }
 
-            final int encStart = encryptionParams.getEncryptedDataStart();
-            final int end = encryptionParams.getDataEnd();
+            final long encStart = encryptionParams.getEncryptedDataStart();
+            final long end = encryptionParams.getDataEnd();
             if (end < encStart) {
                 throw new IOException("end <= encStart");
             }
 
             final Mac mac = getMacInstance(encryptionParams);
             if (mac != null) {
-                final int macStart = encryptionParams.getAuthenticatedDataStart();
+                final long macStart = encryptionParams.getAuthenticatedDataStart();
+                if (macStart >= Integer.MAX_VALUE) {
+                    throw new IOException("macStart >= Integer.MAX_VALUE");
+                }
 
-                final int furtherOffset;
+                final long furtherOffset;
                 if (macStart >= 0 && encStart >= 0 && macStart < encStart) {
                     /*
                      * If there is authenticated data at the beginning, read
                      * that into our MAC first.
                      */
-                    final int authenticatedLength = encStart - macStart;
-                    final byte[] authenticatedData = new byte[authenticatedLength];
+                    final long authenticatedLengthLong = encStart - macStart;
+                    if (authenticatedLengthLong > MAX_AUTHENTICATED_DATA_SIZE) {
+                        throw new IOException("authenticated data is too long");
+                    }
+                    final int authenticatedLength = (int) authenticatedLengthLong;
 
-                    Streams.readFully(inStream, authenticatedData, macStart, authenticatedLength);
+                    final byte[] authenticatedData = new byte[(int) authenticatedLength];
+
+                    Streams.readFully(inStream, authenticatedData, (int) macStart,
+                            authenticatedLength);
                     mac.update(authenticatedData, 0, authenticatedLength);
 
                     furtherOffset = 0;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index ee3b53f..b0939de 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -63,7 +63,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 77;
+    private static final int DATABASE_VERSION = 78;
 
     private Context mContext;
 
@@ -657,7 +657,7 @@
 
             upgradeVersion = 53;
         }
-        
+
         if (upgradeVersion == 53) {
             /*
              * New settings for set install location UI no longer initiated here.
@@ -1047,6 +1047,12 @@
             upgradeVersion = 77;
         }
 
+        if (upgradeVersion == 77) {
+            // Introduce "vibrate when ringing" setting
+            loadVibrateWhenRingingSetting(db);
+
+            upgradeVersion = 78;
+        }
 
         // *** Remember to update DATABASE_VERSION above!
 
@@ -1141,7 +1147,7 @@
             try {
                 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                         + " VALUES(?,?);");
-    
+
                 // Set the timeout to 30 minutes in milliseconds
                 loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                         Integer.toString(30 * 60 * 1000));
@@ -1303,7 +1309,7 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
-    
+
             loadSetting(stmt, Settings.System.VOLUME_MUSIC,
                     AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
             loadSetting(stmt, Settings.System.VOLUME_RING,
@@ -1324,10 +1330,10 @@
                     stmt,
                     Settings.System.VOLUME_BLUETOOTH_SCO,
                     AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
-    
+
             loadSetting(stmt, Settings.System.MODE_RINGER,
                     AudioManager.RINGER_MODE_NORMAL);
-    
+
             // By default:
             // - ringtones, notification, system and music streams are affected by ringer mode
             // on non voice capable devices (tablets)
@@ -1352,6 +1358,8 @@
         } finally {
             if (stmt != null) stmt.close();
         }
+
+        loadVibrateWhenRingingSetting(db);
     }
 
     private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
@@ -1363,7 +1371,7 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
-    
+
             // Vibrate on by default for ringer, on for notification
             int vibrate = 0;
             vibrate = AudioService.getValueForVibrateSetting(vibrate,
@@ -1377,6 +1385,24 @@
         }
     }
 
+    private void loadVibrateWhenRingingSetting(SQLiteDatabase db) {
+        // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here.
+        // Phone app should separately check whether AudioManager#getRingerMode() returns
+        // RINGER_MODE_VIBRATE, with which the device should vibrate anyway.
+        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON,
+                AudioManager.VIBRATE_SETTING_OFF);
+        boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON);
+
+        SQLiteStatement stmt = null;
+        try {
+            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                    + " VALUES(?,?);");
+            loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0);
+        } finally {
+            if (stmt != null) stmt.close();
+        }
+    }
+
     private void loadSettings(SQLiteDatabase db) {
         loadSystemSettings(db);
         loadSecureSettings(db);
@@ -1387,7 +1413,7 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
-    
+
             loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
                     R.bool.def_dim_screen);
             loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
@@ -1396,31 +1422,31 @@
                      ? 1 : 0);
             loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                     R.integer.def_screen_off_timeout);
-    
+
             // Set default cdma emergency tone
             loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
-    
+
             // Set default cdma call auto retry
             loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
-    
+
             // Set default cdma DTMF type
             loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
-    
+
             // Set default hearing aid
             loadSetting(stmt, Settings.System.HEARING_AID, 0);
-    
+
             // Set default tty mode
             loadSetting(stmt, Settings.System.TTY_MODE, 0);
-    
+
             loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
                     R.bool.def_airplane_mode_on);
-    
+
             loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
                     R.string.def_airplane_mode_radios);
-    
+
             loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                     R.string.airplane_mode_toggleable_radios);
-    
+
             loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
                     R.bool.def_auto_time); // Sync time to NITZ
 
@@ -1429,17 +1455,17 @@
 
             loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
                     R.integer.def_screen_brightness);
-    
+
             loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                     R.bool.def_screen_brightness_automatic_mode);
-    
+
             loadDefaultAnimationSettings(stmt);
-    
+
             loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
                     R.bool.def_accelerometer_rotation);
-    
+
             loadDefaultHapticSettings(stmt);
-    
+
             loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                     R.bool.def_notification_pulse);
             loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
@@ -1504,41 +1530,41 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                     + " VALUES(?,?);");
-    
+
             loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
                     R.bool.def_bluetooth_on);
-    
+
             // Data roaming default, based on build
             loadSetting(stmt, Settings.Secure.DATA_ROAMING,
                     "true".equalsIgnoreCase(
                             SystemProperties.get("ro.com.android.dataroaming",
                                     "false")) ? 1 : 0);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                     R.bool.def_install_non_market_apps);
-    
+
             loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                     R.string.def_location_providers_allowed);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
                     R.bool.assisted_gps_enabled);
-    
+
             loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
                     R.integer.def_network_preference);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
                     R.bool.def_usb_mass_storage_enabled);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
                     R.bool.def_wifi_on);
             loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
                     R.bool.def_networks_available_notification_on);
-    
+
             String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
             if (!TextUtils.isEmpty(wifiWatchList)) {
                 loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
             }
-    
+
             // Set the preferred network mode to 0 = Global, CDMA default
             int type;
             if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
@@ -1548,30 +1574,30 @@
                         RILConstants.PREFERRED_NETWORK_MODE);
             }
             loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
-    
+
             // Enable or disable Cell Broadcast SMS
             loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
                     RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
-    
+
             // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
             // persistent system property instead.
             //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
-    
+
             // Allow mock locations default, based on build
             loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
                     "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
-    
+
             loadSecure35Settings(stmt);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
                     R.bool.def_mount_play_notification_snd);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
                     R.bool.def_mount_ums_autostart);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
                     R.bool.def_mount_ums_prompt);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                     R.bool.def_mount_ums_notify_enabled);
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 9d3a942..0038d13 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -161,18 +161,19 @@
 
         <!-- started from ... somewhere -->
         <activity
-            android:name=".Nyandroid"
+            android:name=".BeanBag"
             android:exported="true"
-            android:label="Nyandroid"
-            android:icon="@drawable/nyandroid04"
-            android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+            android:label="BeanBag"
+            android:icon="@drawable/redbeandroid"
+            android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"
             android:hardwareAccelerated="true"
             android:launchMode="singleInstance"
             android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
-<!--                <category android:name="android.intent.category.DREAM" />-->
+                <category android:name="com.android.internal.category.PLATLOGO" />
+<!--            <category android:name="android.intent.category.LAUNCHER" />-->
             </intent-filter>
         </activity>
     </application>
diff --git a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..8a0a30f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..bc6462b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
index 69f3543..f4e28ae 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..25f15e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..4f5bba5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
index fb30982..ef7afb8 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/jandycane.png b/packages/SystemUI/res/drawable-nodpi/jandycane.png
new file mode 100644
index 0000000..278cfec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/jandycane.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid00.png b/packages/SystemUI/res/drawable-nodpi/nyandroid00.png
deleted file mode 100644
index 6cea873..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid00.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid01.png b/packages/SystemUI/res/drawable-nodpi/nyandroid01.png
deleted file mode 100644
index 82b8a21..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid01.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid02.png b/packages/SystemUI/res/drawable-nodpi/nyandroid02.png
deleted file mode 100644
index fde0033..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid02.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid03.png b/packages/SystemUI/res/drawable-nodpi/nyandroid03.png
deleted file mode 100644
index 54c5f46..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid03.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid04.png b/packages/SystemUI/res/drawable-nodpi/nyandroid04.png
deleted file mode 100644
index 35e5ab5..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid04.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid05.png b/packages/SystemUI/res/drawable-nodpi/nyandroid05.png
deleted file mode 100644
index d3eaace..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid05.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid06.png b/packages/SystemUI/res/drawable-nodpi/nyandroid06.png
deleted file mode 100644
index 0e0d3b1..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid06.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid07.png b/packages/SystemUI/res/drawable-nodpi/nyandroid07.png
deleted file mode 100644
index edb0b17..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid07.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid08.png b/packages/SystemUI/res/drawable-nodpi/nyandroid08.png
deleted file mode 100644
index 10fc4f6..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid08.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid09.png b/packages/SystemUI/res/drawable-nodpi/nyandroid09.png
deleted file mode 100644
index 57ade54..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid09.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid10.png b/packages/SystemUI/res/drawable-nodpi/nyandroid10.png
deleted file mode 100644
index 36feb2f..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid10.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/nyandroid11.png b/packages/SystemUI/res/drawable-nodpi/nyandroid11.png
deleted file mode 100644
index 125935b..0000000
--- a/packages/SystemUI/res/drawable-nodpi/nyandroid11.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbean0.png b/packages/SystemUI/res/drawable-nodpi/redbean0.png
new file mode 100644
index 0000000..b088939
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/redbean0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbean1.png b/packages/SystemUI/res/drawable-nodpi/redbean1.png
new file mode 100644
index 0000000..8fc8d9d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/redbean1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbean2.png b/packages/SystemUI/res/drawable-nodpi/redbean2.png
new file mode 100644
index 0000000..ef11ca8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/redbean2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbeandroid.png b/packages/SystemUI/res/drawable-nodpi/redbeandroid.png
new file mode 100644
index 0000000..9aa3f82
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/redbeandroid.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star0.png b/packages/SystemUI/res/drawable-nodpi/star0.png
deleted file mode 100644
index f2ca960..0000000
--- a/packages/SystemUI/res/drawable-nodpi/star0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star1.png b/packages/SystemUI/res/drawable-nodpi/star1.png
deleted file mode 100644
index 69ef4da..0000000
--- a/packages/SystemUI/res/drawable-nodpi/star1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star2.png b/packages/SystemUI/res/drawable-nodpi/star2.png
deleted file mode 100644
index b95968a..0000000
--- a/packages/SystemUI/res/drawable-nodpi/star2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star3.png b/packages/SystemUI/res/drawable-nodpi/star3.png
deleted file mode 100644
index ad0f589..0000000
--- a/packages/SystemUI/res/drawable-nodpi/star3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star4.png b/packages/SystemUI/res/drawable-nodpi/star4.png
deleted file mode 100644
index 934c45b..0000000
--- a/packages/SystemUI/res/drawable-nodpi/star4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/star5.png b/packages/SystemUI/res/drawable-nodpi/star5.png
deleted file mode 100644
index 46a4435..0000000
--- a/packages/SystemUI/res/drawable-nodpi/star5.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..2ff93d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..430f913
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..807241a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..2ff93d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..430f913
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..807241a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..60e7418
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..e243e50
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
index fe2c642..cdad949 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notify_rotation.xml b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
index 213af80..11bc22c 100644
--- a/packages/SystemUI/res/drawable/ic_notify_rotation.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
@@ -14,14 +14,23 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true"
-         android:drawable="@drawable/ic_notify_rotation_on_normal" />
-    <item android:state_checked="true" android:state_pressed="true"
-         android:drawable="@drawable/ic_notify_rotation_on_pressed" />
-    <item android:state_pressed="true"
-         android:drawable="@drawable/ic_notify_rotation_off_pressed" />
-    <item
-         android:drawable="@drawable/ic_notify_rotation_off_normal" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:constantSize="true">
+    <item android:state_checked="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/ic_notify_rotation_on_pressed"
+                android:gravity="center" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/ic_notify_rotation_on_normal"
+                android:gravity="center" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/ic_notify_rotation_off_pressed"
+                android:gravity="center" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/ic_notify_rotation_off_normal"
+                android:gravity="center" />
+    </item>
 </selector>
 
diff --git a/packages/SystemUI/res/drawable/nyandroid_anim.xml b/packages/SystemUI/res/drawable/nyandroid_anim.xml
deleted file mode 100644
index 855a0c2..0000000
--- a/packages/SystemUI/res/drawable/nyandroid_anim.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/nyandroid00" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid01" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid02" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid03" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid04" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid05" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid06" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid07" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid08" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid09" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid10" android:duration="80" />
-    <item android:drawable="@drawable/nyandroid11" android:duration="80" />
-</animation-list>
-
diff --git a/packages/SystemUI/res/drawable/star_anim.xml b/packages/SystemUI/res/drawable/star_anim.xml
deleted file mode 100644
index d7f2d8f..0000000
--- a/packages/SystemUI/res/drawable/star_anim.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/star0" android:duration="200" />
-    <item android:drawable="@drawable/star1" android:duration="200" />
-    <item android:drawable="@drawable/star2" android:duration="200" />
-    <item android:drawable="@drawable/star3" android:duration="200" />
-    <item android:drawable="@drawable/star4" android:duration="200" />
-    <item android:drawable="@drawable/star5" android:duration="200" />
-</animation-list>
-
diff --git a/packages/SystemUI/res/drawable/status_bar_close.xml b/packages/SystemUI/res/drawable/status_bar_close.xml
new file mode 100644
index 0000000..2efc3c3a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_close.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+         android:drawable="@drawable/status_bar_close_on" />
+    <item
+         android:drawable="@drawable/status_bar_close_off" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index fcdd56c..869b164 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -27,6 +27,12 @@
     systemui:recentItemLayout="@layout/status_bar_recent_item"
     >
 
+    <ImageView
+        android:id="@+id/recents_transition_placeholder_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible" />
+
     <FrameLayout
         android:id="@+id/recents_bg_protect"
         android:background="@drawable/status_bar_recents_background"
@@ -45,7 +51,7 @@
             android:fadingEdge="horizontal"
             android:scrollbars="none"
             android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
-            android:layout_gravity="bottom|left"
+            android:layout_gravity="bottom|right"
             android:orientation="horizontal"
             android:clipToPadding="false"
             android:clipChildren="false">
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index 216dcb0..fc9fcf4 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -27,6 +27,12 @@
     systemui:recentItemLayout="@layout/status_bar_recent_item"
     >
 
+    <ImageView
+        android:id="@+id/recents_transition_placeholder_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible" />
+
     <FrameLayout
         android:id="@+id/recents_bg_protect"
         android:background="@drawable/status_bar_recents_background"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 8715a99..f69aac8 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -25,25 +25,24 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:background="@drawable/notification_tracking_bg"
-    android:paddingTop="@*android:dimen/status_bar_height"
+    android:background="@drawable/notification_panel_bg"
+    android:paddingTop="@dimen/notification_panel_padding_top"
     android:layout_marginLeft="@dimen/notification_panel_margin_left"
     >
 
-    <RelativeLayout
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="52dp"
-        android:paddingTop="3dp"
-        android:paddingBottom="5dp"
-        android:paddingRight="3dp"
+        android:layout_height="wrap_content"
+        android:paddingTop="@dimen/notification_panel_header_padding_top"
         android:background="@drawable/notification_header_bg"
+        android:orientation="horizontal"
+        android:gravity="center_vertical"
+        android:baselineAligned="false"
         >
         <com.android.systemui.statusbar.policy.Clock
             android:id="@+id/clock"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
             android:layout_marginLeft="8dp"
             android:singleLine="true"
             android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
@@ -52,64 +51,41 @@
         <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_centerVertical="true"
-            android:layout_toRightOf="@id/clock"
             android:layout_marginLeft="8dp"
-            android:paddingLeft="8dp"
+            android:layout_marginRight="8dp"
             android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
             />
-        <!--
-        <com.android.systemui.statusbar.phone.CarrierLabel
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_marginTop="1dp"
-            android:layout_marginLeft="5dp"
-            android:layout_gravity="center_vertical"
-            android:paddingBottom="1dp"
-            android:paddingLeft="4dp"
-            android:textAppearance="?android:attr/textAppearanceLarge"
-            android:textColor="?android:attr/textColorSecondary"
-            />
-        -->
 
         <com.android.systemui.statusbar.RotationToggle android:id="@+id/rotation_lock_button"
             android:layout_width="32dp"
             android:layout_height="32dp"
-            android:layout_centerVertical="true"
-            android:layout_toRightOf="@id/date"
-            android:layout_marginLeft="12dp"
+            android:layout_margin="8dp"
             android:button="@drawable/ic_notify_rotation"
             android:contentDescription="@string/accessibility_rotation_lock_off"
             />
 
         <ImageView android:id="@+id/settings_button"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_marginLeft="8dp"
-            android:layout_centerVertical="true"
-            android:layout_toRightOf="@id/rotation_lock_button"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:scaleType="center"
             android:src="@drawable/ic_notify_quicksettings"
             android:contentDescription="@string/accessibility_settings_button"
             />
 
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            />
+
         <ImageView android:id="@+id/clear_all_button"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_marginLeft="8dp"
-            android:layout_centerVertical="true"
-            android:layout_alignParentRight="true"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:scaleType="center"
             android:src="@drawable/ic_notify_clear"
             android:contentDescription="@string/accessibility_clear_all"
             />            
-    </RelativeLayout>
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="2dp"
-        android:layout_marginTop="52dp"
-        android:background="@drawable/status_bar_hr"
-        />
+    </LinearLayout>
 
     <ScrollView
         android:id="@+id/scroll"
@@ -117,8 +93,8 @@
         android:layout_height="match_parent"
         android:fadingEdge="none"
         android:overScrollMode="ifContentScrolls"
-		android:layout_marginTop="54dp"
-		android:layout_marginBottom="34dp"
+        android:layout_marginTop="@dimen/notification_panel_header_height"
+        android:layout_marginBottom="@dimen/close_handle_underlap"
         >
         <com.android.systemui.statusbar.policy.NotificationRowLayout
             android:id="@+id/latestItems"
@@ -128,14 +104,6 @@
             />
     </ScrollView>
 
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/title_bar_shadow"
-		android:layout_marginTop="54dp"
-        android:scaleType="fitXY"
-    />
-
     <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
         android:layout_width="match_parent"
         android:layout_height="@dimen/close_handle_height"
@@ -144,10 +112,10 @@
         >
         <ImageView
             android:layout_width="match_parent"
-            android:layout_height="34dp"
+            android:layout_height="@dimen/close_handle_height"
             android:layout_gravity="bottom"
             android:scaleType="fitXY"
-            android:src="@drawable/status_bar_close_on"
+            android:src="@drawable/status_bar_close"
             />
 
     </com.android.systemui.statusbar.phone.CloseDragHandle>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index e69cd8a..7491939 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -1,7 +1,6 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@*android:drawable/notification_bg"
     >
 
     <View
@@ -34,7 +33,6 @@
         >
 
         <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/adaptive"
-           android:background="@*android:drawable/notification_bg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
 
diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
deleted file mode 100644
index c1b0066..0000000
--- a/packages/SystemUI/res/layout/status_bar_tracking.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    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.
--->
-
-<com.android.systemui.statusbar.phone.TrackingView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:visibility="gone"
-    android:focusable="true"
-    android:descendantFocusability="afterDescendants"
-    android:paddingBottom="0px"
-    android:paddingLeft="0px"
-    android:paddingRight="0px"
-    >
-
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:background="@drawable/notification_tracking_bg"
-        >
-        <com.android.systemui.statusbar.phone.CarrierLabel
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:layout_gravity="bottom"
-            android:gravity="center"
-            android:paddingBottom="20dp"
-            />
-    </FrameLayout>
-
-    <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        >
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="bottom"
-            android:scaleType="fitXY"
-            android:src="@drawable/status_bar_close_on"
-            />
-
-    </com.android.systemui.statusbar.phone.CloseDragHandle>
-
-</com.android.systemui.statusbar.phone.TrackingView>
diff --git a/packages/SystemUI/res/layout/system_bar_recent_panel.xml b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
index c2b9e51..d5745c8 100644
--- a/packages/SystemUI/res/layout/system_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
@@ -39,6 +39,12 @@
         android:clipToPadding="false"
         android:clipChildren="false">
 
+        <ImageView
+            android:id="@+id/recents_transition_placeholder_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:visibility="invisible" />
+
         <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 47ac16d..ae520f9 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index ece78dc..d7f4287 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c412d58..b9144a2 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -140,8 +140,12 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"تنشيط شاشة التوقف"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"معلومات التطبيق"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
+    <string name="notifications_off_title" msgid="8936620513608443224">"التنبيهات معطّلة"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"انقر هنا لإعادة تشغيل الإشعارات."</string>
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
     <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 859df39..525137f 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ae1158d..52ee9e1 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 8adba08..5a2c9cd 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -142,8 +142,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Activa el protector de pantalla"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informació de l\'aplicació"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Notificacions desactivades"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Pica aquí per tornar a activar les notificacions."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla està bloquejada en orientació horitzontal."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla està bloquejada en orientació vertical."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 601869d..1647358 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 32ae3a9..ab68e80 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -144,4 +144,7 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skærmen er nu låst i liggende retning."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skærmen er nu låst i stående retning."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index a365ce2..2b62397 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -146,4 +146,7 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Bildschirm bleibt im Querformat."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Bildschirm bleibt im Hochformat."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 72e8629..0b87777 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -142,8 +142,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Ενεργοποίηση προφύλαξης οθόνης"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Πληροφορίες εφαρμογής"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Ειδοποιήσεις ανενεργές"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Πατήστε εδώ για να ενεργοποιήσετε ξανά τις ειδοποιήσεις."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Η οθόνη έχει κλειδωθεί σε οριζόντιο προσανατολισμό."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Η οθόνη έχει κλειδωθεί σε κατακόρυφο προσανατολισμό."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 9701ab8..6b40300 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -140,8 +140,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Activate screen saver"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App info"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Notifications off"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Tap here to turn notifications back on."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3bc4077..b103d58 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index c6e2604..a11194e 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -140,8 +140,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Activar salvapantallas"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Notificaciones desactivadas"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Toca aquí para volver a activar las notificaciones."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla está bloqueada en modo horizontal."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla está bloqueada en modo vertical."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 55ebbad..1ad5358 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index c764821..8097367 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -140,8 +140,12 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلان‌ها"</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"فعال کردن محافظ صفحه نمایش"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"اطلاعات برنامه"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
+    <string name="notifications_off_title" msgid="8936620513608443224">"اعلان‌ها خاموش"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"برای روشن کردن مجدد اعلان‌ها، اینجا را ضربه بزنید."</string>
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
     <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a68675c..6345555 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 52df763..4b3e1d4 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -146,4 +146,7 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"L\'écran est verrouillé en mode paysage."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"L\'écran est verrouillé en mode portrait."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 9220a49..2e5ae61 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2c6c00a..df155dd 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d1ac63a5..6526c63 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 981782d..4571066 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index cac4e73..432d984 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -142,8 +142,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Attiva screensaver"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informazioni applicazione"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Notifiche disattivate"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Tocca qui per riattivare le notifiche."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Lo schermo è bloccato in orientamento orizzontale."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Lo schermo è bloccato in orientamento verticale."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index eeca907..bdc84b6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -140,8 +140,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"הפעלת שומר מסך"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"פרטי יישום"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"מצב התראות כבוי"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"הקש כאן כדי להפעיל מחדש את ההתראות."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"המסך נעול כעת לרוחב."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"המסך נעול כעת לאורך."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 2b1daf8..3912b539 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 4cd5778..438cc0d 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 54ed00c..6810d7f 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index afedc72..bf59477 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index d956d4d..b77df60 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index aca1f94..b416095 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7d50794..936e0958 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -140,8 +140,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Schermbeveiliging inschakelen"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-info"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Meldingen uit"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Tik hier om meldingen weer in te schakelen."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Scherm wordt automatisch geroteerd."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Het scherm is nu vergrendeld in liggende stand."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Het scherm is nu vergrendeld in staande stand."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4847e51..3dab389 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 1d22d2f..30950ba 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8b774e6..a66a649 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 8d3103b..16e5719 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -254,4 +254,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 714ad2d..2896eae 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index dcfe560..f2d056d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 96cd983..64494b8 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b8371ab..73befa6 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e29fc0c..6b475d3 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 691f89e..36950dc 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -144,4 +144,7 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Bildskärmens riktning är nu låst i liggande format."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Bildskärmens riktning är nu låst i stående format."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 5803f3c..8ce45ed 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -138,8 +138,9 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Amilisha hifadhi ya skrini"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Taarifa ya programu"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
+    <string name="notifications_off_title" msgid="8936620513608443224">"Arifa zimezimwa"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Gonga hapa ili kuwasha tena arifa."</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrini imefungwa sasa katika uelekezo wa mandhari."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrini imefungwa katika uelekeo wa picha."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml
new file mode 100644
index 0000000..e440de1
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+    <!-- Recent Applications parameters -->
+    <dimen name="status_bar_recents_app_label_width">190dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
new file mode 100644
index 0000000..7dc91d1
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+    <!-- Recent Applications parameters -->
+    <dimen name="status_bar_recents_app_label_width">140dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 50a61b1..2cb99ff 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -16,8 +16,8 @@
 */
 -->
 <resources>
-    <!-- The width of the notification panel window -->
-    <dimen name="notification_panel_width">446dp</dimen>
+    <!-- The width of the notification panel window: 446 + 16 + 16 (padding in the bg drawable) -->
+    <dimen name="notification_panel_width">478dp</dimen>
 
     <!-- Layout parameters for the notification panel -->
     <dimen name="notification_panel_margin_bottom">192dp</dimen>
@@ -36,4 +36,10 @@
     <!-- Height of search panel including navigation bar height -->
     <dimen name="navbar_search_panel_height">300dip</dimen>
 
+    <!-- Extra space above the clock in the panel; on this device, zero -->
+    <dimen name="notification_panel_header_padding_top">0dp</dimen>
+
+    <!-- Size of application thumbnail -->
+    <dimen name="status_bar_recents_thumbnail_width">200dp</dimen>
+    <dimen name="status_bar_recents_thumbnail_height">177dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2ead831..dbb8d91 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 9729a17..f20f6af 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7a328b3..d0f08fc 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 995f21a..6494fc8 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -144,4 +144,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 7c99f6b..0019c7c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -140,8 +140,12 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Kích hoạt trình bảo vệ màn hình"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Thông tin về ứng dụng"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
+    <string name="notifications_off_title" msgid="8936620513608443224">"Tắt thông báo"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Chạm vào đây để bật lại thông báo."</string>
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
     <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c6e29555..b45251f 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index ad72466..66c834f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -146,4 +146,10 @@
     <skip />
     <!-- no translation found for notifications_off_text (2529001315769385273) -->
     <skip />
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index b2b111d..78b2779 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -140,8 +140,12 @@
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
     <string name="dreams_dock_launcher" msgid="3541196417659166245">"Yenza ukuthi iskrini seyiva sisebenze"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Ulwazi lohlelo lokusebenza"</string>
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
+    <string name="notifications_off_title" msgid="8936620513608443224">"Izaziso zivaliwe"</string>
+    <string name="notifications_off_text" msgid="2529001315769385273">"Thepha lapha ukuvula futhi izaziso."</string>
+    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
     <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
+    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
+    <skip />
+    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 9257195..ac2779f 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,11 +20,11 @@
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="status_bar_background">#ff000000</drawable>
+    <color name="notification_panel_solid_background">#ff000000</color>
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
     <color name="status_bar_recents_app_label_color">#ffffffff</color>
     <drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
     <drawable name="notification_header_bg">#FF000000</drawable>
-    <drawable name="notification_tracking_bg">#66000000</drawable>
     <color name="notification_list_shadow_top">#80000000</color>
     <drawable name="recents_callout_line">#99ffffff</drawable>
     <drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 276d74b..2ff0e00 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -49,14 +49,14 @@
          reducing false presses on navbar buttons; approx 2mm -->
     <dimen name="navigation_bar_deadzone_size">12dp</dimen>
 
-    <!-- thickness (height) of each notification row, including any separators or padding -->
-    <dimen name="notification_height">68dp</dimen>
+    <!-- thickness (height) of each 1U notification row plus glow, padding, etc -->
+    <dimen name="notification_height">72dp</dimen>
 
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
 
-    <!-- Height of a small notification in the status bar -->
-    <dimen name="notification_min_height">@android:dimen/notification_large_icon_height</dimen>
+    <!-- Height of a small notification in the status bar plus glow, padding, etc -->
+    <dimen name="notification_min_height">72dp</dimen>
 
     <!-- Height of a small notification in the status bar -->
     <!-- TODO: change this back to 256dp once we deal with actions. -->
@@ -71,8 +71,8 @@
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">0dp</dimen>
 
-    <!-- thickness (height) of dividers between each notification row -->
-    <dimen name="notification_divider_height">2dp</dimen>
+    <!-- half the distance between notifications in the panel -->
+    <dimen name="notification_divider_height">4dp</dimen>
 
     <!-- Notification drawer tuning parameters (phone UI) -->
     <!-- Initial velocity of the shade when expanding on its own -->
@@ -125,7 +125,19 @@
     <dimen name="navbar_search_panel_height">230dip</dimen>
 
     <!-- Height of the draggable handle at the bottom of the phone notification panel -->
-    <dimen name="close_handle_height">34dp</dimen>
+    <dimen name="close_handle_height">32dp</dimen>
+
+    <!-- Amount of close_handle that will not overlap the notification list -->
+    <dimen name="close_handle_underlap">18dp</dimen>
+
+    <!-- Height of the notification panel header bar -->
+    <dimen name="notification_panel_header_height">48dp</dimen>
+
+    <!-- Height of the notification panel header bar -->
+    <dimen name="notification_panel_padding_top">@*android:dimen/status_bar_height</dimen>
+
+    <!-- Extra space above the clock in the panel; half of (notification_panel_header_height - 32) -->
+    <dimen name="notification_panel_header_padding_top">0dp</dimen>
 
     <!-- Layout parameters for the notification panel -->
     <dimen name="notification_panel_margin_bottom">0dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 2a4c5fd..8ebbc52 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -17,4 +17,5 @@
 
 <resources>
     <item type="id" name="expandable_tag" />
+    <item type="id" name="user_expanded_tag" />
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BeanBag.java b/packages/SystemUI/src/com/android/systemui/BeanBag.java
new file mode 100644
index 0000000..e4f00d6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BeanBag.java
@@ -0,0 +1,439 @@
+/*);
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.animation.AnimatorSet;
+import android.animation.PropertyValuesHolder;
+import android.animation.ObjectAnimator;
+import android.animation.TimeAnimator;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Pair;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import java.util.HashMap;
+import java.util.Random;
+
+public class BeanBag extends Activity {
+    final static boolean DEBUG = false;
+
+    public static class Board extends FrameLayout
+    {
+        static Random sRNG = new Random();
+
+        static float lerp(float a, float b, float f) {
+            return (b-a)*f + a;
+        }
+
+        static float randfrange(float a, float b) {
+            return lerp(a, b, sRNG.nextFloat());
+        }
+
+        static int randsign() {
+            return sRNG.nextBoolean() ? 1 : -1;
+        }
+
+        static boolean flip() {
+            return sRNG.nextBoolean();
+        }
+
+        static float mag(float x, float y) {
+            return (float) Math.sqrt(x*x+y*y);
+        }
+
+        static float dot(float x1, float y1, float x2, float y2) {
+            return x1*x2+y1+y2;
+        }
+
+        static <E> E pick(E[] array) {
+            if (array.length == 0) return null;
+            return array[sRNG.nextInt(array.length)];
+        }
+
+        static int pickInt(int[] array) {
+            if (array.length == 0) return 0;
+            return array[sRNG.nextInt(array.length)];
+        }
+
+        static int NUM_BEANS = 40;
+        static float MIN_SCALE = 0.2f;
+        static float MAX_SCALE = 1f;
+
+        static float LUCKY = 0.001f;
+
+        static int MAX_RADIUS = (int)(576 * MAX_SCALE);
+
+        static int BEANS[] = {
+          R.drawable.redbean0,
+          R.drawable.redbean0,
+          R.drawable.redbean0,
+          R.drawable.redbean0,
+          R.drawable.redbean1,
+          R.drawable.redbean1,
+          R.drawable.redbean2,
+          R.drawable.redbean2,
+          R.drawable.redbeandroid,
+        };
+
+        static int COLORS[] = {
+            0xFF00CC00,
+            0xFFCC0000,
+            0xFF0000CC,
+            0xFFFFFF00,
+            0xFFFF8000,
+            0xFF00CCFF,
+            0xFFFF0080,
+            0xFF8000FF,
+            0xFFFF8080,
+            0xFF8080FF,
+            0xFFB0C0D0,
+            0xFFDDDDDD,
+            0xFF333333,
+        };
+
+        public class Bean extends ImageView {
+            public static final float VMAX = 1000.0f;
+            public static final float VMIN = 100.0f;
+
+            public float x, y, a;
+
+            public float va;
+            public float vx, vy;
+
+            public float r;
+
+            public float z;
+
+            public int h,w;
+
+            public boolean grabbed;
+            public float grabx, graby;
+            public long grabtime;
+
+            public Bean(Context context, AttributeSet as) {
+                super(context, as);
+            }
+
+            public String toString() {
+                return String.format("<bean (%.1f, %.1f) (%d x %d)>",
+                    getX(), getY(), getWidth(), getHeight());
+            }
+
+            private void pickBean() {
+                int beanId = pickInt(BEANS);
+                if (randfrange(0,1) <= LUCKY) {
+                    beanId = R.drawable.jandycane;
+                }
+                BitmapDrawable bean = (BitmapDrawable) getContext().getResources().getDrawable(beanId);
+                Bitmap beanBits = bean.getBitmap();
+                h=beanBits.getHeight();
+                w=beanBits.getWidth();
+
+                if (DEBUG) {
+                    bean.setAlpha(0x80);
+                }
+                this.setImageDrawable(bean);
+
+                Paint pt = new Paint();
+                final int color = pickInt(COLORS);
+                ColorMatrix CM = new ColorMatrix();
+                float[] M = CM.getArray();
+                // we assume the color information is in the red channel
+                /* R */ M[0]  = (float)((color & 0x00FF0000) >> 16) / 0xFF;
+                /* G */ M[5]  = (float)((color & 0x0000FF00) >> 8)  / 0xFF;
+                /* B */ M[10] = (float)((color & 0x000000FF))       / 0xFF;
+                pt.setColorFilter(new ColorMatrixColorFilter(M));
+                setLayerType(View.LAYER_TYPE_HARDWARE, (beanId == R.drawable.jandycane) ? null : pt);
+            }
+
+            public void reset() {
+                pickBean();
+
+                final float scale = lerp(MIN_SCALE,MAX_SCALE,z);
+                setScaleX(scale); setScaleY(scale);
+
+                r = 0.3f*Math.max(h,w)*scale;
+
+                a=(randfrange(0,360));
+                va = randfrange(-30,30);
+
+                vx = randfrange(-40,40) * z;
+                vy = randfrange(-40,40) * z;
+                final float boardh = boardHeight;
+                final float boardw = boardWidth;
+                //android.util.Log.d("BeanBag", "reset: w="+w+" h="+h);
+                if (flip()) {
+                    x=(vx < 0 ? boardw+2*r : -r*4f);
+                    y=(randfrange(0, boardh-3*r)*0.5f + ((vy < 0)?boardh*0.5f:0));
+                } else {
+                    y=(vy < 0 ? boardh+2*r : -r*4f);
+                    x=(randfrange(0, boardw-3*r)*0.5f + ((vx < 0)?boardw*0.5f:0));
+                }
+            }
+
+            public void update(float dt) {
+                if (grabbed) {
+//                    final float interval = (SystemClock.uptimeMillis() - grabtime) / 1000f;
+                    vx = (vx * 0.75f) + ((grabx - x) / dt) * 0.25f;
+                    x = grabx;
+                    vy = (vy * 0.75f) + ((graby - y) / dt) * 0.25f;;
+                    y = graby;
+                } else {
+                    x = (x + vx * dt);
+                    y = (y + vy * dt);
+                    a = (a + va * dt);
+                }
+            }
+
+            public float overlap(Bean other) {
+                final float dx = (x - other.x);
+                final float dy = (y - other.y);
+                return mag(dx, dy) - r - other.r;
+            }
+
+            @Override
+            public boolean onTouchEvent(MotionEvent e) {
+                switch (e.getAction()) {
+                    case MotionEvent.ACTION_DOWN:
+                        grabbed = true;
+                        va = 0;
+                        // fall
+                    case MotionEvent.ACTION_MOVE:
+                        grabx = e.getRawX();
+                        graby = e.getRawY();
+                        grabtime = e.getEventTime();
+                        break;
+                    case MotionEvent.ACTION_CANCEL:
+                    case MotionEvent.ACTION_UP:
+                        grabbed = false;
+                        va = randfrange(-5,5);
+                        break;
+                }
+                return true;
+            }
+        }
+
+        TimeAnimator mAnim;
+        private int boardWidth;
+        private int boardHeight;
+
+        public Board(Context context, AttributeSet as) {
+            super(context, as);
+
+            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
+
+            setWillNotDraw(!DEBUG);
+        }
+
+        private void reset() {
+//            android.util.Log.d("Nyandroid", "board reset");
+            removeAllViews();
+
+            final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
+                        ViewGroup.LayoutParams.WRAP_CONTENT,
+                        ViewGroup.LayoutParams.WRAP_CONTENT);
+
+            for(int i=0; i<NUM_BEANS; i++) {
+                Bean nv = new Bean(getContext(), null);
+                addView(nv, wrap);
+                nv.z = ((float)i/NUM_BEANS);
+                nv.z *= nv.z;
+                nv.reset();
+                nv.x = (randfrange(0, boardWidth));
+                nv.y = (randfrange(0, boardHeight));
+            }
+
+            if (mAnim != null) {
+                mAnim.cancel();
+            }
+            mAnim = new TimeAnimator();
+            mAnim.setTimeListener(new TimeAnimator.TimeListener() {
+                private long lastPrint = 0;
+                public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+                    if (DEBUG && totalTime - lastPrint > 5000) {
+                        lastPrint = totalTime;
+                        for (int i=0; i<getChildCount(); i++) {
+                            android.util.Log.d("BeanBag", "bean " + i + ": " + getChildAt(i));
+                        }
+                    }
+
+                    for (int i=0; i<getChildCount(); i++) {
+                        View v = getChildAt(i);
+                        if (!(v instanceof Bean)) continue;
+                        Bean nv = (Bean) v;
+                        nv.update(deltaTime / 1000f);
+
+                        for (int j=i+1; j<getChildCount(); j++) {
+                            View v2 = getChildAt(j);
+                            if (!(v2 instanceof Bean)) continue;
+                            Bean nv2 = (Bean) v2;
+                            final float overlap = nv.overlap(nv2);
+                            if (false && overlap < 0) {
+                                // angle pointing from nv2 to nv
+                                final float dx = nv.x - nv2.x;
+                                final float dy = nv.y - nv2.y;
+                                final float ang = (float) Math.atan2(dx, dy);
+
+                                if (false) {
+                                nv.vx -= Math.cos(ang) * overlap * 0.5f;
+                                nv.vy -= Math.sin(ang) * overlap * 0.5f;
+                                nv2.vx += Math.cos(ang) * overlap * 0.5f;
+                                nv2.vy += Math.sin(ang) * overlap * 0.5f;
+                                }
+
+
+                                // first, move them apart
+                                nv.x -= Math.cos(ang) * overlap/2;
+                                nv.y -= Math.sin(ang) * overlap/2;
+                                nv2.x += Math.cos(ang) * overlap/2;
+                                nv2.y += Math.sin(ang) * overlap/2;
+
+                                // next, figure out velocities
+                                final float sap = 0f; // randfrange(0,0.25f);
+
+                                final float mag1 = mag(nv.vx, nv.vy) * (1f-sap);
+                                final float mag2 = mag(nv2.vx, nv2.vy) * (1f-sap);
+
+
+                                // hacky way to transfer "momentum"
+                                nv.vx = mag2 * (float)Math.cos(ang);
+                                nv.vy = mag2 * (float)Math.sin(ang);
+                                nv2.vx = -mag1 * (float)Math.cos(ang);
+                                nv2.vy = -mag1 * (float)Math.sin(ang);
+
+                                final float totalva = nv.va + nv2.va;
+                                final float frac = randfrange(0.25f,0.75f);
+                                nv.va = totalva * frac;
+                                nv2.va = totalva * (1f-frac);
+//                                nv.va += randfrange(-20,20);
+//                                nv2.va += randfrange(-20,20);
+
+                            }
+                        }
+
+                        nv.setRotation(nv.a);
+                        nv.setX(nv.x-nv.getPivotX());
+                        nv.setY(nv.y-nv.getPivotY());
+
+                        if (   nv.x < - MAX_RADIUS
+                            || nv.x > boardWidth + MAX_RADIUS
+                            || nv.y < -MAX_RADIUS
+                            || nv.y > boardHeight + MAX_RADIUS)
+                        {
+                            nv.reset();
+                        }
+                    }
+
+                    if (DEBUG) invalidate();
+                }
+            });
+        }
+
+        @Override
+        protected void onSizeChanged (int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w,h,oldw,oldh);
+            boardWidth = w;
+            boardHeight = h;
+//            android.util.Log.d("Nyandroid", "resized: " + w + "x" + h);
+            post(new Runnable() { public void run() {
+                reset();
+                mAnim.start();
+            } });
+        }
+
+
+        @Override
+        protected void onDetachedFromWindow() {
+            super.onDetachedFromWindow();
+            mAnim.cancel();
+        }
+
+        @Override
+        public boolean isOpaque() {
+            return false;
+        }
+
+        @Override
+        public void onDraw(Canvas c) {
+            if (DEBUG) {
+                //android.util.Log.d("BeanBag", "onDraw");
+                Paint pt = new Paint();
+                pt.setAntiAlias(true);
+                pt.setStyle(Paint.Style.STROKE);
+                pt.setColor(0xFFFF0000);
+                pt.setStrokeWidth(4.0f);
+                c.drawRect(0, 0, getWidth(), getHeight(), pt);
+                pt.setColor(0xFFFFCC00);
+                pt.setStrokeWidth(1.0f);
+                for (int i=0; i<getChildCount(); i++) {
+                    Bean b = (Bean) getChildAt(i);
+                    final float a = (360-b.a)/180f*3.14159f;
+                    final float tx = b.getTranslationX();
+                    final float ty = b.getTranslationY();
+                    c.drawCircle(b.x, b.y, b.r, pt);
+                    c.drawCircle(tx, ty, 4, pt);
+                    c.drawLine(b.x, b.y, (float)(b.x+b.r*Math.sin(a)), (float)(b.y+b.r*Math.cos(a)), pt);
+                }
+            }
+        }
+    }
+
+    private Board mBoard;
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        getWindow().addFlags(
+                  WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                );
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mBoard = new Board(this, null);
+        setContentView(mBoard);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index c5928f1..7a7afa7 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -34,6 +34,7 @@
         View getChildAtPosition(MotionEvent ev);
         View getChildAtPosition(float x, float y);
         boolean canChildBeExpanded(View v);
+        boolean setUserExpandedChild(View v, boolean userxpanded);
     }
 
     private static final String TAG = "ExpandHelper";
@@ -272,6 +273,7 @@
         mScaleAnimation.start();
         mStretching = false;
         setGlow(0f);
+        mCallback.setUserExpandedChild(mCurrView, h == mNaturalHeight);
         if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
         clearView();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Nyandroid.java b/packages/SystemUI/src/com/android/systemui/Nyandroid.java
deleted file mode 100644
index 6f168ba..0000000
--- a/packages/SystemUI/src/com/android/systemui/Nyandroid.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*);
- * Copyright (C) 2011 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.animation.AnimatorSet;
-import android.animation.PropertyValuesHolder;
-import android.animation.ObjectAnimator;
-import android.animation.TimeAnimator;
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Pair;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import java.util.HashMap;
-import java.util.Random;
-
-public class Nyandroid extends Activity {
-    final static boolean DEBUG = false;
-
-    public static class Board extends FrameLayout
-    {
-        public static final boolean FIXED_STARS = true;
-        public static final int NUM_CATS = 20;
-
-        static Random sRNG = new Random();
-
-        static float lerp(float a, float b, float f) {
-            return (b-a)*f + a;
-        }
-
-        static float randfrange(float a, float b) {
-            return lerp(a, b, sRNG.nextFloat());
-        }
-
-        static int randsign() {
-            return sRNG.nextBoolean() ? 1 : -1;
-        }
-
-        static <E> E pick(E[] array) {
-            if (array.length == 0) return null;
-            return array[sRNG.nextInt(array.length)];
-        }
-
-        public class FlyingCat extends ImageView {
-            public static final float VMAX = 1000.0f;
-            public static final float VMIN = 100.0f;
-
-            public float v, vr;
-
-            public float dist;
-            public float z;
-
-            public ComponentName component;
-
-            public FlyingCat(Context context, AttributeSet as) {
-                super(context, as);
-                setImageResource(R.drawable.nyandroid_anim); // @@@
-
-                if (DEBUG) setBackgroundColor(0x80FF0000);
-            }
-
-            public String toString() {
-                return String.format("<cat (%.1f, %.1f) (%d x %d)>",
-                    getX(), getY(), getWidth(), getHeight());
-            }
-
-            public void reset() {
-                final float scale = lerp(0.1f,2f,z);
-                setScaleX(scale); setScaleY(scale);
-
-                setX(-scale*getWidth()+1);
-                setY(randfrange(0, Board.this.getHeight()-scale*getHeight()));
-                v = lerp(VMIN, VMAX, z);
-
-                dist = 0;
-
-//                android.util.Log.d("Nyandroid", "reset cat: " + this);
-            }
-
-            public void update(float dt) {
-                dist += v * dt;
-                setX(getX() + v * dt);
-            }
-        }
-
-        TimeAnimator mAnim;
-
-        public Board(Context context, AttributeSet as) {
-            super(context, as);
-
-            setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
-            setBackgroundColor(0xFF003366);
-        }
-
-        private void reset() {
-//            android.util.Log.d("Nyandroid", "board reset");
-            removeAllViews();
-
-            final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
-                        ViewGroup.LayoutParams.WRAP_CONTENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT);
-
-            if (FIXED_STARS) {
-                for(int i=0; i<20; i++) {
-                    ImageView fixedStar = new ImageView(getContext(), null);
-                    if (DEBUG) fixedStar.setBackgroundColor(0x8000FF80);
-                    fixedStar.setImageResource(R.drawable.star_anim); // @@@
-                    addView(fixedStar, wrap);
-                    final float scale = randfrange(0.1f, 1f);
-                    fixedStar.setScaleX(scale); fixedStar.setScaleY(scale);
-                    fixedStar.setX(randfrange(0, getWidth()));
-                    fixedStar.setY(randfrange(0, getHeight()));
-                    final AnimationDrawable anim = (AnimationDrawable) fixedStar.getDrawable();
-                    postDelayed(new Runnable() { 
-                        public void run() {
-                            anim.start();
-                        }}, (int) randfrange(0, 1000));
-                }
-            }
-
-            for(int i=0; i<NUM_CATS; i++) {
-                FlyingCat nv = new FlyingCat(getContext(), null);
-                addView(nv, wrap);
-                nv.z = ((float)i/NUM_CATS);
-                nv.z *= nv.z;
-                nv.reset();
-                nv.setX(randfrange(0,Board.this.getWidth()));
-                final AnimationDrawable anim = (AnimationDrawable) nv.getDrawable();
-                postDelayed(new Runnable() { 
-                    public void run() {
-                        anim.start();
-                    }}, (int) randfrange(0, 1000));
-            }
-
-            if (mAnim != null) {
-                mAnim.cancel();
-            }
-            mAnim = new TimeAnimator();
-            mAnim.setTimeListener(new TimeAnimator.TimeListener() {
-                public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
-                    // setRotation(totalTime * 0.01f); // not as cool as you would think
-//                    android.util.Log.d("Nyandroid", "t=" + totalTime);
-
-                    for (int i=0; i<getChildCount(); i++) {
-                        View v = getChildAt(i);
-                        if (!(v instanceof FlyingCat)) continue;
-                        FlyingCat nv = (FlyingCat) v;
-                        nv.update(deltaTime / 1000f);
-                        final float catWidth = nv.getWidth() * nv.getScaleX();
-                        final float catHeight = nv.getHeight() * nv.getScaleY();
-                        if (   nv.getX() + catWidth < -2
-                            || nv.getX() > getWidth() + 2
-                            || nv.getY() + catHeight < -2
-                            || nv.getY() > getHeight() + 2)
-                        {
-                            nv.reset();
-                        }
-                    }
-                }
-            });
-        }
-
-        @Override
-        protected void onSizeChanged (int w, int h, int oldw, int oldh) {
-            super.onSizeChanged(w,h,oldw,oldh);
-//            android.util.Log.d("Nyandroid", "resized: " + w + "x" + h);
-            post(new Runnable() { public void run() { 
-                reset();
-                mAnim.start(); 
-            } });
-        }
-
-
-        @Override
-        protected void onDetachedFromWindow() {
-            super.onDetachedFromWindow();
-            mAnim.cancel();
-        }
-
-        @Override
-        public boolean isOpaque() {
-            return true;
-        }
-    }
-
-    private Board mBoard;
-
-    @Override
-    public void onStart() {
-        super.onStart();
-
-        getWindow().addFlags(
-                  WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                );
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mBoard = new Board(this, null);
-        setContentView(mBoard);
-
-        mBoard.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
-            @Override
-            public void onSystemUiVisibilityChange(int vis) {
-                if (0 == (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) {
-                    Nyandroid.this.finish();
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onUserInteraction() {
-//        android.util.Log.d("Nyandroid", "finishing on user interaction");
-        finish();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 185ca5b..57f15a8 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -146,7 +146,7 @@
         }
     }
 
-    public void show(boolean show, boolean animate) {
+    public void show(final boolean show, boolean animate) {
         if (animate) {
             if (mShowing != show) {
                 mShowing = show;
@@ -156,21 +156,24 @@
             mShowing = show;
             onAnimationEnd(null);
         }
-        setVisibility(show ? View.VISIBLE : View.GONE);
-        if (show) {
-            setFocusable(true);
-            setFocusableInTouchMode(true);
-            requestFocus();
-        }
+        postDelayed(new Runnable() {
+            public void run() {
+                setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+                if (show) {
+                    setFocusable(true);
+                    setFocusableInTouchMode(true);
+                    requestFocus();
+                }
+            }
+        }, show ? 0 : 100);
     }
 
     public void hide(boolean animate) {
-        if (!animate) {
-            setVisibility(View.GONE);
-        }
         if (mBar != null) {
             // This will indirectly cause show(false, ...) to get called
             mBar.animateCollapse();
+        } else {
+            setVisibility(View.INVISIBLE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
index dc2f0be..a8c2020 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
@@ -21,21 +21,21 @@
 import android.animation.AnimatorSet.Builder;
 import android.animation.ObjectAnimator;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.util.Slog;
 import android.view.View;
+import android.view.ViewRootImpl;
 
 /* package */ class Choreographer implements Animator.AnimatorListener {
     // should group this into a multi-property animation
     private static final int OPEN_DURATION = 136;
-    private static final int CLOSE_DURATION = 250;
+    private static final int CLOSE_DURATION = 130;
     private static final int SCRIM_DURATION = 400;
     private static final String TAG = RecentsPanelView.TAG;
     private static final boolean DEBUG = RecentsPanelView.DEBUG;
 
     boolean mVisible;
     int mPanelHeight;
-    View mRootView;
+    RecentsPanelView mRootView;
     View mScrimView;
     View mContentView;
     View mNoRecentAppsView;
@@ -45,7 +45,7 @@
     // the panel will start to appear this many px from the end
     final int HYPERSPACE_OFFRAMP = 200;
 
-    public Choreographer(View root, View scrim, View content,
+    public Choreographer(RecentsPanelView root, View scrim, View content,
             View noRecentApps, Animator.AnimatorListener listener) {
         mRootView = root;
         mScrimView = scrim;
@@ -67,7 +67,7 @@
             end = 0;
         } else {
             start = y;
-            end = y + HYPERSPACE_OFFRAMP;
+            end = y;
         }
 
         Animator posAnim = ObjectAnimator.ofFloat(mContentView, "translationY",
@@ -77,12 +77,12 @@
                 : new android.view.animation.AccelerateInterpolator(2.5f));
         posAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
 
-        Animator glowAnim = ObjectAnimator.ofFloat(mContentView, "alpha",
+        Animator fadeAnim = ObjectAnimator.ofFloat(mContentView, "alpha",
                 mContentView.getAlpha(), appearing ? 1.0f : 0.0f);
-        glowAnim.setInterpolator(appearing
+        fadeAnim.setInterpolator(appearing
                 ? new android.view.animation.AccelerateInterpolator(1.0f)
                 : new android.view.animation.DecelerateInterpolator(1.0f));
-        glowAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
+        fadeAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
 
         Animator noRecentAppsFadeAnim = null;
         if (mNoRecentAppsView != null &&  // doesn't exist on large devices
@@ -96,7 +96,7 @@
         }
 
         mContentAnim = new AnimatorSet();
-        final Builder builder = mContentAnim.play(glowAnim).with(posAnim);
+        final Builder builder = mContentAnim.play(fadeAnim).with(posAnim);
 
         if (noRecentAppsFadeAnim != null) {
             builder.with(noRecentAppsFadeAnim);
@@ -153,9 +153,10 @@
     public void onAnimationEnd(Animator animation) {
         if (DEBUG) Slog.d(TAG, "onAnimationEnd");
         if (!mVisible) {
-            mRootView.setVisibility(View.GONE);
+            mRootView.hideWindow();
         }
         mContentView.setLayerType(View.LAYER_TYPE_NONE, null);
+        mContentView.setAlpha(1f);
         mContentAnim = null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e865b9c..feb1ac8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -26,7 +26,9 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Matrix;
+import android.graphics.Rect;
 import android.graphics.Shader.TileMode;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
@@ -48,11 +50,9 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
 import android.widget.FrameLayout;
-import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
 import android.widget.PopupMenu;
-import android.widget.ScrollView;
 import android.widget.TextView;
 
 import com.android.systemui.R;
@@ -83,6 +83,9 @@
     private Choreographer mChoreo;
     OnRecentsPanelVisibilityChangedListener mVisibilityChangedListener;
 
+    ImageView mPlaceholderThumbnail;
+    boolean mHideWindowAfterPlaceholderThumbnailIsHidden;
+
     private RecentTasksLoader mRecentTasksLoader;
     private ArrayList<TaskDescription> mRecentTaskDescriptions;
     private Runnable mPreloadTasksRunnable;
@@ -91,6 +94,7 @@
     private int mThumbnailWidth;
     private boolean mFitThumbnailToXY;
     private int mRecentItemLayoutId;
+    private boolean mFirstScreenful = true;
 
     public static interface OnRecentsPanelVisibilityChangedListener {
         public void onRecentsPanelVisibilityChanged(boolean visible);
@@ -206,6 +210,22 @@
         }
     }
 
+    public RecentsPanelView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mContext = context;
+        updateValuesFromResources();
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
+                defStyle, 0);
+
+        mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
+        a.recycle();
+    }
+
     public int numItemsInOneScreenful() {
         if (mRecentsContainer instanceof RecentsScrollView){
             RecentsScrollView scrollView
@@ -266,7 +286,9 @@
     public void show(boolean show, boolean animate,
             ArrayList<TaskDescription> recentTaskDescriptions, boolean firstScreenful) {
         // For now, disable animations. We may want to re-enable in the future
-        animate = false;
+        if (show) {
+            animate = false;
+        }
         if (show) {
             // Need to update list of recent apps before we set visibility so this view's
             // content description is updated before it gets focus for TalkBack mode
@@ -297,6 +319,7 @@
             mRecentTasksDirty = true;
             mWaitingToShow = false;
             mReadyToShow = false;
+            mRecentsNoApps.setVisibility(View.INVISIBLE);
         }
         if (animate) {
             if (mShowing != show) {
@@ -415,21 +438,6 @@
         super.setVisibility(visibility);
     }
 
-    public RecentsPanelView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        mContext = context;
-        updateValuesFromResources();
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
-                defStyle, 0);
-
-        mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
-    }
-
     public void updateValuesFromResources() {
         final Resources res = mContext.getResources();
         mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
@@ -572,7 +580,7 @@
         showIfReady();
     }
 
-    // additional optimization when we have sofware system buttons - start loading the recent
+    // additional optimization when we have software system buttons - start loading the recent
     // tasks on touch down
     @Override
     public boolean onTouch(View v, MotionEvent ev) {
@@ -631,7 +639,6 @@
         }
     }
 
-    boolean mFirstScreenful;
     public void onTasksLoaded(ArrayList<TaskDescription> tasks) {
         if (!mFirstScreenful && tasks.size() == 0) {
             return;
@@ -685,11 +692,31 @@
                 context.getSystemService(Context.ACTIVITY_SERVICE);
         holder.thumbnailViewImage.setDrawingCacheEnabled(true);
         Bitmap bm = holder.thumbnailViewImage.getDrawingCache();
-        ActivityOptions opts = ActivityOptions.makeThumbnailScaleUpAnimation(
+        mPlaceholderThumbnail = (ImageView) findViewById(R.id.recents_transition_placeholder_icon);
+
+        final ImageView placeholderThumbnail = mPlaceholderThumbnail;
+        mHideWindowAfterPlaceholderThumbnailIsHidden = false;
+        placeholderThumbnail.setVisibility(VISIBLE);
+        Bitmap b2 = bm.copy(bm.getConfig(), true);
+        placeholderThumbnail.setImageBitmap(b2);
+
+        Rect r = new Rect();
+        holder.thumbnailViewImage.getGlobalVisibleRect(r);
+
+        placeholderThumbnail.setTranslationX(r.left);
+        placeholderThumbnail.setTranslationY(r.top);
+
+        show(false, true);
+
+        ActivityOptions opts = ActivityOptions.makeDelayedThumbnailScaleUpAnimation(
                 holder.thumbnailViewImage, bm, 0, 0,
                 new ActivityOptions.OnAnimationStartedListener() {
                     @Override public void onAnimationStarted() {
-                        hide(true);
+                        mPlaceholderThumbnail = null;
+                        placeholderThumbnail.setVisibility(INVISIBLE);
+                        if (mHideWindowAfterPlaceholderThumbnailIsHidden) {
+                            hideWindow();
+                        }
                     }
                 });
         if (ad.taskId >= 0) {
@@ -707,6 +734,15 @@
         holder.thumbnailViewImage.setDrawingCacheEnabled(false);
     }
 
+    public void hideWindow() {
+        if (mPlaceholderThumbnail != null) {
+            mHideWindowAfterPlaceholderThumbnailIsHidden = true;
+        } else {
+            setVisibility(GONE);
+            mHideWindowAfterPlaceholderThumbnailIsHidden = false;
+        }
+    }
+
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         handleOnClick(view);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f0db2bce..a310b1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -20,6 +20,7 @@
 
 import android.app.ActivityManagerNative;
 import android.app.KeyguardManager;
+import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +35,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
@@ -46,6 +48,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RemoteViews;
 import android.widget.PopupMenu;
@@ -61,6 +64,7 @@
 import com.android.systemui.recent.RecentTasksLoader;
 import com.android.systemui.recent.TaskDescription;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.policy.NotificationRowLayout;
 import com.android.systemui.statusbar.tablet.StatusBarPanel;
 
 import com.android.systemui.R;
@@ -76,11 +80,24 @@
     protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
     protected static final int MSG_OPEN_SEARCH_PANEL = 1024;
     protected static final int MSG_CLOSE_SEARCH_PANEL = 1025;
+    protected static final int MSG_SHOW_INTRUDER = 1026;
+    protected static final int MSG_HIDE_INTRUDER = 1027;
+
+    protected static final boolean ENABLE_INTRUDERS = false;
+
+    public static final int EXPANDED_LEAVE_ALONE = -10000;
+    public static final int EXPANDED_FULL_OPEN = -10001;
 
     protected CommandQueue mCommandQueue;
     protected IStatusBarService mBarService;
     protected H mHandler = createHandler();
 
+    // all notifications
+    protected NotificationData mNotificationData = new NotificationData();
+    protected NotificationRowLayout mPile;
+
+    protected StatusBarNotification mCurrentlyIntrudingNotification;
+
     // used to notify status bar for suppressing notification LED
     protected boolean mPanelSlightlyVisible;
 
@@ -469,17 +486,7 @@
         // for blaming (see SwipeHelper.setLongPressListener)
         row.setTag(sbn.pkg);
 
-        // XXX: temporary: while testing big notifications, auto-expand all of them
         ViewGroup.LayoutParams lp = row.getLayoutParams();
-        Boolean expandable = Boolean.FALSE;
-        if (large != null) {
-            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
-            expandable = Boolean.TRUE;
-        } else {
-            lp.height = rowHeight;
-        }
-        row.setLayoutParams(lp);
-        row.setTag(R.id.expandable_tag, expandable);
         workAroundBadLayerDrawableOpacity(row);
         View vetoButton = updateNotificationVetoButton(row, sbn);
         vetoButton.setContentDescription(mContext.getString(
@@ -545,10 +552,11 @@
 
         applyLegacyRowBackground(sbn, content);
 
+        row.setTag(R.id.expandable_tag, Boolean.valueOf(large != null));
         entry.row = row;
         entry.content = content;
         entry.expanded = expandedOneU;
-        entry.expandedLarge = expandedOneU;
+        entry.setLargeView(expandedLarge);
 
         return true;
     }
@@ -633,4 +641,232 @@
         }
     }
 
+    /**
+     * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
+     * about the failure.
+     *
+     * WARNING: this will call back into us.  Don't hold any locks.
+     */
+    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
+        removeNotification(key);
+        try {
+            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
+        } catch (RemoteException ex) {
+            // The end is nigh.
+        }
+    }
+
+    protected StatusBarNotification removeNotificationViews(IBinder key) {
+        NotificationData.Entry entry = mNotificationData.remove(key);
+        if (entry == null) {
+            Slog.w(TAG, "removeNotification for unknown key: " + key);
+            return null;
+        }
+        // Remove the expanded view.
+        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
+        if (rowParent != null) rowParent.removeView(entry.row);
+        updateExpansionStates();
+        updateNotificationIcons();
+
+        return entry.notification;
+    }
+
+    protected StatusBarIconView addNotificationViews(IBinder key,
+            StatusBarNotification notification) {
+        if (DEBUG) {
+            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
+        }
+        // Construct the icon.
+        final StatusBarIconView iconView = new StatusBarIconView(mContext,
+                notification.pkg + "/0x" + Integer.toHexString(notification.id),
+                notification.notification);
+        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+
+        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
+                    notification.notification.icon,
+                    notification.notification.iconLevel,
+                    notification.notification.number,
+                    notification.notification.tickerText);
+        if (!iconView.set(ic)) {
+            handleNotificationError(key, notification, "Couldn't create icon: " + ic);
+            return null;
+        }
+        // Construct the expanded view.
+        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
+        if (!inflateViews(entry, mPile)) {
+            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
+                    + notification);
+            return null;
+        }
+
+        // Add the expanded view and icon.
+        int pos = mNotificationData.add(entry);
+        if (DEBUG) {
+            Slog.d(TAG, "addNotificationViews: added at " + pos);
+        }
+        updateExpansionStates();
+        updateNotificationIcons();
+
+        return iconView;
+    }
+
+    protected boolean expandView(NotificationData.Entry entry, boolean expand) {
+        if (entry.expandable()) {
+            int rowHeight =
+                    mContext.getResources().getDimensionPixelSize(R.dimen.notification_height);
+            ViewGroup.LayoutParams lp = entry.row.getLayoutParams();
+            if (expand) {
+                lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+            } else {
+                lp.height = rowHeight;
+            }
+            entry.row.setLayoutParams(lp);
+            return expand;
+        } else {
+            return false;
+        }
+    }
+
+    protected void updateExpansionStates() {
+        int N = mNotificationData.size();
+        for (int i = 0; i < N; i++) {
+            NotificationData.Entry entry = mNotificationData.get(i);
+            if (i == (N-1)) {
+                if (DEBUG) Slog.d(TAG, "expanding top notification at " + i);
+                expandView(entry, true);
+            } else {
+                if (!entry.userExpanded()) {
+                    if (DEBUG) Slog.d(TAG, "collapsing notification at " + i);
+                    expandView(entry, false);
+                } else {
+                    if (DEBUG) Slog.d(TAG, "ignoring user-modified notification at " + i);
+                }
+            }
+        }
+    }
+
+    protected abstract void haltTicker();
+    protected abstract void setAreThereNotifications();
+    protected abstract void updateNotificationIcons();
+    protected abstract void tick(IBinder key, StatusBarNotification n, boolean firstTime);
+    protected abstract void updateExpandedViewPos(int expandedPosition);
+    protected abstract int getExpandedViewMaxHeight();
+
+    protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
+        return parent.indexOfChild(entry.row) == 0;
+    }
+
+    public void updateNotification(IBinder key, StatusBarNotification notification) {
+        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
+
+        final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
+        if (oldEntry == null) {
+            Slog.w(TAG, "updateNotification for unknown key: " + key);
+            return;
+        }
+
+        final StatusBarNotification oldNotification = oldEntry.notification;
+
+        // XXX: modify when we do something more intelligent with the two content views
+        final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null)
+                ? oldNotification.notification.bigContentView
+                : oldNotification.notification.contentView;
+        final RemoteViews contentView = (notification.notification.bigContentView != null)
+                ? notification.notification.bigContentView
+                : notification.notification.contentView;
+
+        if (DEBUG) {
+            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
+                    + " ongoing=" + oldNotification.isOngoing()
+                    + " expanded=" + oldEntry.expanded
+                    + " contentView=" + oldContentView
+                    + " rowParent=" + oldEntry.row.getParent());
+            Slog.d(TAG, "new notification: when=" + notification.notification.when
+                    + " ongoing=" + oldNotification.isOngoing()
+                    + " contentView=" + contentView);
+        }
+
+        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
+        // didn't change.
+        boolean contentsUnchanged = oldEntry.expanded != null
+                && contentView != null && oldContentView != null
+                && contentView.getPackage() != null
+                && oldContentView.getPackage() != null
+                && oldContentView.getPackage().equals(contentView.getPackage())
+                && oldContentView.getLayoutId() == contentView.getLayoutId();
+        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
+        boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
+                && notification.score == oldNotification.score;
+                // score now encompasses/supersedes isOngoing()
+
+        boolean updateTicker = notification.notification.tickerText != null
+                && !TextUtils.equals(notification.notification.tickerText,
+                        oldEntry.notification.notification.tickerText);
+        boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
+        if (contentsUnchanged && (orderUnchanged || isTopAnyway)) {
+            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
+            oldEntry.notification = notification;
+            try {
+                // Reapply the RemoteViews
+                contentView.reapply(mContext, oldEntry.content);
+                // update the contentIntent
+                final PendingIntent contentIntent = notification.notification.contentIntent;
+                if (contentIntent != null) {
+                    final View.OnClickListener listener = makeClicker(contentIntent,
+                            notification.pkg, notification.tag, notification.id);
+                    oldEntry.content.setOnClickListener(listener);
+                } else {
+                    oldEntry.content.setOnClickListener(null);
+                }
+                // Update the icon.
+                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
+                        notification.notification.icon, notification.notification.iconLevel,
+                        notification.notification.number,
+                        notification.notification.tickerText);
+                if (!oldEntry.icon.set(ic)) {
+                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
+                    return;
+                }
+                updateExpansionStates();
+            }
+            catch (RuntimeException e) {
+                // It failed to add cleanly.  Log, and remove the view from the panel.
+                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
+                removeNotificationViews(key);
+                addNotificationViews(key, notification);
+            }
+        } else {
+            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
+            if (DEBUG) Slog.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
+            if (DEBUG) Slog.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
+            if (DEBUG) Slog.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
+            removeNotificationViews(key);
+            addNotificationViews(key, notification);
+        }
+
+        // Update the veto button accordingly (and as a result, whether this row is
+        // swipe-dismissable)
+        updateNotificationVetoButton(oldEntry.row, notification);
+
+        // Restart the ticker if it's still running
+        if (updateTicker) {
+            haltTicker();
+            tick(key, notification, false);
+        }
+
+        // Recalculate the position of the sliding windows and the titles.
+        setAreThereNotifications();
+        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+
+        // See if we need to update the intruder.
+        if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
+            if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
+            // XXX: this is a hack for Alarms. The real implementation will need to *update*
+            // the intruder.
+            if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
+                if (DEBUG) Slog.d(TAG, "no longer intrudes!");
+                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 3ff85d9..1a07ed3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -22,6 +22,7 @@
 import android.widget.ImageView;
 
 import com.android.internal.statusbar.StatusBarNotification;
+import com.android.systemui.R;
 
 import java.util.Comparator;
 import java.util.ArrayList;
@@ -38,13 +39,32 @@
         public View content; // takes the click events and sends the PendingIntent
         public View expanded; // the inflated RemoteViews
         public ImageView largeIcon;
-        public View expandedLarge;
+        protected View expandedLarge;
         public Entry() {}
         public Entry(IBinder key, StatusBarNotification n, StatusBarIconView ic) {
             this.key = key;
             this.notification = n;
             this.icon = ic;
         }
+        public void setLargeView(View expandedLarge) {
+            this.expandedLarge = expandedLarge;
+            writeBooleanTag(row, R.id.expandable_tag, expandedLarge != null);
+        }
+        public View getLargeView() {
+            return expandedLarge;
+        }
+        /**
+         * Return whether the entry can be expanded.
+         */
+        public boolean expandable() {
+            return NotificationData.getIsExpandable(row);
+        }
+        /**
+         * Return whether the entry has been manually expanded by the user.
+         */
+        public boolean userExpanded() {
+            return NotificationData.getUserExpanded(row);
+        }
     }
     private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
     private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() {
@@ -134,4 +154,41 @@
         }
         return false;
     }
+
+    protected static boolean readBooleanTag(View view, int id)  {
+        if (view != null) {
+            Object value = view.getTag(id);
+            return value != null && value instanceof Boolean && ((Boolean) value).booleanValue();
+        }
+        return false;
+    }
+
+    protected static boolean writeBooleanTag(View view, int id, boolean value)  {
+        if (view != null) {
+            view.setTag(id, Boolean.valueOf(value));
+            return value;
+        }
+        return false;
+    }
+
+    /**
+     * Return whether the entry can be expanded.
+     */
+    public static boolean getIsExpandable(View row) {
+        return readBooleanTag(row, R.id.expandable_tag);
+    }
+
+    /**
+     * Return whether the entry has been manually expanded by the user.
+     */
+    public static boolean getUserExpanded(View row) {
+        return readBooleanTag(row, R.id.user_expanded_tag);
+    }
+
+    /**
+     * Set whether the entry has been manually expanded by the user.
+     */
+    public static boolean setUserExpanded(View row, boolean userExpanded) {
+        return writeBooleanTag(row, R.id.user_expanded_tag, userExpanded);
+    }
 }
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 f6f41b8..d3fbdab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -42,7 +42,6 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Slog;
@@ -105,15 +104,10 @@
     public static final String ACTION_STATUSBAR_START
             = "com.android.internal.policy.statusbar.START";
 
-    private static final boolean ENABLE_INTRUDERS = false;
-
-    static final int EXPANDED_LEAVE_ALONE = -10000;
-    static final int EXPANDED_FULL_OPEN = -10001;
+    private static final boolean DIM_BEHIND_EXPANDED_PANEL = false;
 
     private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
     private static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
-    private static final int MSG_SHOW_INTRUDER = 1002;
-    private static final int MSG_HIDE_INTRUDER = 1003;
     // 1020-1030 reserved for BaseStatusBar
 
     // will likely move to a resource or other tunable param at some point
@@ -178,10 +172,6 @@
     CloseDragHandle mCloseView;
     private int mCloseViewHeight;
 
-    // all notifications
-    NotificationData mNotificationData = new NotificationData();
-    NotificationRowLayout mPile;
-
     // position
     int[] mPositionTmp = new int[2];
     boolean mExpanded;
@@ -212,6 +202,7 @@
 
     Choreographer mChoreographer;
     boolean mAnimating;
+    boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
     float mAnimY;
     float mAnimVel;
     float mAnimAccel;
@@ -311,6 +302,12 @@
             }
         });
 
+        if (!ActivityManager.isHighEndGfx(mDisplay)) {
+            mStatusBarWindow.setBackground(null);
+            mNotificationPanel.setBackgroundColor(context.getResources().getColor(
+                    R.color.notification_panel_solid_background));
+        }
+
         if (ENABLE_INTRUDERS) {
             mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
             mIntruderAlertView.setVisibility(View.GONE);
@@ -459,6 +456,9 @@
         // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
         // a bit jarring
         mRecentsPanel.setMinSwipeAlpha(0.03f);
+        if (mNavigationBarView != null) {
+            mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
+        }
     }
 
     @Override
@@ -474,7 +474,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
         lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
     }
 
@@ -484,7 +483,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
         lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
     }
 
@@ -510,7 +508,7 @@
             toggleRecentApps();
         }
     };
-    private StatusBarNotification mCurrentlyIntrudingNotification;
+
     View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
         public boolean onTouch(View v, MotionEvent event) {
             switch(event.getAction()) {
@@ -565,8 +563,7 @@
                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_SLIPPERY,
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.OPAQUE);
         // this will allow the navbar to run in an overlay on devices that support this
         if (ActivityManager.isHighEndGfx(mDisplay)) {
@@ -685,7 +682,7 @@
 
             // show the ticker if there isn't an intruder too
             if (mCurrentlyIntrudingNotification == null) {
-                tick(notification);
+                tick(null, notification, true);
             }
         }
 
@@ -694,117 +691,6 @@
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
     }
 
-    public void updateNotification(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
-
-        final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
-        if (oldEntry == null) {
-            Slog.w(TAG, "updateNotification for unknown key: " + key);
-            return;
-        }
-
-        final StatusBarNotification oldNotification = oldEntry.notification;
-
-        // XXX: modify when we do something more intelligent with the two content views
-        final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null) 
-                ? oldNotification.notification.bigContentView
-                : oldNotification.notification.contentView;
-        final RemoteViews contentView = (notification.notification.bigContentView != null) 
-                ? notification.notification.bigContentView
-                : notification.notification.contentView;
-
-        if (DEBUG) {
-            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
-                    + " ongoing=" + oldNotification.isOngoing()
-                    + " expanded=" + oldEntry.expanded
-                    + " contentView=" + oldContentView
-                    + " rowParent=" + oldEntry.row.getParent());
-            Slog.d(TAG, "new notification: when=" + notification.notification.when
-                    + " ongoing=" + oldNotification.isOngoing()
-                    + " contentView=" + contentView);
-        }
-
-
-        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
-        // didn't change.
-        boolean contentsUnchanged = oldEntry.expanded != null
-                && contentView != null && oldContentView != null
-                && contentView.getPackage() != null
-                && oldContentView.getPackage() != null
-                && oldContentView.getPackage().equals(contentView.getPackage())
-                && oldContentView.getLayoutId() == contentView.getLayoutId();
-        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
-        boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
-                && notification.score == oldNotification.score;
-                // score now encompasses/supersedes isOngoing()
-
-        boolean updateTicker = notification.notification.tickerText != null
-                && !TextUtils.equals(notification.notification.tickerText,
-                        oldEntry.notification.notification.tickerText);
-        boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0;
-        if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) {
-            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
-            oldEntry.notification = notification;
-            try {
-                // Reapply the RemoteViews
-                contentView.reapply(mContext, oldEntry.content);
-                // update the contentIntent
-                final PendingIntent contentIntent = notification.notification.contentIntent;
-                if (contentIntent != null) {
-                    final View.OnClickListener listener = new NotificationClicker(contentIntent,
-                            notification.pkg, notification.tag, notification.id);
-                    oldEntry.content.setOnClickListener(listener);
-                } else {
-                    oldEntry.content.setOnClickListener(null);
-                }
-                // Update the icon.
-                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
-                        notification.notification.icon, notification.notification.iconLevel,
-                        notification.notification.number,
-                        notification.notification.tickerText);
-                if (!oldEntry.icon.set(ic)) {
-                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
-                    return;
-                }
-            }
-            catch (RuntimeException e) {
-                // It failed to add cleanly.  Log, and remove the view from the panel.
-                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
-                removeNotificationViews(key);
-                addNotificationViews(key, notification);
-            }
-        } else {
-            if (SPEW) Slog.d(TAG, "not reusing notification");
-            removeNotificationViews(key);
-            addNotificationViews(key, notification);
-        }
-
-        // Update the veto button accordingly (and as a result, whether this row is
-        // swipe-dismissable)
-        updateNotificationVetoButton(oldEntry.row, notification);
-
-        // Restart the ticker if it's still running
-        if (updateTicker) {
-            mTicker.halt();
-            tick(notification);
-        }
-
-        // Recalculate the position of the sliding windows and the titles.
-        setAreThereNotifications();
-        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
-
-        // See if we need to update the intruder.
-        if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
-            if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
-            // XXX: this is a hack for Alarms. The real implementation will need to *update* 
-            // the intruder.
-            if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
-                if (DEBUG) Slog.d(TAG, "no longer intrudes!");
-                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
-            }
-        }
-    }
-
     public void removeNotification(IBinder key) {
         StatusBarNotification old = removeNotificationViews(key);
         if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
@@ -833,44 +719,6 @@
         updateRecentsPanel();
     }
 
-
-    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) {
-            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
-        }
-        // Construct the icon.
-        final StatusBarIconView iconView = new StatusBarIconView(mContext,
-                notification.pkg + "/0x" + Integer.toHexString(notification.id),
-                notification.notification);
-        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
-
-        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
-                    notification.notification.icon,
-                    notification.notification.iconLevel,
-                    notification.notification.number,
-                    notification.notification.tickerText);
-        if (!iconView.set(ic)) {
-            handleNotificationError(key, notification, "Couldn't create icon: " + ic);
-            return null;
-        }
-        // Construct the expanded view.
-        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
-        if (!inflateViews(entry, mPile)) {
-            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
-                    + notification);
-            return null;
-        }
-
-        // Add the expanded view and icon.
-        int pos = mNotificationData.add(entry);
-        if (DEBUG) {
-            Slog.d(TAG, "addNotificationViews: added at " + pos);
-        }
-        updateNotificationIcons();
-
-        return iconView;
-    }
-
     private void loadNotificationShade() {
         int N = mNotificationData.size();
 
@@ -907,7 +755,8 @@
         updateNotificationIcons();
     }
 
-    private void updateNotificationIcons() {
+    @Override
+    protected void updateNotificationIcons() {
         loadNotificationShade();
 
         final LinearLayout.LayoutParams params
@@ -948,21 +797,8 @@
         }
     }
 
-    StatusBarNotification removeNotificationViews(IBinder key) {
-        NotificationData.Entry entry = mNotificationData.remove(key);
-        if (entry == null) {
-            Slog.w(TAG, "removeNotification for unknown key: " + key);
-            return null;
-        }
-        // Remove the expanded view.
-        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
-        if (rowParent != null) rowParent.removeView(entry.row);
-        updateNotificationIcons();
-
-        return entry.notification;
-    }
-
-    private void setAreThereNotifications() {
+    @Override
+    protected void setAreThereNotifications() {
         final boolean any = mNotificationData.size() > 0;
 
         final boolean clearable = any && mNotificationData.hasClearableItems();
@@ -1270,14 +1106,26 @@
         }
     }
 
+    void resetLastAnimTime() {
+        mAnimLastTimeNanos = System.nanoTime();
+        if (SPEW) {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            Slog.d(TAG, "resetting last anim time=" + mAnimLastTimeNanos, t);
+        }
+    }
+
     void doAnimation(long frameTimeNanos) {
         if (mAnimating) {
-            if (SPEW) Slog.d(TAG, "doAnimation");
+            if (SPEW) Slog.d(TAG, "doAnimation dt=" + (frameTimeNanos - mAnimLastTimeNanos));
             if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
             incrementAnim(frameTimeNanos);
-            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
+            if (SPEW) {
+                Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
+                Slog.d(TAG, "doAnimation expandedViewMax=" + getExpandedViewMaxHeight());
+            }
 
-            if (mAnimY >= getExpandedViewMaxHeight()-1) {
+            if (mAnimY >= getExpandedViewMaxHeight()-1 && !mClosing) {
                 if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
                 mAnimating = false;
                 updateExpandedViewPos(EXPANDED_FULL_OPEN);
@@ -1285,14 +1133,14 @@
                 return;
             }
 
-            if (mAnimY == 0 && mAnimAccel == 0 && mAnimVel == 0) {
+            if (mAnimY == 0 && mAnimAccel == 0 && mClosing) {
                 if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
                 mAnimating = false;
                 performCollapse();
                 return;
             }
 
-            if (mAnimY < getStatusBarHeight()) {
+            if (mAnimY < getStatusBarHeight() && mClosing) {
                 // Draw one more frame with the bar positioned at the top of the screen
                 // before ending the animation so that the user sees the bar in
                 // its final position.  The call to performCollapse() causes a window
@@ -1314,6 +1162,7 @@
         mPile.setLayerType(View.LAYER_TYPE_NONE, null);
         mVelocityTracker.recycle();
         mVelocityTracker = null;
+        mCloseView.setPressed(false);
     }
 
     void incrementAnim(long frameTimeNanos) {
@@ -1330,6 +1179,9 @@
     }
     
     void doRevealAnimation(long frameTimeNanos) {
+        if (SPEW) {
+            Slog.d(TAG, "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos));
+        }
         final int h = getCloseViewHeight() + getStatusBarHeight();
         if (mAnimatingReveal && mAnimating && mAnimY < h) {
             incrementAnim(frameTimeNanos);
@@ -1349,6 +1201,8 @@
             Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
         }
 
+        mCloseView.setPressed(true);
+
         mTracking = true;
         mPile.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         mVelocityTracker = VelocityTracker.obtain();
@@ -1359,7 +1213,7 @@
             updateExpandedViewPos((int)mAnimY);
             mAnimating = true;
             mAnimatingReveal = true;
-            mAnimLastTimeNanos = System.nanoTime();
+            resetLastAnimTime();
             mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
                     mAnimationCallback, null);
             mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
@@ -1433,8 +1287,9 @@
         //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
         //        + " mAnimAccel=" + mAnimAccel);
 
-        mAnimLastTimeNanos = System.nanoTime();
+        resetLastAnimTime();
         mAnimating = true;
+        mClosing = mAnimAccel < 0;
 
         mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
                 mAnimationCallback, null);
@@ -1474,8 +1329,8 @@
             if (!mExpanded) {
                 mViewDelta = statusBarSize - y;
             } else {
-//                mCloseView.getLocationOnScreen(mAbsPos)...?
-//                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
+                mCloseView.getLocationOnScreen(mAbsPos);
+                mViewDelta = mAbsPos[1] + statusBarSize + getCloseViewHeight() - y; // XXX: not closeViewHeight, but paddingBottom from the 9patch
             }
             if ((!mExpanded && y < hitSize) ||
                     // @@ add taps outside the panel if it's not full-screen
@@ -1727,7 +1582,8 @@
         }
     }
 
-    private void tick(StatusBarNotification n) {
+    @Override
+    protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
         // no ticking in lights-out mode
         if (!areLightsOn()) return;
         
@@ -1743,21 +1599,6 @@
         }
     }
 
-    /**
-     * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
-     * about the failure.
-     *
-     * WARNING: this will call back into us.  Don't hold any locks.
-     */
-    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
-        removeNotification(key);
-        try {
-            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
-        } catch (RemoteException ex) {
-            // The end is nigh.
-        }
-    }
-
     private class MyTicker extends Ticker {
         MyTicker(Context context, View sb) {
             super(context, sb);
@@ -1930,11 +1771,13 @@
         return a < 0f ? 0f : (a > 1f ? 1f : a);
     }
 
-    int getExpandedViewMaxHeight() {
+    @Override
+    protected int getExpandedViewMaxHeight() {
         return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
     }
 
-    void updateExpandedViewPos(int expandedPosition) {
+    @Override
+    protected void updateExpandedViewPos(int expandedPosition) {
         if (SPEW) {
             Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
                     //+ " mTrackingParams.y=" + ((mTrackingParams == null) ? "?" : mTrackingParams.y)
@@ -1987,11 +1830,14 @@
             Slog.v(TAG, "updated cropView height=" + panelh + " grav=" + lp.gravity);
         }
         mNotificationPanel.setLayoutParams(lp);
-        // woo, special effects
-        final int barh = getCloseViewHeight() + getStatusBarHeight();
-        final float frac = saturate((float)(panelh - barh) / (disph - barh));
-        final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24;
-        mStatusBarWindow.setBackgroundColor(color);
+
+        if (DIM_BEHIND_EXPANDED_PANEL && ActivityManager.isHighEndGfx(mDisplay)) {
+            // woo, special effects
+            final int barh = getCloseViewHeight() + getStatusBarHeight();
+            final float frac = saturate((float)(panelh - barh) / (disph - barh));
+            final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24;
+            mStatusBarWindow.setBackgroundColor(color);
+        }
     }
 
     void updateDisplaySize() {
@@ -2258,5 +2104,10 @@
             vibrate();
         }
     };
+
+    @Override
+    protected void haltTicker() {
+        mTicker.halt();
+    }
 }
 
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 a8f5c64..a9cc62a4d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -31,6 +31,7 @@
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.policy.FixedSizeDrawable;
 
 public class PhoneStatusBarView extends FrameLayout {
@@ -95,7 +96,7 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        mService.updateExpandedViewPos(PhoneStatusBar.EXPANDED_LEAVE_ALONE);
+        mService.updateExpandedViewPos(BaseStatusBar.EXPANDED_LEAVE_ALONE);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 03dfd1c..0fe7a0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -39,6 +39,7 @@
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.NotificationData;
 
 import java.util.HashMap;
 
@@ -175,9 +176,11 @@
     }
 
     public boolean canChildBeExpanded(View v) {
-        Object isExpandable = v.getTag(R.id.expandable_tag);
-        return isExpandable != null && isExpandable instanceof Boolean &&
-                ((Boolean)isExpandable).booleanValue();
+        return NotificationData.getIsExpandable(v);
+    }
+
+    public boolean setUserExpandedChild(View v, boolean userExpanded) {
+        return NotificationData.setUserExpanded(v, userExpanded);
     }
 
     public void onChildDismissed(View v) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index a394596..906d1aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -109,7 +109,6 @@
     private static final boolean FAKE_SPACE_BAR = true;
 
     // Notification "peeking" (flyover preview of individual notifications)
-    final static boolean NOTIFICATION_PEEK_ENABLED = false;
     final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms
     final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms
 
@@ -127,9 +126,6 @@
 
     IWindowManager mWindowManager;
 
-    // tracking all current notifications
-    private NotificationData mNotificationData = new NotificationData();
-
     TabletStatusBarView mStatusBarView;
     View mNotificationArea;
     View mNotificationTrigger;
@@ -160,8 +156,6 @@
     int mNotificationPeekTapDuration;
     int mNotificationFlingVelocity;
 
-    NotificationRowLayout mPile;
-
     BatteryController mBatteryController;
     BluetoothController mBluetoothController;
     LocationController mLocationController;
@@ -290,47 +284,6 @@
 
         WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
 
-        // Notification preview window
-        if (NOTIFICATION_PEEK_ENABLED) {
-            mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
-                    R.layout.system_bar_notification_peek, null);
-            mNotificationPeekWindow.setBar(this);
-
-            mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
-            mNotificationPeekWindow.setVisibility(View.GONE);
-            mNotificationPeekWindow.setOnTouchListener(
-                    new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow));
-            mNotificationPeekScrubRight = new LayoutTransition();
-            mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING,
-                    ObjectAnimator.ofInt(null, "left", -512, 0));
-            mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING,
-                    ObjectAnimator.ofInt(null, "left", -512, 0));
-            mNotificationPeekScrubRight.setDuration(500);
-
-            mNotificationPeekScrubLeft = new LayoutTransition();
-            mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING,
-                    ObjectAnimator.ofInt(null, "left", 512, 0));
-            mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING,
-                    ObjectAnimator.ofInt(null, "left", 512, 0));
-            mNotificationPeekScrubLeft.setDuration(500);
-
-            // XXX: setIgnoreChildren?
-            lp = new WindowManager.LayoutParams(
-                    512, // ViewGroup.LayoutParams.WRAP_CONTENT,
-                    ViewGroup.LayoutParams.WRAP_CONTENT,
-                    WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                    PixelFormat.TRANSLUCENT);
-            lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
-            lp.y = res.getDimensionPixelOffset(R.dimen.peek_window_y_offset);
-            lp.setTitle("NotificationPeekWindow");
-            lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
-
-            WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp);
-        }
-
         // Recents Panel
         mRecentTasksLoader = new RecentTasksLoader(context);
         updateRecentsPanel();
@@ -395,6 +348,11 @@
         scroller.setFillViewport(true);
     }
 
+    @Override
+    protected int getExpandedViewMaxHeight() {
+        return getNotificationPanelHeight();
+    }
+
     private int getNotificationPanelHeight() {
         final Resources res = mContext.getResources();
         final Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
@@ -494,24 +452,16 @@
 
         // the whole right-hand side of the bar
         mNotificationArea = sb.findViewById(R.id.notificationArea);
-        if (!NOTIFICATION_PEEK_ENABLED) {
-            mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener());
-        }
+        mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener());
 
         // the button to open the notification area
         mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
-        if (NOTIFICATION_PEEK_ENABLED) {
-            mNotificationTrigger.setOnTouchListener(new NotificationTriggerTouchListener());
-        }
 
         // the more notifications icon
         mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
 
         // where the icons go
         mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
-        if (NOTIFICATION_PEEK_ENABLED) {
-            mIconLayout.setOnTouchListener(new NotificationIconTouchListener());
-        }
 
         ViewConfiguration vc = ViewConfiguration.get(context);
         mNotificationPeekTapDuration = vc.getTapTimeout();
@@ -704,7 +654,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
         lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
     }
 
@@ -714,7 +663,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
         lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
     }
 
@@ -829,9 +777,6 @@
                 case MSG_OPEN_NOTIFICATION_PANEL:
                     if (DEBUG) Slog.d(TAG, "opening notifications panel");
                     if (!mNotificationPanel.isShowing()) {
-                        if (NOTIFICATION_PEEK_ENABLED) {
-                            mNotificationPeekWindow.setVisibility(View.GONE);
-                        }
                         mNotificationPanel.show(true, true);
                         mNotificationArea.setVisibility(View.INVISIBLE);
                         mTicker.halt();
@@ -918,106 +863,6 @@
         setAreThereNotifications();
     }
 
-    public void updateNotification(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
-
-        final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
-        if (oldEntry == null) {
-            Slog.w(TAG, "updateNotification for unknown key: " + key);
-            return;
-        }
-
-        final StatusBarNotification oldNotification = oldEntry.notification;
-
-        // XXX: modify when we do something more intelligent with the two content views
-        final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null) 
-                ? oldNotification.notification.bigContentView
-                : oldNotification.notification.contentView;
-        final RemoteViews contentView = (notification.notification.bigContentView != null) 
-                ? notification.notification.bigContentView
-                : notification.notification.contentView;
-
-        if (DEBUG) {
-            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
-                    + " ongoing=" + oldNotification.isOngoing()
-                    + " expanded=" + oldEntry.expanded
-                    + " contentView=" + oldContentView
-                    + " rowParent=" + oldEntry.row.getParent());
-            Slog.d(TAG, "new notification: when=" + notification.notification.when
-                    + " ongoing=" + oldNotification.isOngoing()
-                    + " contentView=" + contentView);
-        }
-
-        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
-        // didn't change.
-        boolean contentsUnchanged = oldEntry.expanded != null
-                && contentView != null && oldContentView != null
-                && contentView.getPackage() != null
-                && oldContentView.getPackage() != null
-                && oldContentView.getPackage().equals(contentView.getPackage())
-                && oldContentView.getLayoutId() == contentView.getLayoutId();
-        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
-        boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
-                && notification.score == oldNotification.score;
-                // score now encompasses/supersedes isOngoing()
-        boolean updateTicker = notification.notification.tickerText != null
-                && !TextUtils.equals(notification.notification.tickerText,
-                        oldEntry.notification.notification.tickerText);
-        boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount()-1;
-        if (contentsUnchanged && (orderUnchanged || isLastAnyway)) {
-            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
-            oldEntry.notification = notification;
-            try {
-                // Reapply the RemoteViews
-                contentView.reapply(mContext, oldEntry.content);
-                // update the contentIntent
-                final PendingIntent contentIntent = notification.notification.contentIntent;
-                if (contentIntent != null) {
-                    final View.OnClickListener listener = makeClicker(contentIntent,
-                            notification.pkg, notification.tag, notification.id);
-                    oldEntry.content.setOnClickListener(listener);
-                } else {
-                    oldEntry.content.setOnClickListener(null);
-                }
-                // Update the icon.
-                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
-                        notification.notification.icon, notification.notification.iconLevel,
-                        notification.notification.number,
-                        notification.notification.tickerText);
-                if (!oldEntry.icon.set(ic)) {
-                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
-                    return;
-                }
-
-                if (NOTIFICATION_PEEK_ENABLED && key == mNotificationPeekKey) {
-                    // must update the peek window
-                    Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
-                    peekMsg.arg1 = mNotificationPeekIndex;
-                    mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
-                    mHandler.sendMessage(peekMsg);
-                }
-            }
-            catch (RuntimeException e) {
-                // It failed to add cleanly.  Log, and remove the view from the panel.
-                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
-                removeNotificationViews(key);
-                addNotificationViews(key, notification);
-            }
-        } else {
-            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
-            removeNotificationViews(key);
-            addNotificationViews(key, notification);
-        }
-
-        // Restart the ticker if it's still running
-        if (updateTicker) {
-            mTicker.halt();
-            tick(key, notification, false);
-        }
-
-        setAreThereNotifications();
-    }
-
     public void removeNotification(IBinder key) {
         if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ")");
         removeNotificationViews(key);
@@ -1107,7 +952,8 @@
         return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
     }
 
-    private void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
+    @Override
+    protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
         // Don't show the ticker when the windowshade is open.
         if (mNotificationPanel.isShowing()) {
             return;
@@ -1136,11 +982,6 @@
     }
 
     public void animateExpand() {
-        if (NOTIFICATION_PEEK_ENABLED) {
-            mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
-            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
-            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
-        }
         mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
         mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
     }
@@ -1160,10 +1001,6 @@
         mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL);
         mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL);
         mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL);
-        if (NOTIFICATION_PEEK_ENABLED) {
-            mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
-            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
-        }
     }
 
     @Override // CommandQueue
@@ -1352,24 +1189,13 @@
         }
     }
 
-    private void setAreThereNotifications() {
+    @Override
+    protected void setAreThereNotifications() {
         if (mNotificationPanel != null) {
             mNotificationPanel.setClearable(mNotificationData.hasClearableItems());
         }
     }
 
-    /**
-     * Cancel this notification and tell the status bar service about the failure. Hold no locks.
-     */
-    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
-        removeNotification(key);
-        try {
-            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
-        } catch (RemoteException ex) {
-            // The end is nigh.
-        }
-    }
-
     private View.OnClickListener mOnClickListener = new View.OnClickListener() {
         public void onClick(View v) {
             if (v == mRecentButton) {
@@ -1407,28 +1233,6 @@
         mHandler.sendEmptyMessage(msg);
     }
 
-    StatusBarNotification removeNotificationViews(IBinder key) {
-        NotificationData.Entry entry = mNotificationData.remove(key);
-        if (entry == null) {
-            Slog.w(TAG, "removeNotification for unknown key: " + key);
-            return null;
-        }
-        // Remove the expanded view.
-        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
-        if (rowParent != null) rowParent.removeView(entry.row);
-
-        if (NOTIFICATION_PEEK_ENABLED && key == mNotificationPeekKey) {
-            // must close the peek as well, since it's gone
-            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
-        }
-        // Remove the icon.
-//        ViewGroup iconParent = (ViewGroup)entry.icon.getParent();
-//        if (iconParent != null) iconParent.removeView(entry.icon);
-        updateNotificationIcons();
-
-        return entry.notification;
-    }
-
     private class NotificationTriggerTouchListener implements View.OnTouchListener {
         VelocityTracker mVT;
         float mInitialTouchX, mInitialTouchY;
@@ -1621,50 +1425,14 @@
         }
     }
 
-    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) {
-            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
-        }
-        // Construct the icon.
-        final StatusBarIconView iconView = new StatusBarIconView(mContext,
-                notification.pkg + "/0x" + Integer.toHexString(notification.id),
-                notification.notification);
-        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
-
-        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
-                    notification.notification.icon,
-                    notification.notification.iconLevel,
-                    notification.notification.number,
-                    notification.notification.tickerText);
-        if (!iconView.set(ic)) {
-            handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic);
-            return null;
-        }
-        // Construct the expanded view.
-        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
-        if (!inflateViews(entry, mPile)) {
-            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
-                    + notification);
-            return null;
-        }
-
-        // Add the icon.
-        int pos = mNotificationData.add(entry);
-        if (DEBUG) {
-            Slog.d(TAG, "addNotificationViews: added at " + pos);
-        }
-        updateNotificationIcons();
-
-        return iconView;
-    }
-
     private void reloadAllNotificationIcons() {
         if (mIconLayout == null) return;
         mIconLayout.removeAllViews();
         updateNotificationIcons();
     }
 
-    private void updateNotificationIcons() {
+    @Override
+    protected void updateNotificationIcons() {
         // XXX: need to implement a new limited linear layout class
         // to avoid removing & readding everything
 
@@ -1837,6 +1605,19 @@
         mNetworkController.dump(fd, pw, args);
     }
 
+    @Override
+    protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
+        return parent.indexOfChild(entry.row) == parent.getChildCount()-1;
+    }
+
+    @Override
+    protected void haltTicker() {
+        mTicker.halt();
+    }
+
+    @Override
+    protected void updateExpandedViewPos(int expandedPosition) {
+    }
 }
 
 
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 6e09b7f..ffdeeb1 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -28,6 +28,7 @@
 import android.content.ServiceConnection;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.TelephonyManager;
@@ -112,10 +113,14 @@
 
     /**
      * Sets the Face Unlock view to visible, hiding it after the specified amount of time.  If
-     * timeoutMillis is 0, no hide is performed.
+     * timeoutMillis is 0, no hide is performed.  Called on the UI thread.
      */
     public void show(long timeoutMillis) {
         if (DEBUG) Log.d(TAG, "show()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "show() called off of the UI thread");
+        }
+
         removeDisplayMessages();
         if (mFaceUnlockView != null) {
             mFaceUnlockView.setVisibility(View.VISIBLE);
@@ -138,9 +143,14 @@
     /**
      * Binds to the Face Unlock service.  Face Unlock will be started when the bind completes.  The
      * Face Unlock view is displayed to hide the backup lock while the service is starting up.
+     * Called on the UI thread.
      */
     public boolean start() {
         if (DEBUG) Log.d(TAG, "start()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "start() called off of the UI thread");
+        }
+
         if (mIsRunning) {
             Log.w(TAG, "start() called when already running");
         }
@@ -160,20 +170,19 @@
             Log.w(TAG, "Attempt to bind to Face Unlock when already bound");
         }
 
-        // When switching between portrait and landscape view while Face Unlock is running, the
-        // screen will eventually go dark unless we poke the wakelock when Face Unlock is
-        // restarted
-        mKeyguardScreenCallback.pokeWakelock();
-
         mIsRunning = true;
         return true;
     }
 
     /**
-     * Stops Face Unlock and unbinds from the service.
+     * Stops Face Unlock and unbinds from the service.  Called on the UI thread.
      */
     public boolean stop() {
         if (DEBUG) Log.d(TAG, "stop()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "stop() called off of the UI thread");
+        }
+
         boolean mWasRunning = mIsRunning;
         stopUi();
 
@@ -254,7 +263,7 @@
                 handleExposeFallback();
                 break;
             case MSG_POKE_WAKELOCK:
-                handlePokeWakelock();
+                handlePokeWakelock(msg.arg1);
                 break;
             default:
                 Log.e(TAG, "Unhandled message");
@@ -306,6 +315,11 @@
         if (mFaceUnlockView != null) {
             IBinder windowToken = mFaceUnlockView.getWindowToken();
             if (windowToken != null) {
+                // When switching between portrait and landscape view while Face Unlock is running,
+                // the screen will eventually go dark unless we poke the wakelock when Face Unlock
+                // is restarted.
+                mKeyguardScreenCallback.pokeWakelock();
+
                 int[] position;
                 position = new int[2];
                 mFaceUnlockView.getLocationInWindow(position);
@@ -352,7 +366,7 @@
 
     /**
      * Stops the Face Unlock service and exposes the backup lock.  Called when the user presses the
-     * cancel button to skip Face Unlock or no face is detected.
+     * cancel button to skip Face Unlock, no face is detected or there is an error.
      */
     void handleCancel() {
         if (DEBUG) Log.d(TAG, "handleCancel()");
@@ -396,10 +410,10 @@
     }
 
     /**
-     * Pokes the wakelock to keep the screen alive and active.
+     * Pokes the wakelock to keep the screen alive and active for a specific amount of time.
      */
-    void handlePokeWakelock() {
-        mKeyguardScreenCallback.pokeWakelock();
+    void handlePokeWakelock(int millis) {
+        mKeyguardScreenCallback.pokeWakelock(millis);
     }
 
     /**
@@ -439,13 +453,27 @@
      * Tells the Face Unlock service to start displaying its UI and start processing.
      */
     private void startUi(IBinder windowToken, int x, int y, int w, int h) {
-        if (DEBUG) Log.d(TAG, "startUi()");
+        Log.d(TAG, "startUi()");
         synchronized (mServiceRunningLock) {
             if (!mServiceRunning) {
                 if (DEBUG) Log.d(TAG, "Starting Face Unlock");
                 try {
+                    // TODO: these checks and logs are for tracking down bug 6409767 and can be
+                    // removed when that bug is fixed.
+                    if (mService == null) {
+                        Log.d(TAG, "mService is null");
+                    }
+                    if (windowToken == null) {
+                        Log.d(TAG, "windowToken is null");
+                    }
+                    if (mLockPatternUtils == null) {
+                        Log.d(TAG, "mLockPatternUtils is null");
+                    }
+                    Log.d(TAG, "x,y,w,h,live: " + x + "," + y + "," + w + "," + h + "," +
+                            (mLockPatternUtils.isBiometricWeakLivelinessEnabled()?"yes":"no"));
                     mService.startUi(windowToken, x, y, w, h,
                             mLockPatternUtils.isBiometricWeakLivelinessEnabled());
+                    Log.d(TAG, "mService.startUi() called");
                 } catch (RemoteException e) {
                     Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
                     return;
@@ -497,7 +525,8 @@
         }
 
         /**
-         * Called when the user presses cancel to skip Face Unlock or a face cannot be found.
+         * Called when the user presses cancel to skip Face Unlock, a face cannot be found or
+         * there is an error.
          */
         @Override
         public void cancel() {
@@ -526,12 +555,14 @@
         }
 
         /**
-         * Called when Face Unlock wants to keep the screen alive and active.
+         * Called when Face Unlock wants to keep the screen alive and active for a specific amount
+         * of time.
          */
-        @Override
-        public void pokeWakelock() {
-            if (DEBUG) Log.d(TAG, "pokeWakelock()");
-            mHandler.sendEmptyMessage(MSG_POKE_WAKELOCK);
+        public void pokeWakelock(int millis) {
+            if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms");
+            Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1);
+            mHandler.sendMessage(message);
         }
+
     };
 }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 4b91422..cc7050a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2098,7 +2098,6 @@
             if (widthMode == AT_MOST) {
                 final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
                 if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
-                    fixedWidth = true;
                     final int w;
                     if (tvw.type == TypedValue.TYPE_DIMENSION) {
                         w = (int) tvw.getDimension(metrics);
@@ -2112,6 +2111,7 @@
                         final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
                         widthMeasureSpec = MeasureSpec.makeMeasureSpec(
                                 Math.min(w, widthSize), EXACTLY);
+                        fixedWidth = true;
                     }
                 }
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 6348d37..794ed15 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -463,8 +463,8 @@
     Intent mHomeIntent;
     Intent mCarDockIntent;
     Intent mDeskDockIntent;
-    int mShortcutKeyPressed = -1;
-    boolean mConsumeShortcutKeyUp;
+    boolean mSearchKeyShortcutPending;
+    boolean mConsumeSearchKeyUp;
 
     // support for activating the lock screen while the screen is on
     boolean mAllowLockscreenWhenOn;
@@ -509,7 +509,9 @@
     ShortcutManager mShortcutManager;
     PowerManager.WakeLock mBroadcastWakeLock;
 
-    final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
+    // Fallback actions by key code.
+    private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions =
+            new SparseArray<KeyCharacterMap.FallbackAction>();
 
     private static final int MSG_ENABLE_POINTER_LOCATION = 1;
     private static final int MSG_DISABLE_POINTER_LOCATION = 2;
@@ -1709,7 +1711,8 @@
 
         if (false) {
             Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
-                    + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
+                    + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
+                    + " canceled=" + canceled);
         }
 
         // If we think we might have a volume down & power key chord on the way
@@ -1842,13 +1845,13 @@
         } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
             if (down) {
                 if (repeatCount == 0) {
-                    mShortcutKeyPressed = keyCode;
-                    mConsumeShortcutKeyUp = false;
+                    mSearchKeyShortcutPending = true;
+                    mConsumeSearchKeyUp = false;
                 }
-            } else if (keyCode == mShortcutKeyPressed) {
-                mShortcutKeyPressed = -1;
-                if (mConsumeShortcutKeyUp) {
-                    mConsumeShortcutKeyUp = false;
+            } else {
+                mSearchKeyShortcutPending = false;
+                if (mConsumeSearchKeyUp) {
+                    mConsumeSearchKeyUp = false;
                     return -1;
                 }
             }
@@ -1865,10 +1868,11 @@
         // even if no shortcut was invoked.  This prevents text from being
         // inadvertently inserted when using a keyboard that has built-in macro
         // shortcut keys (that emit Search+x) and some of them are not registered.
-        if (mShortcutKeyPressed != -1) {
+        if (mSearchKeyShortcutPending) {
             final KeyCharacterMap kcm = event.getKeyCharacterMap();
             if (kcm.isPrintingKey(keyCode)) {
-                mConsumeShortcutKeyUp = true;
+                mConsumeSearchKeyUp = true;
+                mSearchKeyShortcutPending = false;
                 if (down && repeatCount == 0 && !keyguardOn) {
                     Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
                     if (shortcutIntent != null) {
@@ -1878,13 +1882,11 @@
                         } catch (ActivityNotFoundException ex) {
                             Slog.w(TAG, "Dropping shortcut key combination because "
                                     + "the activity to which it is registered was not found: "
-                                    + KeyEvent.keyCodeToString(mShortcutKeyPressed)
-                                    + "+" + KeyEvent.keyCodeToString(keyCode), ex);
+                                    + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex);
                         }
                     } else {
                         Slog.i(TAG, "Dropping unregistered shortcut key combination: "
-                                + KeyEvent.keyCodeToString(mShortcutKeyPressed)
-                                + "+" + KeyEvent.keyCodeToString(keyCode));
+                                + "SEARCH+" + KeyEvent.keyCodeToString(keyCode));
                     }
                 }
                 return -1;
@@ -1964,51 +1966,70 @@
                     + ", policyFlags=" + policyFlags);
         }
 
+        KeyEvent fallbackEvent = null;
         if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
             final KeyCharacterMap kcm = event.getKeyCharacterMap();
             final int keyCode = event.getKeyCode();
             final int metaState = event.getMetaState();
+            final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
+                    && event.getRepeatCount() == 0;
 
             // Check for fallback actions specified by the key character map.
-            if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
+            final FallbackAction fallbackAction;
+            if (initialDown) {
+                fallbackAction = kcm.getFallbackAction(keyCode, metaState);
+            } else {
+                fallbackAction = mFallbackActions.get(keyCode);
+            }
+
+            if (fallbackAction != null) {
                 if (DEBUG_FALLBACK) {
-                    Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode
-                            + " metaState=" + Integer.toHexString(mFallbackAction.metaState));
+                    Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode
+                            + " metaState=" + Integer.toHexString(fallbackAction.metaState));
                 }
 
-                int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
-                KeyEvent fallbackEvent = KeyEvent.obtain(
+                final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
+                fallbackEvent = KeyEvent.obtain(
                         event.getDownTime(), event.getEventTime(),
-                        event.getAction(), mFallbackAction.keyCode,
-                        event.getRepeatCount(), mFallbackAction.metaState,
+                        event.getAction(), fallbackAction.keyCode,
+                        event.getRepeatCount(), fallbackAction.metaState,
                         event.getDeviceId(), event.getScanCode(),
                         flags, event.getSource(), null);
-                int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
-                if ((actions & ACTION_PASS_TO_USER) != 0) {
-                    long delayMillis = interceptKeyBeforeDispatching(
-                            win, fallbackEvent, policyFlags);
-                    if (delayMillis == 0) {
-                        if (DEBUG_FALLBACK) {
-                            Slog.d(TAG, "Performing fallback.");
-                        }
-                        return fallbackEvent;
-                    }
+
+                if (!interceptFallback(win, fallbackEvent, policyFlags)) {
+                    fallbackEvent.recycle();
+                    fallbackEvent = null;
                 }
-                fallbackEvent.recycle();
+
+                if (initialDown) {
+                    mFallbackActions.put(keyCode, fallbackAction);
+                } else if (event.getAction() == KeyEvent.ACTION_UP) {
+                    mFallbackActions.remove(keyCode);
+                    fallbackAction.recycle();
+                }
             }
         }
 
         if (DEBUG_FALLBACK) {
-            Slog.d(TAG, "No fallback.");
+            if (fallbackEvent == null) {
+                Slog.d(TAG, "No fallback.");
+            } else {
+                Slog.d(TAG, "Performing fallback: " + fallbackEvent);
+            }
         }
-        return null;
+        return fallbackEvent;
     }
 
-    private boolean getFallbackAction(KeyCharacterMap kcm, int keyCode, int metaState,
-            FallbackAction outFallbackAction) {
-        // Consult the key character map for specific fallback actions.
-        // For example, map NUMPAD_1 to MOVE_HOME when NUMLOCK is not pressed.
-        return kcm.getFallbackAction(keyCode, metaState, outFallbackAction);
+    private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) {
+        int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
+        if ((actions & ACTION_PASS_TO_USER) != 0) {
+            long delayMillis = interceptKeyBeforeDispatching(
+                    win, fallbackEvent, policyFlags);
+            if (delayMillis == 0) {
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index f80ac18..50bfee6 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "EventHub"
 
-// #define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
 
 #include "EventHub.h"
 
@@ -767,11 +767,7 @@
                     size_t count = size_t(readSize) / sizeof(struct input_event);
                     for (size_t i = 0; i < count; i++) {
                         const struct input_event& iev = readBuffer[i];
-                        ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
-                                device->path.string(),
-                                (int) iev.time.tv_sec, (int) iev.time.tv_usec,
-                                iev.type, iev.code, iev.value);
-
+                        nsecs_t delta = 0; 
 #ifdef HAVE_POSIX_CLOCKS
                         // Use the time specified in the event instead of the current time
                         // so that downstream code can get more accurate estimates of
@@ -786,10 +782,23 @@
                         // system call that also queries ktime_get_ts().
                         event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
                                 + nsecs_t(iev.time.tv_usec) * 1000LL;
-                        ALOGV("event time %lld, now %lld", event->when, now);
+                        delta = now - event->when;
+
+                        // Only log verbose if events are older that 1ms
+                        if (delta > 1 * 1000000LL) {
+                            ALOGV("event time %lld, now %lld, delta %lldus", event->when, now, delta / 1000LL);
+                        }
 #else
                         event->when = now;
 #endif
+                        if (delta > 1 * 1000000LL) {
+                            ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
+                                  device->path.string(),
+                                  (int) iev.time.tv_sec, (int) iev.time.tv_usec,
+                                  iev.type, iev.code, iev.value);
+                        }
+
+
                         event->deviceId = deviceId;
                         event->type = iev.type;
                         event->code = iev.code;
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index ada9d9e..1062d68 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -3354,6 +3354,25 @@
             // generated a fallback or if the window is not a foreground window,
             // then cancel the associated fallback key, if any.
             if (fallbackKeyCode != -1) {
+                // Dispatch the unhandled key to the policy with the cancel flag.
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+                ALOGD("Unhandled key event: Asking policy to cancel fallback action.  "
+                        "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
+                        keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
+                        keyEntry->policyFlags);
+#endif
+                KeyEvent event;
+                initializeKeyEvent(&event, keyEntry);
+                event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
+
+                mLock.unlock();
+
+                mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
+                        &event, keyEntry->policyFlags, &event);
+
+                mLock.lock();
+
+                // Cancel the fallback key.
                 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
                     CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
                             "application handled the original non-fallback key "
@@ -3374,8 +3393,9 @@
 #if DEBUG_OUTBOUND_EVENT_DETAILS
                 ALOGD("Unhandled key event: Skipping unhandled key event processing "
                         "since this is not an initial down.  "
-                        "keyCode=%d, action=%d, repeatCount=%d",
-                        originalKeyCode, keyEntry->action, keyEntry->repeatCount);
+                        "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
+                        originalKeyCode, keyEntry->action, keyEntry->repeatCount,
+                        keyEntry->policyFlags);
 #endif
                 return false;
             }
@@ -3383,8 +3403,9 @@
             // Dispatch the unhandled key to the policy.
 #if DEBUG_OUTBOUND_EVENT_DETAILS
             ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
-                    "keyCode=%d, action=%d, repeatCount=%d",
-                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
+                    "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
+                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
+                    keyEntry->policyFlags);
 #endif
             KeyEvent event;
             initializeKeyEvent(&event, keyEntry);
@@ -3426,7 +3447,7 @@
                             "to send %d instead.  Fallback canceled.",
                             event.getKeyCode(), originalKeyCode, fallbackKeyCode);
                 } else {
-                    ALOGD("Unhandled key event: Policy did not request fallback for %d,"
+                    ALOGD("Unhandled key event: Policy did not request fallback for %d, "
                             "but on the DOWN it had requested to send %d.  "
                             "Fallback canceled.",
                             originalKeyCode, fallbackKeyCode);
@@ -3903,8 +3924,10 @@
     memento.source = entry->source;
     memento.keyCode = entry->keyCode;
     memento.scanCode = entry->scanCode;
+    memento.metaState = entry->metaState;
     memento.flags = flags;
     memento.downTime = entry->downTime;
+    memento.policyFlags = entry->policyFlags;
 }
 
 void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
@@ -3919,6 +3942,7 @@
     memento.downTime = entry->downTime;
     memento.setPointers(entry);
     memento.hovering = hovering;
+    memento.policyFlags = entry->policyFlags;
 }
 
 void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
@@ -3935,9 +3959,9 @@
         const KeyMemento& memento = mKeyMementos.itemAt(i);
         if (shouldCancelKey(memento, options)) {
             outEvents.push(new KeyEntry(currentTime,
-                    memento.deviceId, memento.source, 0,
+                    memento.deviceId, memento.source, memento.policyFlags,
                     AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
-                    memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
+                    memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
         }
     }
 
@@ -3945,7 +3969,7 @@
         const MotionMemento& memento = mMotionMementos.itemAt(i);
         if (shouldCancelMotion(memento, options)) {
             outEvents.push(new MotionEntry(currentTime,
-                    memento.deviceId, memento.source, 0,
+                    memento.deviceId, memento.source, memento.policyFlags,
                     memento.hovering
                             ? AMOTION_EVENT_ACTION_HOVER_EXIT
                             : AMOTION_EVENT_ACTION_CANCEL,
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 07ca9d5..06b8d64 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -732,8 +732,10 @@
             uint32_t source;
             int32_t keyCode;
             int32_t scanCode;
+            int32_t metaState;
             int32_t flags;
             nsecs_t downTime;
+            uint32_t policyFlags;
         };
 
         struct MotionMemento {
@@ -747,6 +749,7 @@
             PointerProperties pointerProperties[MAX_POINTERS];
             PointerCoords pointerCoords[MAX_POINTERS];
             bool hovering;
+            uint32_t policyFlags;
 
             void setPointers(const MotionEntry* entry);
         };
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 8e3b825..a49ccf7 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1142,6 +1142,10 @@
         if (mCurToken != null) {
             try {
                 if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken);
+                if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0) {
+                    // The current IME is shown. Hence an IME switch (transition) is happening.
+                    mWindowManagerService.saveLastInputMethodWindowForTransition();
+                }
                 mIWindowManager.removeWindowToken(mCurToken);
             } catch (RemoteException e) {
             }
@@ -2410,17 +2414,63 @@
         }
     }
 
-    private static class ImeSubtypeListItem {
+    private static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
         public final CharSequence mImeName;
         public final CharSequence mSubtypeName;
         public final InputMethodInfo mImi;
         public final int mSubtypeId;
+        private final boolean mIsSystemLocale;
+        private final boolean mIsSystemLanguage;
+
         public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
-                InputMethodInfo imi, int subtypeId) {
+                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
             mImeName = imeName;
             mSubtypeName = subtypeName;
             mImi = imi;
             mSubtypeId = subtypeId;
+            if (TextUtils.isEmpty(subtypeLocale)) {
+                mIsSystemLocale = false;
+                mIsSystemLanguage = false;
+            } else {
+                mIsSystemLocale = subtypeLocale.equals(systemLocale);
+                mIsSystemLanguage = mIsSystemLocale
+                        || subtypeLocale.startsWith(systemLocale.substring(0, 2));
+            }
+        }
+
+        @Override
+        public int compareTo(ImeSubtypeListItem other) {
+            if (TextUtils.isEmpty(mImeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mImeName)) {
+                return -1;
+            }
+            if (!TextUtils.equals(mImeName, other.mImeName)) {
+                return mImeName.toString().compareTo(other.mImeName.toString());
+            }
+            if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
+                return 0;
+            }
+            if (mIsSystemLocale) {
+                return -1;
+            }
+            if (other.mIsSystemLocale) {
+                return 1;
+            }
+            if (mIsSystemLanguage) {
+                return -1;
+            }
+            if (other.mIsSystemLanguage) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(mSubtypeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mSubtypeName)) {
+                return -1;
+            }
+            return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
         }
     }
 
@@ -2619,7 +2669,11 @@
         return getSubtypeIdFromHashCode(imi, subtypeId);
     }
 
-    private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
+    private static boolean isValidSubtypeId(InputMethodInfo imi, int subtypeHashCode) {
+        return getSubtypeIdFromHashCode(imi, subtypeHashCode) != NOT_A_SUBTYPE_ID;
+    }
+
+    private static int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
         if (imi != null) {
             final int subtypeCount = imi.getSubtypeCount();
             for (int i = 0; i < subtypeCount; ++i) {
@@ -2844,6 +2898,9 @@
      */
     @Override
     public InputMethodSubtype getCurrentInputMethodSubtype() {
+        if (mCurMethodId == null) {
+            return null;
+        }
         boolean subtypeIsSelected = false;
         try {
             subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(),
@@ -2851,36 +2908,35 @@
         } catch (SettingNotFoundException e) {
         }
         synchronized (mMethodMap) {
-            if (!subtypeIsSelected || mCurrentSubtype == null) {
-                String lastInputMethodId = Settings.Secure.getString(
-                        mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
-                int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId);
+            final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+            if (imi == null || imi.getSubtypeCount() == 0) {
+                return null;
+            }
+            if (!subtypeIsSelected || mCurrentSubtype == null
+                    || !isValidSubtypeId(imi, mCurrentSubtype.hashCode())) {
+                int subtypeId = getSelectedInputMethodSubtypeId(mCurMethodId);
                 if (subtypeId == NOT_A_SUBTYPE_ID) {
-                    InputMethodInfo imi = mMethodMap.get(lastInputMethodId);
-                    if (imi != null) {
-                        // If there are no selected subtypes, the framework will try to find
-                        // the most applicable subtype from explicitly or implicitly enabled
-                        // subtypes.
-                        List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
-                                getEnabledInputMethodSubtypeList(imi, true);
-                        // If there is only one explicitly or implicitly enabled subtype,
-                        // just returns it.
-                        if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
-                            mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
-                        } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+                    // If there are no selected subtypes, the framework will try to find
+                    // the most applicable subtype from explicitly or implicitly enabled
+                    // subtypes.
+                    List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
+                            getEnabledInputMethodSubtypeList(imi, true);
+                    // If there is only one explicitly or implicitly enabled subtype,
+                    // just returns it.
+                    if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
+                        mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
+                    } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+                        mCurrentSubtype = findLastResortApplicableSubtypeLocked(
+                                mRes, explicitlyOrImplicitlyEnabledSubtypes,
+                                SUBTYPE_MODE_KEYBOARD, null, true);
+                        if (mCurrentSubtype == null) {
                             mCurrentSubtype = findLastResortApplicableSubtypeLocked(
-                                    mRes, explicitlyOrImplicitlyEnabledSubtypes,
-                                    SUBTYPE_MODE_KEYBOARD, null, true);
-                            if (mCurrentSubtype == null) {
-                                mCurrentSubtype = findLastResortApplicableSubtypeLocked(
-                                        mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
-                                        true);
-                            }
+                                    mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
+                                    true);
                         }
                     }
                 } else {
-                    mCurrentSubtype =
-                            getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId);
+                    mCurrentSubtype = getSubtypes(imi).get(subtypeId);
                 }
             }
             return mCurrentSubtype;
@@ -2946,10 +3002,13 @@
         private final Context mContext;
         private final PackageManager mPm;
         private final InputMethodManagerService mImms;
+        private final String mSystemLocaleStr;
         public InputMethodAndSubtypeListManager(Context context, InputMethodManagerService imms) {
             mContext = context;
             mPm = context.getPackageManager();
             mImms = imms;
+            mSystemLocaleStr =
+                    imms.mLastSystemLocale != null ? imms.mLastSystemLocale.toString() : "";
         }
 
         private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
@@ -2979,7 +3038,7 @@
             }
             final int N = imList.size();
             final int currentSubtypeId = subtype != null
-                    ? mImms.getSubtypeIdFromHashCode(imi, subtype.hashCode())
+                    ? getSubtypeIdFromHashCode(imi, subtype.hashCode())
                     : NOT_A_SUBTYPE_ID;
             for (int i = 0; i < N; ++i) {
                 final ImeSubtypeListItem isli = imList.get(i);
@@ -3037,7 +3096,8 @@
                                     subtype.overridesImplicitlyEnabledSubtype() ? null
                                             : subtype.getDisplayName(mContext, imi.getPackageName(),
                                                     imi.getServiceInfo().applicationInfo);
-                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j));
+                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j,
+                                    subtype.getLocale(), mSystemLocaleStr));
 
                             // Removing this subtype from enabledSubtypeSet because we no longer
                             // need to add an entry of this subtype to imList to avoid duplicated
@@ -3046,9 +3106,11 @@
                         }
                     }
                 } else {
-                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID));
+                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID,
+                            null, mSystemLocaleStr));
                 }
             }
+            Collections.sort(imList);
             return imList;
         }
     }
@@ -3356,10 +3418,10 @@
             for (Pair<String, ArrayList<String>> enabledIme: enabledImes) {
                 if (enabledIme.first.equals(imeId)) {
                     final ArrayList<String> explicitlyEnabledSubtypes = enabledIme.second;
+                    final InputMethodInfo imi = mMethodMap.get(imeId);
                     if (explicitlyEnabledSubtypes.size() == 0) {
                         // If there are no explicitly enabled subtypes, applicable subtypes are
                         // enabled implicitly.
-                        InputMethodInfo imi = mMethodMap.get(imeId);
                         // If IME is enabled and no subtypes are enabled, applicable subtypes
                         // are enabled implicitly, so needs to treat them to be enabled.
                         if (imi != null && imi.getSubtypeCount() > 0) {
@@ -3379,7 +3441,17 @@
                         for (String s: explicitlyEnabledSubtypes) {
                             if (s.equals(subtypeHashCode)) {
                                 // If both imeId and subtypeId are enabled, return subtypeId.
-                                return s;
+                                try {
+                                    final int hashCode = Integer.valueOf(subtypeHashCode);
+                                    // Check whether the subtype id is valid or not
+                                    if (isValidSubtypeId(imi, hashCode)) {
+                                        return s;
+                                    } else {
+                                        return NOT_A_SUBTYPE_ID_STR;
+                                    }
+                                } catch (NumberFormatException e) {
+                                    return NOT_A_SUBTYPE_ID_STR;
+                                }
                             }
                         }
                     }
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index f33bf8b..cc8e6a4 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -20,7 +20,7 @@
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.net.nsd.DnsSdServiceInfo;
+import android.net.nsd.NsdServiceInfo;
 import android.net.nsd.DnsSdTxtRecord;
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
@@ -32,6 +32,7 @@
 import android.os.IBinder;
 import android.provider.Settings;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -72,13 +73,16 @@
      */
     private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>();
 
+    /* A map from unique id to client info */
+    private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>();
+
     private AsyncChannel mReplyChannel = new AsyncChannel();
 
     private int INVALID_ID = 0;
     private int mUniqueId = 1;
 
     private static final int BASE = Protocol.BASE_NSD_MANAGER;
-    private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
+    private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1;
     private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
 
     static {
@@ -87,7 +91,6 @@
         sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
         sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
         sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
-        sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
     }
 
     private static String cmdToString(int cmd) {
@@ -101,9 +104,9 @@
 
     private class NsdStateMachine extends StateMachine {
 
-        private DefaultState mDefaultState = new DefaultState();
-        private DisabledState mDisabledState = new DisabledState();
-        private EnabledState mEnabledState = new EnabledState();
+        private final DefaultState mDefaultState = new DefaultState();
+        private final DisabledState mDisabledState = new DisabledState();
+        private final EnabledState mEnabledState = new EnabledState();
 
         @Override
         protected String getMessageInfo(Message msg) {
@@ -151,29 +154,26 @@
                         ac.connect(mContext, getHandler(), msg.replyTo);
                         break;
                     case NsdManager.DISCOVER_SERVICES:
-                        mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                NsdManager.BUSY);
+                        replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                        break;
                     case NsdManager.STOP_DISCOVERY:
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                    NsdManager.ERROR);
+                       replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                               NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
                     case NsdManager.REGISTER_SERVICE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                NsdManager.ERROR);
+                        replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
                     case NsdManager.UNREGISTER_SERVICE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
-                                NsdManager.ERROR);
+                        replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
                     case NsdManager.RESOLVE_SERVICE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
-                                NsdManager.ERROR);
+                        replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
-                    case NsdManager.STOP_RESOLVE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                NsdManager.ERROR);
-                        break;
+                    case NsdManager.NATIVE_DAEMON_EVENT:
                     default:
                         Slog.e(TAG, "Unhandled " + msg);
                         return NOT_HANDLED;
@@ -217,11 +217,30 @@
                 }
             }
 
+            private boolean requestLimitReached(ClientInfo clientInfo) {
+                if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
+                    if (DBG) Slog.d(TAG, "Exceeded max outstanding requests " + clientInfo);
+                    return true;
+                }
+                return false;
+            }
+
+            private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+                clientInfo.mClientIds.put(clientId, globalId);
+                mIdToClientInfoMap.put(globalId, clientInfo);
+            }
+
+            private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+                clientInfo.mClientIds.remove(clientId);
+                mIdToClientInfoMap.remove(globalId);
+            }
+
             @Override
             public boolean processMessage(Message msg) {
                 ClientInfo clientInfo;
-                DnsSdServiceInfo servInfo;
+                NsdServiceInfo servInfo;
                 boolean result = HANDLED;
+                int id;
                 switch (msg.what) {
                   case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                         //First client
@@ -244,111 +263,112 @@
                         break;
                     case NsdManager.DISCOVER_SERVICES:
                         if (DBG) Slog.d(TAG, "Discover services");
-                        servInfo = (DnsSdServiceInfo) msg.obj;
+                        servInfo = (NsdServiceInfo) msg.obj;
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mDiscoveryId != INVALID_ID) {
-                            //discovery already in progress
-                            if (DBG) Slog.d(TAG, "discovery in progress");
-                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                    NsdManager.ALREADY_ACTIVE);
+
+                        if (requestLimitReached(clientInfo)) {
+                            replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                    NsdManager.FAILURE_MAX_LIMIT);
                             break;
                         }
-                        clientInfo.mDiscoveryId = getUniqueId();
-                        if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
-                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
+
+                        id = getUniqueId();
+                        if (discoverServices(id, servInfo.getServiceType())) {
+                            if (DBG) {
+                                Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
+                                        servInfo.getServiceType());
+                            }
+                            storeRequestMap(msg.arg2, id, clientInfo);
+                            replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                    NsdManager.ERROR);
-                            clientInfo.mDiscoveryId = INVALID_ID;
+                            stopServiceDiscovery(id);
+                            replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
                     case NsdManager.STOP_DISCOVERY:
                         if (DBG) Slog.d(TAG, "Stop service discovery");
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mDiscoveryId == INVALID_ID) {
-                            //already stopped
-                            if (DBG) Slog.d(TAG, "discovery already stopped");
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                    NsdManager.ALREADY_ACTIVE);
+
+                        try {
+                            id = clientInfo.mClientIds.get(msg.arg2).intValue();
+                        } catch (NullPointerException e) {
+                            replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                             break;
                         }
-                        if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
-                            clientInfo.mDiscoveryId = INVALID_ID;
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
+                        removeRequestMap(msg.arg2, id, clientInfo);
+                        if (stopServiceDiscovery(id)) {
+                            replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                    NsdManager.ERROR);
+                            replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
                     case NsdManager.REGISTER_SERVICE:
                         if (DBG) Slog.d(TAG, "Register service");
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
-                            if (DBG) Slog.d(TAG, "register service exceeds limit");
-                            mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                    NsdManager.MAX_REGS_REACHED);
+                        if (requestLimitReached(clientInfo)) {
+                            replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_MAX_LIMIT);
+                            break;
                         }
 
-                        int id = getUniqueId();
-                        if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
-                            clientInfo.mRegisteredIds.add(id);
+                        id = getUniqueId();
+                        if (registerService(id, (NsdServiceInfo) msg.obj)) {
+                            if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
+                            storeRequestMap(msg.arg2, id, clientInfo);
+                            // Return success after mDns reports success
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                    NsdManager.ERROR);
+                            unregisterService(id);
+                            replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
                     case NsdManager.UNREGISTER_SERVICE:
                         if (DBG) Slog.d(TAG, "unregister service");
                         clientInfo = mClients.get(msg.replyTo);
-                        int regId = msg.arg1;
-                        if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
-                                unregisterService(regId)) {
-                            mReplyChannel.replyToMessage(msg,
-                                    NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
-                        } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
-                                    NsdManager.ERROR);
+                        try {
+                            id = clientInfo.mClientIds.get(msg.arg2).intValue();
+                        } catch (NullPointerException e) {
+                            replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
+                            break;
                         }
-                        break;
-                    case NsdManager.UPDATE_SERVICE:
-                        if (DBG) Slog.d(TAG, "Update service");
-                        //TODO: implement
-                        mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
+                        removeRequestMap(msg.arg2, id, clientInfo);
+                        if (unregisterService(id)) {
+                            replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
+                        } else {
+                            replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
                         break;
                     case NsdManager.RESOLVE_SERVICE:
                         if (DBG) Slog.d(TAG, "Resolve service");
-                        servInfo = (DnsSdServiceInfo) msg.obj;
+                        servInfo = (NsdServiceInfo) msg.obj;
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mResolveId != INVALID_ID) {
-                            //first cancel existing resolve
-                            stopResolveService(clientInfo.mResolveId);
-                        }
 
-                        clientInfo.mResolveId = getUniqueId();
-                        if (!resolveService(clientInfo.mResolveId, servInfo)) {
-                            mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
-                                    NsdManager.ERROR);
-                            clientInfo.mResolveId = INVALID_ID;
-                        }
-                        break;
-                    case NsdManager.STOP_RESOLVE:
-                        if (DBG) Slog.d(TAG, "Stop resolve");
-                        clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mResolveId == INVALID_ID) {
-                            //already stopped
-                            if (DBG) Slog.d(TAG, "resolve already stopped");
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                    NsdManager.ALREADY_ACTIVE);
+
+                        if (clientInfo.mResolvedService != null) {
+                            replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                    NsdManager.FAILURE_ALREADY_ACTIVE);
                             break;
                         }
-                        if (stopResolveService(clientInfo.mResolveId)) {
-                            clientInfo.mResolveId = INVALID_ID;
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
+
+                        id = getUniqueId();
+                        if (resolveService(id, servInfo)) {
+                            clientInfo.mResolvedService = new NsdServiceInfo();
+                            storeRequestMap(msg.arg2, id, clientInfo);
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                    NsdManager.ERROR);
+                            replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
+                    case NsdManager.NATIVE_DAEMON_EVENT:
+                        NativeEvent event = (NativeEvent) msg.obj;
+                        handleNativeEvent(event.code, event.raw,
+                                NativeDaemonEvent.unescapeArgs(event.raw));
+                        break;
                     default:
                         result = NOT_HANDLED;
                         break;
@@ -439,121 +459,144 @@
         public static final int SERVICE_GET_ADDR_SUCCESS    =   612;
     }
 
+    private class NativeEvent {
+        int code;
+        String raw;
+
+        NativeEvent(int code, String raw) {
+            this.code = code;
+            this.raw = raw;
+        }
+    }
+
     class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
         public void onDaemonConnected() {
             mNativeDaemonConnected.countDown();
         }
 
         public boolean onEvent(int code, String raw, String[] cooked) {
-            ClientInfo clientInfo;
-            DnsSdServiceInfo servInfo;
-            int id = Integer.parseInt(cooked[1]);
-            switch (code) {
-                case NativeResponseCode.SERVICE_FOUND:
-                    /* NNN uniqueId serviceName regType domain */
-                    if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
-                    clientInfo = getClientByDiscovery(id);
-                    if (clientInfo == null) break;
+            // TODO: NDC translates a message to a callback, we could enhance NDC to
+            // directly interact with a state machine through messages
+            NativeEvent event = new NativeEvent(code, raw);
+            mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
+            return true;
+        }
+    }
 
-                    servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
-                    clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
+    private void handleNativeEvent(int code, String raw, String[] cooked) {
+        NsdServiceInfo servInfo;
+        int id = Integer.parseInt(cooked[1]);
+        ClientInfo clientInfo = mIdToClientInfoMap.get(id);
+        if (clientInfo == null) {
+            Slog.e(TAG, "Unique id with no client mapping: " + id);
+            return;
+        }
+
+        /* This goes in response as msg.arg2 */
+        int clientId = -1;
+        int keyId = clientInfo.mClientIds.indexOfValue(id);
+        if (keyId != -1) {
+            clientId = clientInfo.mClientIds.keyAt(keyId);
+        }
+        switch (code) {
+            case NativeResponseCode.SERVICE_FOUND:
+                /* NNN uniqueId serviceName regType domain */
+                if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
+                servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+                clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0,
+                        clientId, servInfo);
+                break;
+            case NativeResponseCode.SERVICE_LOST:
+                /* NNN uniqueId serviceName regType domain */
+                if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
+                servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+                clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0,
+                        clientId, servInfo);
+                break;
+            case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
+                /* NNN uniqueId errorCode */
+                if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
+                clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_REGISTERED:
+                /* NNN regId serviceName regType */
+                if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
+                servInfo = new NsdServiceInfo(cooked[2], null, null);
+                clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
+                        id, clientId, servInfo);
+                break;
+            case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
+                /* NNN regId errorCode */
+                if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
+                clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_UPDATED:
+                /* NNN regId */
+                break;
+            case NativeResponseCode.SERVICE_UPDATE_FAILED:
+                /* NNN regId errorCode */
+                break;
+            case NativeResponseCode.SERVICE_RESOLVED:
+                /* NNN resolveId fullName hostName port txtlen txtdata */
+                if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
+                int index = cooked[2].indexOf(".");
+                if (index == -1) {
+                    Slog.e(TAG, "Invalid service found " + raw);
                     break;
-                case NativeResponseCode.SERVICE_LOST:
-                    /* NNN uniqueId serviceName regType domain */
-                    if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
-                    clientInfo = getClientByDiscovery(id);
-                    if (clientInfo == null) break;
+                }
+                String name = cooked[2].substring(0, index);
+                String rest = cooked[2].substring(index);
+                String type = rest.replace(".local.", "");
 
-                    servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
-                    clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
-                    break;
-                case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
-                    /* NNN uniqueId errorCode */
-                    if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
-                    clientInfo = getClientByDiscovery(id);
-                    if (clientInfo == null) break;
+                clientInfo.mResolvedService.setServiceName(name);
+                clientInfo.mResolvedService.setServiceType(type);
+                clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
 
-                    clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
-                            NsdManager.ERROR);
-                    break;
-                case NativeResponseCode.SERVICE_REGISTERED:
-                    /* NNN regId serviceName regType */
-                    if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
-                    clientInfo = getClientByRegistration(id);
-                    if (clientInfo == null) break;
-
-                    servInfo = new DnsSdServiceInfo(cooked[2], null, null);
-                    clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
-                            id, 0, servInfo);
-                    break;
-                case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
-                    /* NNN regId errorCode */
-                    if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
-                    clientInfo = getClientByRegistration(id);
-                    if (clientInfo == null) break;
-
-                    clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
-                            NsdManager.ERROR);
-                    break;
-                case NativeResponseCode.SERVICE_UPDATED:
-                    /* NNN regId */
-                    break;
-                case NativeResponseCode.SERVICE_UPDATE_FAILED:
-                    /* NNN regId errorCode */
-                    break;
-                case NativeResponseCode.SERVICE_RESOLVED:
-                    /* NNN resolveId fullName hostName port txtlen txtdata */
-                    if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
-                    clientInfo = getClientByResolve(id);
-                    if (clientInfo == null) break;
-
-                    int index = cooked[2].indexOf(".");
-                    if (index == -1) {
-                        Slog.e(TAG, "Invalid service found " + raw);
-                        break;
-                    }
-                    String name = cooked[2].substring(0, index);
-                    String rest = cooked[2].substring(index);
-                    String type = rest.replace(".local.", "");
-
-                    clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
-                    clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
-
-                    stopResolveService(id);
-                    getAddrInfo(id, cooked[3]);
-                    break;
-                case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
-                case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
-                    /* NNN resolveId errorCode */
-                    if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
-                    clientInfo = getClientByResolve(id);
-                    if (clientInfo == null) break;
-
+                stopResolveService(id);
+                if (!getAddrInfo(id, cooked[3])) {
                     clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
-                            NsdManager.ERROR);
-                    break;
-                case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
-                    /* NNN resolveId hostname ttl addr */
-                    if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
-                    clientInfo = getClientByResolve(id);
-                    if (clientInfo == null || clientInfo.mResolvedService == null) break;
-
-                    try {
-                        clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
-                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
-                                clientInfo.mResolvedService);
-                        clientInfo.mResolvedService = null;
-                        clientInfo.mResolveId = INVALID_ID;
-                    } catch (java.net.UnknownHostException e) {
-                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
-                                NsdManager.ERROR);
-                    }
-                    stopGetAddrInfo(id);
-                    break;
-                default:
-                    break;
-            }
-            return false;
+                            NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                    mIdToClientInfoMap.remove(id);
+                    clientInfo.mResolvedService = null;
+                }
+                break;
+            case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
+                /* NNN resolveId errorCode */
+                if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+                stopResolveService(id);
+                mIdToClientInfoMap.remove(id);
+                clientInfo.mResolvedService = null;
+                clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
+                /* NNN resolveId errorCode */
+                stopGetAddrInfo(id);
+                mIdToClientInfoMap.remove(id);
+                clientInfo.mResolvedService = null;
+                if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+                clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
+                /* NNN resolveId hostname ttl addr */
+                if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
+                try {
+                    clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
+                    clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
+                            0, clientId, clientInfo.mResolvedService);
+                } catch (java.net.UnknownHostException e) {
+                    clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+                            NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                }
+                stopGetAddrInfo(id);
+                mIdToClientInfoMap.remove(id);
+                clientInfo.mResolvedService = null;
+                break;
+            default:
+                break;
         }
     }
 
@@ -579,7 +622,7 @@
         return true;
     }
 
-    private boolean registerService(int regId, DnsSdServiceInfo service) {
+    private boolean registerService(int regId, NsdServiceInfo service) {
         if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
         try {
             //Add txtlen and txtdata
@@ -637,7 +680,7 @@
         return true;
     }
 
-    private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
+    private boolean resolveService(int resolveId, NsdServiceInfo service) {
         if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
         try {
             mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
@@ -700,49 +743,52 @@
         mNsdStateMachine.dump(fd, pw, args);
     }
 
-    private ClientInfo getClientByDiscovery(int discoveryId) {
-        for (ClientInfo c: mClients.values()) {
-            if (c.mDiscoveryId == discoveryId) {
-                return c;
-            }
-        }
-        return null;
+    /* arg2 on the source message has an id that needs to be retained in replies
+     * see NsdManager for details */
+    private Message obtainMessage(Message srcMsg) {
+        Message msg = Message.obtain();
+        msg.arg2 = srcMsg.arg2;
+        return msg;
     }
 
-    private ClientInfo getClientByResolve(int resolveId) {
-        for (ClientInfo c: mClients.values()) {
-            if (c.mResolveId == resolveId) {
-                return c;
-            }
-        }
-        return null;
+    private void replyToMessage(Message msg, int what) {
+        if (msg.replyTo == null) return;
+        Message dstMsg = obtainMessage(msg);
+        dstMsg.what = what;
+        mReplyChannel.replyToMessage(msg, dstMsg);
     }
 
-    private ClientInfo getClientByRegistration(int regId) {
-        for (ClientInfo c: mClients.values()) {
-            if (c.mRegisteredIds.contains(regId)) {
-                return c;
-            }
-        }
-        return null;
+    private void replyToMessage(Message msg, int what, int arg1) {
+        if (msg.replyTo == null) return;
+        Message dstMsg = obtainMessage(msg);
+        dstMsg.what = what;
+        dstMsg.arg1 = arg1;
+        mReplyChannel.replyToMessage(msg, dstMsg);
+    }
+
+    private void replyToMessage(Message msg, int what, Object obj) {
+        if (msg.replyTo == null) return;
+        Message dstMsg = obtainMessage(msg);
+        dstMsg.what = what;
+        dstMsg.obj = obj;
+        mReplyChannel.replyToMessage(msg, dstMsg);
     }
 
     /* Information tracked per client */
     private class ClientInfo {
 
-        private static final int MAX_REG = 5;
+        private static final int MAX_LIMIT = 10;
         private AsyncChannel mChannel;
         private Messenger mMessenger;
-        private int mDiscoveryId;
-        private int mResolveId;
         /* Remembers a resolved service until getaddrinfo completes */
-        private DnsSdServiceInfo mResolvedService;
-        private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
+        private NsdServiceInfo mResolvedService;
+
+        /* A map from client id to unique id sent to mDns */
+        private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
 
         private ClientInfo(AsyncChannel c, Messenger m) {
             mChannel = c;
             mMessenger = m;
-            mDiscoveryId = mResolveId = INVALID_ID;
             if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
         }
 
@@ -751,11 +797,10 @@
             StringBuffer sb = new StringBuffer();
             sb.append("mChannel ").append(mChannel).append("\n");
             sb.append("mMessenger ").append(mMessenger).append("\n");
-            sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
-            sb.append("mResolveId ").append(mResolveId).append("\n");
             sb.append("mResolvedService ").append(mResolvedService).append("\n");
-            for(int regId : mRegisteredIds) {
-                sb.append("regId ").append(regId).append("\n");
+            for(int i = 0; i< mClientIds.size(); i++) {
+                sb.append("clientId ").append(mClientIds.keyAt(i));
+                sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
             }
             return sb.toString();
         }
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 5799f2b..289ab2a 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -485,7 +485,7 @@
                 //mDimScreen = getInt(DIM_SCREEN) != 0;
 
                 mScreenBrightnessSetting = getInt(SCREEN_BRIGHTNESS, DEFAULT_SCREEN_BRIGHTNESS);
-                mLightSensorAdjustSetting = getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
+                mLightSensorAdjustSetting = 0; //getFloat(SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
 
                 // SCREEN_BRIGHTNESS_MODE, default to manual
                 setScreenBrightnessMode(getInt(SCREEN_BRIGHTNESS_MODE,
@@ -649,7 +649,7 @@
                         + Settings.System.NAME + "=?) or ("
                         + Settings.System.NAME + "=?)",
                 new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN, SCREEN_BRIGHTNESS,
-                        SCREEN_BRIGHTNESS_MODE, SCREEN_AUTO_BRIGHTNESS_ADJ,
+                        SCREEN_BRIGHTNESS_MODE, /*SCREEN_AUTO_BRIGHTNESS_ADJ,*/
                         WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
                 null);
         mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index e447218..0c6d85d 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -17,7 +17,7 @@
 package com.android.server.accessibility;
 
 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
-import static android.accessibilityservice.AccessibilityServiceInfo.INCLUDE_NOT_IMPORTANT_VIEWS;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
 
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
@@ -259,7 +259,7 @@
                         updateInputFilterLocked();
                         sendStateToClientsLocked();
                     }
-                    
+
                     return;
                 }
 
@@ -531,12 +531,12 @@
         //       last record in the enabled services setting. Ideally,
         //       the user should make the call which service handles
         //       gestures. However, only one service should handle
-        //       gestrues to avoid user frustration when different
-        //       bahiour is observed from different combinations of
+        //       gestures to avoid user frustration when different
+        //       behavior is observed from different combinations of
         //       enabled accessibility services.
         for (int i = mServices.size() - 1; i >= 0; i--) {
             Service service = mServices.get(i);
-            if (service.mCanHandleGestures && service.mIsDefault == isDefault) {
+            if (service.mReqeustTouchExplorationMode && service.mIsDefault == isDefault) {
                 mGestureHandler.scheduleHandleGesture(gestureId, service.mServiceInterface);
                 return true;
             }
@@ -1225,7 +1225,7 @@
 
         boolean mCanRetrieveScreenContent;
 
-        boolean mCanHandleGestures;
+        boolean mReqeustTouchExplorationMode;
 
         boolean mIsAutomation;
 
@@ -1243,7 +1243,9 @@
             mIsAutomation = isAutomation;
             if (!isAutomation) {
                 mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent();
-                mCanHandleGestures = accessibilityServiceInfo.getCanHandleGestures();
+                mReqeustTouchExplorationMode =
+                    (accessibilityServiceInfo.flags
+                            & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
                 mIntent = new Intent().setComponent(mComponentName);
                 mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                         com.android.internal.R.string.accessibility_binding_label);
@@ -1251,7 +1253,6 @@
                         mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
             } else {
                 mCanRetrieveScreenContent = true;
-                mCanHandleGestures = true;
             }
             setDynamicallyConfigurableProperties(accessibilityServiceInfo);
         }
@@ -1266,16 +1267,13 @@
             mNotificationTimeout = info.notificationTimeout;
             mIsDefault = (info.flags & DEFAULT) != 0;
 
-            if (!mIsAutomation) {
-                final int targetSdkVersion =
-                    info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion;
-                // TODO: Uncomment this line and remove the line below when JellyBean
-                // SDK version is finalized.
-                // if (targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
-                if (targetSdkVersion > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
-                    mIncludeNotImportantViews =
-                        (info.flags & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
-                }
+            if (mIsAutomation || info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion
+                    // TODO: Uncomment this line and remove the line below when JellyBean
+                    // SDK version is finalized.
+                    // >= Build.VERSION_CODES.JELLY_BEAN) {
+                    > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
+                mIncludeNotImportantViews =
+                    (info.flags & FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
             }
 
             synchronized (mLock) {
@@ -1703,14 +1701,9 @@
             | AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
             | AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
             | AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT
-            | AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT;
-
-        private static final int VALID_GRANULARITIES =
-            AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-            | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
-            | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
-            | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
-            | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE;
+            | AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT
+            | AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+            | AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD;
 
         private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
             AccessibilityEvent.TYPE_VIEW_CLICKED
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ab35ac2..54ef724 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1567,6 +1567,31 @@
     @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
+        if (code == SYSPROPS_TRANSACTION) {
+            // We need to tell all apps about the system property change.
+            ArrayList<IBinder> procs = new ArrayList<IBinder>();
+            synchronized(this) {
+                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+                    final int NA = apps.size();
+                    for (int ia=0; ia<NA; ia++) {
+                        ProcessRecord app = apps.valueAt(ia);
+                        if (app.thread != null) {
+                            procs.add(app.thread.asBinder());
+                        }
+                    }
+                }
+            }
+
+            int N = procs.size();
+            for (int i=0; i<N; i++) {
+                Parcel data2 = Parcel.obtain();
+                try {
+                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
+                } catch (RemoteException e) {
+                }
+                data2.recycle();
+            }
+        }
         try {
             return super.onTransact(code, data, reply, flags);
         } catch (RuntimeException e) {
@@ -5335,6 +5360,7 @@
         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
         outInfo.availMem = Process.getFreeMemory();
+        outInfo.totalMem = Process.getTotalMemory();
         outInfo.threshold = homeAppMem;
         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
         outInfo.hiddenAppThreshold = hiddenAppMem;
@@ -11057,7 +11083,7 @@
                     updateOomAdjLocked(r.app);
                 }
                 int flags = 0;
-                if (si.deliveryCount > 0) {
+                if (si.deliveryCount > 1) {
                     flags |= Service.START_FLAG_RETRY;
                 }
                 if (si.doneExecutingCount > 0) {
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 97bfd6f..ad80273 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -552,7 +552,8 @@
 
     void applyOptionsLocked() {
         if (pendingOptions != null) {
-            switch (pendingOptions.getAnimationType()) {
+            final int animationType = pendingOptions.getAnimationType();
+            switch (animationType) {
                 case ActivityOptions.ANIM_CUSTOM:
                     service.mWindowManager.overridePendingAppTransition(
                             pendingOptions.getPackageName(),
@@ -571,10 +572,13 @@
                     }
                     break;
                 case ActivityOptions.ANIM_THUMBNAIL:
+                case ActivityOptions.ANIM_THUMBNAIL_DELAYED:
+                    boolean delayed = (animationType == ActivityOptions.ANIM_THUMBNAIL_DELAYED);
                     service.mWindowManager.overridePendingAppTransitionThumb(
                             pendingOptions.getThumbnail(),
                             pendingOptions.getStartX(), pendingOptions.getStartY(),
-                            pendingOptions.getOnAnimationStartListener());
+                            pendingOptions.getOnAnimationStartListener(),
+                            delayed);
                     if (intent.getSourceBounds() == null) {
                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
                                 pendingOptions.getStartY(),
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1e14f5b..c300411 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1794,10 +1794,6 @@
                 mService.mWindowManager.prepareAppTransition(
                         WindowManagerPolicy.TRANSIT_NONE, keepCurTransition);
                 mNoAnimActivities.add(r);
-            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
-                mService.mWindowManager.prepareAppTransition(
-                        WindowManagerPolicy.TRANSIT_TASK_OPEN, keepCurTransition);
-                mNoAnimActivities.remove(r);
             } else {
                 mService.mWindowManager.prepareAppTransition(newTask
                         ? WindowManagerPolicy.TRANSIT_TASK_OPEN
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index 2ce7771..c3ecf54 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -26,6 +26,7 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.TrafficStats;
+import android.os.DropBoxManager;
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.Slog;
@@ -34,6 +35,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.google.android.collect.Sets;
 
+import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.IOException;
@@ -43,6 +45,8 @@
 import java.util.HashSet;
 import java.util.Map;
 
+import libcore.io.IoUtils;
+
 /**
  * Logic to record deltas between periodic {@link NetworkStats} snapshots into
  * {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
@@ -56,8 +60,14 @@
     private static final boolean LOGD = false;
     private static final boolean LOGV = false;
 
+    private static final String TAG_NETSTATS_DUMP = "netstats_dump";
+
+    /** Dump before deleting in {@link #recoverFromWtf()}. */
+    private static final boolean DUMP_BEFORE_DELETE = true;
+
     private final FileRotator mRotator;
     private final NonMonotonicObserver<String> mObserver;
+    private final DropBoxManager mDropBox;
     private final String mCookie;
 
     private final long mBucketDuration;
@@ -74,9 +84,10 @@
     private WeakReference<NetworkStatsCollection> mComplete;
 
     public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
-            String cookie, long bucketDuration, boolean onlyTags) {
+            DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
         mRotator = checkNotNull(rotator, "missing FileRotator");
         mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
+        mDropBox = checkNotNull(dropBox, "missing DropBoxManager");
         mCookie = cookie;
 
         mBucketDuration = bucketDuration;
@@ -122,6 +133,7 @@
                 mComplete = new WeakReference<NetworkStatsCollection>(complete);
             } catch (IOException e) {
                 Log.wtf(TAG, "problem completely reading network stats", e);
+                recoverFromWtf();
             }
         }
         return complete;
@@ -212,6 +224,7 @@
                 mPending.reset();
             } catch (IOException e) {
                 Log.wtf(TAG, "problem persisting pending stats", e);
+                recoverFromWtf();
             }
         }
     }
@@ -226,6 +239,7 @@
             mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid));
         } catch (IOException e) {
             Log.wtf(TAG, "problem removing UID " + uid, e);
+            recoverFromWtf();
         }
 
         // clear UID from current stats snapshot
@@ -355,4 +369,25 @@
             mSinceBoot.dump(pw);
         }
     }
+
+    /**
+     * Recover from {@link FileRotator} failure by dumping state to
+     * {@link DropBoxManager} and deleting contents.
+     */
+    private void recoverFromWtf() {
+        if (DUMP_BEFORE_DELETE) {
+            final ByteArrayOutputStream os = new ByteArrayOutputStream();
+            try {
+                mRotator.dumpAll(os);
+            } catch (IOException e) {
+                // ignore partial contents
+                os.reset();
+            } finally {
+                IoUtils.closeQuietly(os);
+            }
+            mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
+        }
+
+        mRotator.deleteAll();
+    }
 }
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 1a56b80..0e93b0a 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -338,9 +338,11 @@
 
     private NetworkStatsRecorder buildRecorder(
             String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
+        final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
+                Context.DROPBOX_SERVICE);
         return new NetworkStatsRecorder(new FileRotator(
                 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
-                mNonMonotonicObserver, prefix, config.bucketDuration, includeTags);
+                mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
     }
 
     private void shutdownLocked() {
@@ -606,17 +608,19 @@
 
         // clamp threshold into safe range
         mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
-        updatePersistThresholds();
-
         if (LOGV) {
             Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
                     + mPersistThreshold);
         }
 
-        // persist if beyond new thresholds
+        // update and persist if beyond new thresholds
         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
                 : System.currentTimeMillis();
         synchronized (mStatsLock) {
+            if (!mSystemReady) return;
+
+            updatePersistThresholds();
+
             mDevRecorder.maybePersistLocked(currentTime);
             mXtRecorder.maybePersistLocked(currentTime);
             mUidRecorder.maybePersistLocked(currentTime);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 4ae3c57..d41cd5a 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1050,7 +1050,7 @@
             mSystemInstallObserver.startWatching();
             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
-            
+
             // Collect all vendor packages.
             mVendorAppDir = new File("/vendor/app");
             mVendorInstallObserver = new AppDirObserver(
@@ -1068,8 +1068,30 @@
                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
                 while (psit.hasNext()) {
                     PackageSetting ps = psit.next();
-                    if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
-                            || mPackages.containsKey(ps.name)) {
+
+                    /*
+                     * If this is not a system app, it can't be a
+                     * disable system app.
+                     */
+                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                        continue;
+                    }
+
+                    /*
+                     * If the package is scanned, it's not erased.
+                     */
+                    if (mPackages.containsKey(ps.name)) {
+                        /*
+                         * If the system app is both scanned and in the
+                         * disabled packages list, then it must have been
+                         * added via OTA. Remove it from the currently
+                         * scanned package so the previously user-installed
+                         * application can be scanned.
+                         */
+                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
+                            mPackages.remove(ps.name);
+                        }
+
                         continue;
                     }
 
@@ -3096,15 +3118,22 @@
                             + "reverting from " + ps.codePathString
                             + ": new version " + pkg.mVersionCode
                             + " better than installed " + ps.versionCode);
-                    InstallArgs args = new FileInstallArgs(ps.codePathString,
-                            ps.resourcePathString, ps.nativeLibraryPathString);
-                    args.cleanUpResourcesLI();
-                    mSettings.enableSystemPackageLPw(ps.name);
+
+                    InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
+                            ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
+                    synchronized (mInstaller) {
+                        args.cleanUpResourcesLI();
+                    }
+                    synchronized (mPackages) {
+                        mSettings.enableSystemPackageLPw(ps.name);
+                    }
                 }
             }
         }
+
         if (updatedPkg != null) {
-            // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
+            // An updated system app will not have the PARSE_IS_SYSTEM flag set
+            // initially
             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
         }
         // Verify certificates against what was last scanned
@@ -3112,6 +3141,49 @@
             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
             return null;
         }
+
+        /*
+         * A new system app appeared, but we already had a non-system one of the
+         * same name installed earlier.
+         */
+        boolean shouldHideSystemApp = false;
+        if (updatedPkg == null && ps != null
+                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
+            /*
+             * Check to make sure the signatures match first. If they don't,
+             * wipe the installed application and its data.
+             */
+            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
+                    != PackageManager.SIGNATURE_MATCH) {
+                deletePackageLI(pkg.packageName, true, 0, null, false);
+                ps = null;
+            } else {
+                /*
+                 * If the newly-added system app is an older version than the
+                 * already installed version, hide it. It will be scanned later
+                 * and re-added like an update.
+                 */
+                if (pkg.mVersionCode < ps.versionCode) {
+                    shouldHideSystemApp = true;
+                } else {
+                    /*
+                     * The newly found system app is a newer version that the
+                     * one previously installed. Simply remove the
+                     * already-installed application and replace it with our own
+                     * while keeping the application data.
+                     */
+                    Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
+                            + ps.codePathString + ": new version " + pkg.mVersionCode
+                            + " better than installed " + ps.versionCode);
+                    InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
+                            ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
+                    synchronized (mInstaller) {
+                        args.cleanUpResourcesLI();
+                    }
+                }
+            }
+        }
+
         // The apk is forward locked (not public) if its code and resources
         // are kept in different files.
         // TODO grab this value from PackageSettings
@@ -3135,7 +3207,27 @@
         // Set application objects path explicitly.
         setApplicationInfoPaths(pkg, codePath, resPath);
         // Note that we invoke the following method only if we are about to unpack an application
-        return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
+        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
+                | SCAN_UPDATE_SIGNATURE, currentTime);
+
+        /*
+         * If the system app should be overridden by a previously installed
+         * data, hide the system app now and let the /data/app scan pick it up
+         * again.
+         */
+        if (shouldHideSystemApp) {
+            synchronized (mPackages) {
+                /*
+                 * We have to grant systems permissions before we hide, because
+                 * grantPermissions will assume the package update is trying to
+                 * expand its permissions.
+                 */
+                grantPermissionsLPw(pkg, true);
+                mSettings.disableSystemPackageLPw(pkg.packageName);
+            }
+        }
+
+        return scannedPkg;
     }
 
     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
@@ -7161,6 +7253,11 @@
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
     }
 
+
+    private boolean isForwardLocked(PackageSetting ps) {
+        return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
+    }
+
     private static boolean isExternal(PackageParser.Package pkg) {
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
     }
@@ -7177,10 +7274,25 @@
         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
 
+    private static boolean isSystemApp(PackageSetting ps) {
+        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
     }
 
+    private int packageFlagsToInstallFlags(PackageSetting ps) {
+        int installFlags = 0;
+        if (isExternal(ps)) {
+            installFlags |= PackageManager.INSTALL_EXTERNAL;
+        }
+        if (isForwardLocked(ps)) {
+            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+        }
+        return installFlags;
+    }
+
     private void deleteTempPackageFiles() {
         FilenameFilter filter = new FilenameFilter() {
             public boolean accept(File dir, String name) {
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 33612b0..a115345c 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -322,8 +322,6 @@
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
                 updateState(state);
                 mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);
-                mAudioSourceEnabled = containsFunction(mCurrentFunctions,
-                        UsbManager.USB_FUNCTION_AUDIO_SOURCE);
 
                 // Upgrade step for previous versions that used persist.service.adb.enable
                 String value = SystemProperties.get("persist.service.adb.enable", "");
@@ -537,26 +535,29 @@
             mContext.sendStickyBroadcast(intent);
         }
 
-        private void updateAudioSourceFunction(boolean enabled) {
-            // send a sticky broadcast containing current USB state
-            Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
-            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            intent.putExtra("state", (enabled ? 1 : 0));
-            if (enabled) {
-                try {
-                    Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
-                    int card = scanner.nextInt();
-                    int device = scanner.nextInt();
-                    intent.putExtra("card", card);
-                    intent.putExtra("device", device);
-                } catch (FileNotFoundException e) {
-                    Slog.e(TAG, "could not open audio source PCM file", e);
+        private void updateAudioSourceFunction() {
+            boolean enabled = containsFunction(mCurrentFunctions,
+                    UsbManager.USB_FUNCTION_AUDIO_SOURCE);
+            if (enabled != mAudioSourceEnabled) {
+                // send a sticky broadcast containing current USB state
+                Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                intent.putExtra("state", (enabled ? 1 : 0));
+                if (enabled) {
+                    try {
+                        Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
+                        int card = scanner.nextInt();
+                        int device = scanner.nextInt();
+                        intent.putExtra("card", card);
+                        intent.putExtra("device", device);
+                    } catch (FileNotFoundException e) {
+                        Slog.e(TAG, "could not open audio source PCM file", e);
+                    }
                 }
+                mContext.sendStickyBroadcast(intent);
+                mAudioSourceEnabled = enabled;
             }
-
-            mContext.sendStickyBroadcast(intent);
-            mAudioSourceEnabled = enabled;
         }
 
         @Override
@@ -578,11 +579,7 @@
                     }
                     if (mBootCompleted) {
                         updateUsbState();
-                        boolean audioSourceEnabled = containsFunction(mCurrentFunctions,
-                                UsbManager.USB_FUNCTION_AUDIO_SOURCE);
-                        if (audioSourceEnabled != mAudioSourceEnabled) {
-                            updateAudioSourceFunction(audioSourceEnabled);
-                        }
+                        updateAudioSourceFunction();
                     }
                     break;
                 case MSG_ENABLE_ADB:
@@ -597,13 +594,13 @@
                     updateUsbNotification();
                     updateAdbNotification();
                     updateUsbState();
+                    updateAudioSourceFunction();
                     break;
                 case MSG_BOOT_COMPLETED:
                     mBootCompleted = true;
                     if (mCurrentAccessory != null) {
                         mSettingsManager.accessoryAttached(mCurrentAccessory);
                     }
-                    updateAudioSourceFunction(mAudioSourceEnabled);
                     break;
             }
         }
@@ -686,7 +683,7 @@
                     notification.defaults = 0; // please be quiet
                     notification.sound = null;
                     notification.vibrate = null;
-                    notification.priority = Notification.PRIORITY_MIN;
+                    notification.priority = Notification.PRIORITY_LOW;
 
                     Intent intent = Intent.makeRestartActivityTask(
                             new ComponentName("com.android.settings",
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 2e817ca..146de34 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -85,6 +85,15 @@
         mPolicy = policy;
     }
 
+    void hideWallpapersLocked() {
+        for (final WindowToken token : mService.mWallpaperTokens) {
+            for (final WindowState wallpaper : token.windows) {
+                wallpaper.mWinAnimator.hide();
+            }
+            token.hidden = true;
+        }
+    }
+
     private void testWallpaperAndBackgroundLocked() {
         if (mWindowDetachedWallpaper != mDetachedWallpaper) {
             if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
@@ -445,6 +454,7 @@
         mPendingLayoutChanges = 0;
         mCurrentTime = SystemClock.uptimeMillis();
         mBulkUpdateParams = 0;
+        boolean wasAnimating = mAnimating;
         mAnimating = false;
         if (WindowManagerService.DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
@@ -500,6 +510,8 @@
 
         if (mAnimating) {
             mService.scheduleAnimationLocked();
+        } else if (wasAnimating) {
+            mService.requestTraversalLocked();
         }
         if (WindowManagerService.DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
@@ -539,6 +551,10 @@
         return mDimParams != null;
     }
 
+    boolean isDimming(final WindowStateAnimator winAnimator) {
+        return mDimParams != null && mDimParams.mDimWinAnimator == winAnimator;
+    }
+
     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
         if (mWindowDetachedWallpaper != null) {
             pw.print("  mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 6caa3e8..2efcb8e 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -512,6 +512,7 @@
     int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
     String mNextAppTransitionPackage;
     Bitmap mNextAppTransitionThumbnail;
+    boolean mNextAppTransitionDelayed;
     IRemoteCallback mNextAppTransitionCallback;
     int mNextAppTransitionEnter;
     int mNextAppTransitionExit;
@@ -3176,7 +3177,7 @@
     }
 
     private Animation createThumbnailAnimationLocked(int transit,
-            boolean enter, boolean thumb) {
+            boolean enter, boolean thumb, boolean delayed) {
         Animation a;
         final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
@@ -3186,6 +3187,7 @@
         // it  is the standard duration for that.  Otherwise we use the longer
         // task transition duration.
         int duration;
+        int delayDuration = delayed ? 200 : 0;
         switch (transit) {
             case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
             case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
@@ -3193,7 +3195,7 @@
                         com.android.internal.R.integer.config_shortAnimTime);
                 break;
             default:
-                duration = 300;
+                duration = delayed ? 200 : 300;
                 break;
         }
         if (thumb) {
@@ -3201,6 +3203,7 @@
             // filling the screen.
             float scaleW = mAppDisplayWidth/thumbWidth;
             float scaleH = mAppDisplayHeight/thumbHeight;
+
             Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
                     computePivot(mNextAppTransitionStartX, 1/scaleW),
                     computePivot(mNextAppTransitionStartY, 1/scaleH));
@@ -3210,17 +3213,38 @@
             set.addAnimation(scale);
             alpha.setDuration(duration);
             set.addAnimation(alpha);
+            set.setFillBefore(true);
+            if (delayDuration > 0) {
+                set.setStartOffset(delayDuration);
+            }
             a = set;
         } else if (enter) {
             // Entering app zooms out from the center of the thumbnail.
-            float scaleW = thumbWidth/mAppDisplayWidth;
-            float scaleH = thumbHeight/mAppDisplayHeight;
-            a = new ScaleAnimation(scaleW, 1, scaleH, 1,
+            float scaleW = thumbWidth / mAppDisplayWidth;
+            float scaleH = thumbHeight / mAppDisplayHeight;
+            AnimationSet set = new AnimationSet(true);
+            Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
                     computePivot(mNextAppTransitionStartX, scaleW),
                     computePivot(mNextAppTransitionStartY, scaleH));
-            a.setDuration(duration);
+            scale.setDuration(duration);
+            scale.setFillBefore(true);
+            set.addAnimation(scale);
+            // Need to set an alpha animation on the entering app window
+            // in case it appears one frame before the thumbnail window
+            // (this solves flicker)
+            Animation alpha = new AlphaAnimation(0, 1);
+            alpha.setDuration(1);
+            alpha.setFillAfter(true);
+            set.addAnimation(alpha);
+            a = set;
+            if (delayDuration > 0) {
+                a.setStartOffset(delayDuration);
+            }
         } else {
             a = createExitAnimationLocked(transit, duration);
+            if (delayDuration > 0) {
+                a.setStartOffset(delayDuration);
+            }
         }
         a.setFillAfter(true);
         final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
@@ -3252,12 +3276,18 @@
                 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
                         + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
                         + " transit=" + transit + " Callers " + Debug.getCallers(3));
-            } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL) {
-                a = createThumbnailAnimationLocked(transit, enter, false);
+            } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL ||
+                    mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_DELAYED) {
+                boolean delayed = (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_DELAYED);
+                a = createThumbnailAnimationLocked(transit, enter, false, delayed);
                 initialized = true;
-                if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
-                        + " anim=" + a + " nextAppTransition=ANIM_THUMBNAIL"
-                        + " transit=" + transit + " Callers " + Debug.getCallers(3));
+
+                if (DEBUG_ANIM) {
+                    String animName = delayed ? "ANIM_THUMBNAIL_DELAYED" : "ANIM_THUMBNAIL";
+                    Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+                            + " anim=" + a + " nextAppTransition=" + animName
+                            + " transit=" + transit + " Callers " + Debug.getCallers(3));
+                }
             } else {
                 int animAttr = 0;
                 switch (transit) {
@@ -3430,9 +3460,6 @@
         synchronized(mWindowMap) {
             WindowToken wtoken = mTokenMap.remove(token);
             if (wtoken != null) {
-                if (wtoken.windowType == TYPE_INPUT_METHOD && mInputMethodWindow != null) {
-                    mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
-                }
                 boolean delayed = false;
                 if (!wtoken.hidden) {
                     wtoken.hidden = true;
@@ -3825,7 +3852,8 @@
         synchronized(mWindowMap) {
             if (DEBUG_APP_TRANSITIONS) Slog.v(
                     TAG, "Prepare app transition: transit=" + transit
-                    + " mNextAppTransition=" + mNextAppTransition);
+                    + " mNextAppTransition=" + mNextAppTransition
+                    + "\nCallers=" + Debug.getCallers(3));
             if (okToDisplay()) {
                 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
                         || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
@@ -3881,11 +3909,13 @@
     }
 
     public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
-            int startY, IRemoteCallback startedCallback) {
+            int startY, IRemoteCallback startedCallback, boolean delayed) {
         if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
-            mNextAppTransitionType = ActivityOptions.ANIM_THUMBNAIL;
+            mNextAppTransitionType =
+                    delayed ? ActivityOptions.ANIM_THUMBNAIL_DELAYED : ActivityOptions.ANIM_THUMBNAIL;
             mNextAppTransitionPackage = null;
             mNextAppTransitionThumbnail = srcThumb;
+            mNextAppTransitionDelayed = delayed;
             mNextAppTransitionStartX = startX;
             mNextAppTransitionStartY = startY;
             mNextAppTransitionCallback = startedCallback;
@@ -4237,7 +4267,7 @@
                     e = new RuntimeException();
                     e.fillInStackTrace();
                 }
-                Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
+                Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
                         + "): mNextAppTransition=" + mNextAppTransition
                         + " hidden=" + wtoken.hidden
                         + " hiddenRequested=" + wtoken.hiddenRequested, e);
@@ -6673,8 +6703,7 @@
         public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
         public static final int SET_WALLPAPER_OFFSET = ANIMATOR_WHAT_OFFSET + 2;
         public static final int SET_DIM_PARAMETERS = ANIMATOR_WHAT_OFFSET + 3;
-        public static final int SET_MOVE_ANIMATION = ANIMATOR_WHAT_OFFSET + 4;
-        public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 5;
+        public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 4;
 
         private Session mLastReportedHold;
 
@@ -7158,18 +7187,6 @@
                     break;
                 }
 
-                case SET_MOVE_ANIMATION: {
-                    WindowAnimator.SetAnimationParams params =
-                            (WindowAnimator.SetAnimationParams) msg.obj;
-                    WindowStateAnimator winAnimator = params.mWinAnimator;
-                    winAnimator.setAnimation(params.mAnimation);
-                    winAnimator.mAnimDw = params.mAnimDw;
-                    winAnimator.mAnimDh = params.mAnimDh;
-
-                    scheduleAnimationLocked();
-                    break;
-                }
-
                 case CLEAR_PENDING_ACTIONS: {
                     mAnimator.clearPendingActions();
                     break;
@@ -7525,7 +7542,10 @@
         }
 
         for (i=0; i<N; i++) {
-            WindowState w = mWindows.get(i);
+            final WindowState w = mWindows.get(i);
+            final WindowStateAnimator winAnimator = w.mWinAnimator;
+            boolean layerChanged = false;
+            int oldLayer = w.mLayer;
             if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
                     || (i > 0 && w.mIsWallpaper)) {
                 curLayer += WINDOW_LAYER_MULTIPLIER;
@@ -7534,22 +7554,33 @@
                 curBaseLayer = curLayer = w.mBaseLayer;
                 w.mLayer = curLayer;
             }
+            if (w.mLayer != oldLayer) {
+                layerChanged = true;
+            }
+            oldLayer = winAnimator.mAnimLayer;
             if (w.mTargetAppToken != null) {
-                w.mWinAnimator.mAnimLayer =
+                winAnimator.mAnimLayer =
                         w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
             } else if (w.mAppToken != null) {
-                w.mWinAnimator.mAnimLayer =
+                winAnimator.mAnimLayer =
                         w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
             } else {
-                w.mWinAnimator.mAnimLayer = w.mLayer;
+                winAnimator.mAnimLayer = w.mLayer;
             }
             if (w.mIsImWindow) {
-                w.mWinAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
+                winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
             } else if (w.mIsWallpaper) {
-                w.mWinAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
+                winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
+            }
+            if (winAnimator.mAnimLayer != oldLayer) {
+                layerChanged = true;
+            }
+            if (layerChanged && mAnimator.isDimming(winAnimator)) {
+                // Force an animation pass just to update the mDimAnimator layer.
+                scheduleAnimationLocked();
             }
             if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
-                    + w.mWinAnimator.mAnimLayer);
+                    + winAnimator.mAnimLayer);
             //System.out.println(
             //    "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
         }
@@ -7866,8 +7897,10 @@
                 mToTopApps.clear();
             }
 
+            // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
             WindowState oldWallpaper =
                     mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+                        && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
                     ? null : mWallpaperTarget;
 
             adjustWallpaperWindowsLocked();
@@ -8037,7 +8070,8 @@
                     drawSurface.unlockCanvasAndPost(c);
                     drawSurface.release();
                     topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer;
-                    Animation anim = createThumbnailAnimationLocked(transit, true, true);
+                    Animation anim = createThumbnailAnimationLocked(
+                            transit, true, true, mNextAppTransitionDelayed);
                     topOpeningApp.mAppAnimator.thumbnailAnimation = anim;
                     anim.restrictDuration(MAX_ANIMATION_DURATION);
                     anim.scaleCurrentDuration(mTransitionAnimationScale);
@@ -8250,7 +8284,8 @@
             if (!mInnerFields.mDimming) {
                 //Slog.i(TAG, "DIM BEHIND: " + w);
                 mInnerFields.mDimming = true;
-                if (!mAnimator.isDimming()) {
+                final WindowStateAnimator winAnimator = w.mWinAnimator;
+                if (!mAnimator.isDimming(winAnimator)) {
                     final int width, height;
                     if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
                         width = mCurDisplayWidth;
@@ -8259,7 +8294,7 @@
                         width = innerDw;
                         height = innerDh;
                     }
-                    mAnimator.startDimming(w.mWinAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount,
+                    mAnimator.startDimming(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount,
                             width, height);
                 }
             }
@@ -8415,9 +8450,6 @@
                     winAnimator.setAnimation(a);
                     winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
                     winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
-                } else {
-                    winAnimator.mAnimDw = innerDw;
-                    winAnimator.mAnimDh = innerDh;
                 }
 
                 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
@@ -9266,6 +9298,15 @@
         }
     }
 
+    // It is assumed that this method is called only by InputMethodManagerService.
+    public void saveLastInputMethodWindowForTransition() {
+        synchronized (mWindowMap) {
+            if (mInputMethodWindow != null) {
+                mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
+            }
+        }
+    }
+
     @Override
     public boolean hasNavigationBar() {
         return mPolicy.hasNavigationBar();
@@ -9609,10 +9650,12 @@
                             pw.println(mNextAppTransitionStartHeight);
                     break;
                 case ActivityOptions.ANIM_THUMBNAIL:
+                case ActivityOptions.ANIM_THUMBNAIL_DELAYED:
                     pw.print("  mNextAppTransitionThumbnail=");
                             pw.print(mNextAppTransitionThumbnail);
                             pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
                             pw.print(" mNextAppTransitionStartY="); pw.println(mNextAppTransitionStartY);
+                            pw.print(" mNextAppTransitionDelayed="); pw.println(mNextAppTransitionDelayed);
                     break;
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 4f08d92..293d3e8 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -142,6 +142,8 @@
         mContext = mService.mContext;
         mAttrFlags = win.mAttrs.flags;
         mAttrType = win.mAttrs.type;
+        mAnimDw = service.mAppDisplayWidth;
+        mAnimDh = service.mAppDisplayHeight;
     }
 
     public void setAnimation(Animation anim) {
@@ -177,6 +179,13 @@
                                 || atoken.inPendingTransaction));
     }
 
+    /** Is the window animating the DummyAnimation? */
+    boolean isDummyAnimation() {
+        final AppWindowToken atoken = mWin.mAppToken;
+        return atoken != null
+                && atoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
+    }
+
     /** Is this window currently animating? */
     boolean isWindowAnimating() {
         return mAnimation != null;
@@ -224,6 +233,8 @@
                         " scale=" + mService.mWindowAnimationScale);
                     mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
                             mAnimDw, mAnimDh);
+                    mAnimDw = mService.mAppDisplayWidth;
+                    mAnimDh = mService.mAppDisplayHeight;
                     mAnimation.setStartTime(currentTime);
                     mLocalAnimating = true;
                     mAnimating = true;
@@ -363,19 +374,33 @@
             mWin.mDestroying = true;
             if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
                 mWin, "HIDE (finishExit)", null);
-            mSurfaceShown = false;
-            try {
-                mSurface.hide();
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error hiding surface in " + this, e);
-            }
-            mLastHidden = true;
+            hide();
         }
         mWin.mExiting = false;
         if (mWin.mRemoveOnExit) {
             mService.mPendingRemove.add(mWin);
             mWin.mRemoveOnExit = false;
         }
+        if (mService.mWallpaperTarget == mWin && mService.mLowerWallpaperTarget == null) {
+            mAnimator.hideWallpapersLocked();
+        }
+    }
+
+    void hide() {
+        if (!mLastHidden) {
+            //dump();
+            mLastHidden = true;
+            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
+                    "HIDE (performLayout)", null);
+            if (mSurface != null) {
+                mSurfaceShown = false;
+                try {
+                    mSurface.hide();
+                } catch (RuntimeException e) {
+                    Slog.w(TAG, "Exception hiding surface in " + mWin);
+                }
+            }
+        }
     }
 
     boolean finishDrawingLocked() {
@@ -987,20 +1012,7 @@
         setSurfaceBoundaries(recoveringMemory);
 
         if (w.mAttachedHidden || !w.isReadyForDisplay()) {
-            if (!mLastHidden) {
-                //dump();
-                mLastHidden = true;
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "HIDE (performLayout)", null);
-                if (mSurface != null) {
-                    mSurfaceShown = false;
-                    try {
-                        mSurface.hide();
-                    } catch (RuntimeException e) {
-                        Slog.w(TAG, "Exception hiding surface in " + w);
-                    }
-                }
-            }
+            hide();
             // If we are waiting for this window to handle an
             // orientation change, well, it is hidden, so
             // doesn't really matter.  Note that this does
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 5afe56c..f740718 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1711,12 +1711,8 @@
             return false;
         }
 
-        // STOPSHIP: remove this after figuring out issue 5914560, 6383850.
         Log.d(LOG_TAG, "System property doesn't provide any emergency numbers."
-                + " Use embedded logic for determining emergency numbers."
-                + " number: " + toLogSafePhoneNumber(number)
-                + ", Iso: " + defaultCountryIso
-                + ", useExactMatch: " + useExactMatch);
+                + " Use embedded logic for determining ones.");
 
         // No ecclist system property, so use our own list.
         if (defaultCountryIso != null) {
@@ -1735,21 +1731,6 @@
         }
     }
 
-    private static String toLogSafePhoneNumber(String number) {
-        // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
-        // sanitized phone numbers.
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < number.length(); i++) {
-            char c = number.charAt(i);
-            if (c == '-' || c == '@' || c == '.') {
-                builder.append(c);
-            } else {
-                builder.append('x');
-            }
-        }
-        return builder.toString();
-    }
-
     /**
      * Checks if a given number is an emergency number for the country that the user is in. The
      * current country is determined using the CountryDetector.
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
index 80d5044..e984a87 100644
--- a/telephony/java/com/android/internal/telephony/ApnContext.java
+++ b/telephony/java/com/android/internal/telephony/ApnContext.java
@@ -129,9 +129,9 @@
         return apn;
     }
 
-    public synchronized void removeNextWaitingApn() {
-        if ((mWaitingApns != null) && (!mWaitingApns.isEmpty())) {
-            mWaitingApns.remove(0);
+    public synchronized void removeWaitingApn(ApnSetting apn) {
+        if (mWaitingApns != null) {
+            mWaitingApns.remove(apn);
         }
     }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index bfdb706..e2579e3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1970,19 +1970,11 @@
                 handleError = true;
             } else {
                 DataConnection dc = apnContext.getDataConnection();
-
-                if (DBG) {
-                    // TODO We may use apnContext.getApnSetting() directly
-                    // instead of getWaitingApns().get(0)
-                    String apnStr = "<unknown>";
-                    if (apnContext.getWaitingApns() != null
-                            && !apnContext.getWaitingApns().isEmpty()){
-                        apnStr = apnContext.getWaitingApns().get(0).apn;
-                    }
-                    log("onDataSetupComplete: success apn=" + apnStr);
-                }
                 ApnSetting apn = apnContext.getApnSetting();
-                if (apn.proxy != null && apn.proxy.length() != 0) {
+                if (DBG) {
+                    log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
+                }
+                if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
                     try {
                         String port = apn.port;
                         if (TextUtils.isEmpty(port)) port = "8080";
@@ -2000,7 +1992,7 @@
                     SystemProperties.set("gsm.defaultpdpcontext.active", "true");
                     if (canSetPreferApn && mPreferredApn == null) {
                         if (DBG) log("onDataSetupComplete: PREFERED APN is null");
-                        mPreferredApn = apnContext.getApnSetting();
+                        mPreferredApn = apn;
                         if (mPreferredApn != null) {
                             setPreferredApn(mPreferredApn.id);
                         }
@@ -2011,16 +2003,11 @@
                 notifyDefaultData(apnContext);
             }
         } else {
-            String apnString;
-
             cause = (DataConnection.FailCause) (ar.result);
             if (DBG) {
-                try {
-                    apnString = apnContext.getWaitingApns().get(0).apn;
-                } catch (Exception e) {
-                    apnString = "<unknown>";
-                }
-                log(String.format("onDataSetupComplete: error apn=%s cause=%s", apnString, cause));
+                ApnSetting apn = apnContext.getApnSetting();
+                log(String.format("onDataSetupComplete: error apn=%s cause=%s",
+                        (apn == null ? "unknown" : apn.apn), cause));
             }
             if (cause.isEventLoggable()) {
                 // Log this failure to the Event Logs.
@@ -2032,7 +2019,7 @@
             // Count permanent failures and remove the APN we just tried
             if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
 
-            apnContext.removeNextWaitingApn();
+            apnContext.removeWaitingApn(apnContext.getApnSetting());
             if (DBG) {
                 log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
                         " WaitingApnsPermFailureCountDown=%d",
diff --git a/test-runner/src/android/test/mock/MockContentResolver.java b/test-runner/src/android/test/mock/MockContentResolver.java
index 6c91f4e..65eb21b 100644
--- a/test-runner/src/android/test/mock/MockContentResolver.java
+++ b/test-runner/src/android/test/mock/MockContentResolver.java
@@ -106,6 +106,18 @@
         return true;
     }
 
+    /** @hide */
+    @Override
+    protected IContentProvider acquireUnstableProvider(Context c, String name) {
+        return acquireProvider(c, name);
+    }
+
+    /** @hide */
+    @Override
+    public boolean releaseUnstableProvider(IContentProvider icp) {
+        return releaseProvider(icp);
+    }
+
     /**
      * Overrides {@link android.content.ContentResolver#notifyChange(Uri, ContentObserver, boolean)
      * ContentResolver.notifChange(Uri, ContentObserver, boolean)}. All parameters are ignored.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 16f1575..9aed8c8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -307,6 +307,11 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static void freeTextLayoutCaches() {
+        // nothing to be done here yet.
+    }
+
+    @LayoutlibDelegate
     /*package*/ static int initRaster(int nativeBitmapOrZero) {
         if (nativeBitmapOrZero > 0) {
             // get the Bitmap from the int
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
index 0257686..fec2c3f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
@@ -62,6 +62,16 @@
         return false;
     }
 
+    @Override
+    protected IContentProvider acquireUnstableProvider(Context c, String name) {
+        return acquireProvider(c, name);
+    }
+
+    @Override
+    public boolean releaseUnstableProvider(IContentProvider icp) {
+        return releaseProvider(icp);
+    }
+
     /**
      * Stub for the layoutlib bridge content resolver.
      */
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 85b67d5..a4b2125 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -240,7 +240,7 @@
 
     @Override
     public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback) throws RemoteException {
+            IRemoteCallback startedCallback, boolean delayed) throws RemoteException {
         // TODO Auto-generated method stub
     }
 
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index f31ee68..5220d04 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -100,15 +100,11 @@
        Level 1  -88 <= RSSI < -78
        Level 0         RSSI < -88 */
 
-    /* Wi-fi connection is considered poor below this
-       RSSI level threshold and the watchdog report it
-       to the WifiStateMachine */
-    private static final int RSSI_LEVEL_CUTOFF = 0;
     /* Wi-fi connection is monitored actively below this
        threshold */
-    private static final int RSSI_LEVEL_MONITOR = 1;
-    /* RSSI threshold during monitoring below which network is avoided */
-    private static final int RSSI_MONITOR_THRESHOLD = -84;
+    private static final int RSSI_LEVEL_MONITOR = 0;
+    /* Rssi threshold is at level 0 (-88dBm) */
+    private static final int RSSI_MONITOR_THRESHOLD = -88;
     /* Number of times RSSI is measured to be low before being avoided */
     private static final int RSSI_MONITOR_COUNT = 5;
     private int mRssiMonitorCount = 0;
@@ -193,7 +189,7 @@
     private WalledGardenCheckState mWalledGardenCheckState = new WalledGardenCheckState();
     /* Online and watching link connectivity */
     private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
-    /* RSSI level is at RSSI_LEVEL_MONITOR and needs close monitoring */
+    /* RSSI level is below RSSI_LEVEL_MONITOR and needs close monitoring */
     private RssiMonitoringState mRssiMonitoringState = new RssiMonitoringState();
     /* Online and doing nothing */
     private OnlineState mOnlineState = new OnlineState();
@@ -731,9 +727,7 @@
         }
 
         private void handleRssiChange() {
-            if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
-                sendPoorLinkDetected();
-            } else if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
+            if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
                 transitionTo(mRssiMonitoringState);
             } else {
                 //stay here
@@ -773,9 +767,7 @@
             switch (msg.what) {
                 case EVENT_RSSI_CHANGE:
                     mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
-                    if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
-                        sendPoorLinkDetected();
-                    } else if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
+                    if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
                         //stay here;
                     } else {
                         //We dont need frequent RSSI monitoring any more
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index ef77d45..2c25e9d 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
-import android.net.nsd.DnsSdTxtRecord;
 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
@@ -46,6 +45,7 @@
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an
@@ -585,11 +585,11 @@
          *
          * @param fullDomainName full domain name. <br>
          * e.g) "MyPrinter._ipp._tcp.local.".
-         * @param record txt record.
+         * @param txtRecordMap TXT record data as a map of key/value pairs
          * @param srcDevice source device.
          */
         public void onDnsSdTxtRecordAvailable(String fullDomainName,
-                DnsSdTxtRecord record,
+                Map<String, String> txtRecordMap,
                 WifiP2pDevice srcDevice);
    }
 
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
index 54b7ac4..bc1d3c6 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
@@ -83,19 +83,22 @@
      *  e.g) "MyPrinter"
      * @param serviceType service type.<br>
      *  e.g) "_ipp._tcp"
-     * @param txtRecord TXT record as defined at
+     * @param txtMap TXT record with key/value pair in a map confirming to format defined at
      * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
      * @return Bonjour service information object
      */
     public static WifiP2pDnsSdServiceInfo newInstance(String instanceName,
-            String serviceType, DnsSdTxtRecord txtRecord) {
+            String serviceType, Map<String, String> txtMap) {
         if (TextUtils.isEmpty(instanceName) || TextUtils.isEmpty(serviceType)) {
             throw new IllegalArgumentException(
                     "instance name or service type cannot be empty");
         }
 
-        if (txtRecord == null) {
-            txtRecord = new DnsSdTxtRecord();
+        DnsSdTxtRecord txtRecord = new DnsSdTxtRecord();
+        if (txtMap != null) {
+            for (String key : txtMap.keySet()) {
+                txtRecord.set(key, txtMap.get(key));
+            }
         }
 
         ArrayList<String> queries = new ArrayList<String>();
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
index c053c8a..ed84a1a 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse.java
@@ -16,7 +16,6 @@
 
 package android.net.wifi.p2p.nsd;
 
-import android.net.nsd.DnsSdTxtRecord;
 import android.net.wifi.p2p.WifiP2pDevice;
 
 import java.io.ByteArrayInputStream;
@@ -68,7 +67,7 @@
      * This field is only used when the dns type equals to
      * {@link WifiP2pDnsSdServiceInfo#DNS_TYPE_TXT}.
      */
-    private DnsSdTxtRecord mTxtRecord;
+    private final HashMap<String, String> mTxtRecord = new HashMap<String, String>();
 
     /**
      * Virtual memory packet.
@@ -121,7 +120,7 @@
      * Return TXT record data.
      * @return TXT record data.
      */
-    public DnsSdTxtRecord getTxtRecord() {
+    public Map<String, String> getTxtRecord() {
         return mTxtRecord;
     }
 
@@ -133,8 +132,9 @@
         sbuf.append(" srcAddr:").append(mDevice.deviceAddress);
         sbuf.append(" version:").append(String.format("%02x", mVersion));
         sbuf.append(" dnsName:").append(mDnsQueryName);
-        if (mTxtRecord != null) {
-            sbuf.append(" TxtRecord:").append(mTxtRecord);
+        sbuf.append(" TxtRecord:");
+        for (String key : mTxtRecord.keySet()) {
+            sbuf.append(" key:").append(key).append(" value:").append(mTxtRecord.get(key));
         }
         if (mInstanceName != null) {
             sbuf.append(" InsName:").append(mInstanceName);
@@ -205,10 +205,7 @@
             mInstanceName = rData.substring(0,
                     rData.length() - mDnsQueryName.length() -1);
         } else if (mDnsType == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
-            mTxtRecord = readTxtData(dis);
-            if (mTxtRecord == null) {
-                return false;
-            }
+            return readTxtData(dis);
         } else {
             return false;
         }
@@ -261,10 +258,9 @@
      * Read TXT record data.
      *
      * @param dis
-     * @return TXT record data
+     * @return true if TXT data is valid
      */
-    private DnsSdTxtRecord readTxtData(DataInputStream dis) {
-        DnsSdTxtRecord txtRecord = new DnsSdTxtRecord();
+    private boolean readTxtData(DataInputStream dis) {
         try {
             while (dis.available() > 0) {
                 int len = dis.readUnsignedByte();
@@ -275,15 +271,15 @@
                 dis.readFully(data);
                 String[] keyVal = new String(data).split("=");
                 if (keyVal.length != 2) {
-                    return null;
+                    return false;
                 }
-                txtRecord.set(keyVal[0], keyVal[1]);
+                mTxtRecord.put(keyVal[0], keyVal[1]);
             }
-            return txtRecord;
+            return true;
         } catch (IOException e) {
             e.printStackTrace();
         }
-        return null;
+        return false;
     }
 
     /**