Merge "Fix locking for skip draw" into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 40f92ba..a8bf949 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2017,6 +2017,7 @@
     method protected void onServiceConnected();
     method public final boolean performGlobalAction(int);
     method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
+    field public static final int GESTURE_DOUBLE_TAP = 17; // 0x11
     field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2
     field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; // 0xf
     field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; // 0x10
@@ -2033,8 +2034,7 @@
     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 GESTURE_TAP_AND_HOLD = 18; // 0x12
     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
@@ -11236,7 +11236,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
@@ -12709,21 +12708,6 @@
 
 package android.net.nsd {
 
-  public class DnsSdServiceInfo implements android.os.Parcelable {
-    ctor public DnsSdServiceInfo();
-    method public int describeContents();
-    method public java.net.InetAddress getHost();
-    method public int getPort();
-    method public java.lang.String getServiceName();
-    method public java.lang.String getServiceType();
-    method public void setHost(java.net.InetAddress);
-    method public void setPort(int);
-    method public void setServiceName(java.lang.String);
-    method public void setServiceType(java.lang.String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
   public class DnsSdTxtRecord implements android.os.Parcelable {
     ctor public DnsSdTxtRecord();
     ctor public DnsSdTxtRecord(byte[]);
@@ -12740,53 +12724,56 @@
     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);
+  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 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 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 UNSUPPORTED = 1; // 0x1
+    field public static final int PROTOCOL_DNS_SD = 1; // 0x1
   }
 
-  public static abstract interface NsdManager.ActionListener {
-    method public abstract void onFailure(int);
-    method public abstract void onSuccess();
+  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 class NsdManager.Channel {
+  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.ChannelListener {
-    method public abstract void onChannelConnected(android.net.nsd.NsdManager.Channel);
-    method public abstract void onChannelDisconnected();
+  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 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);
+  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();
+    method public java.lang.String getServiceName();
+    method public java.lang.String getServiceType();
+    method public void setHost(java.net.InetAddress);
+    method public void setPort(int);
+    method public void setServiceName(java.lang.String);
+    method public void setServiceType(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
 }
@@ -18753,7 +18740,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 +18895,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 +18942,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 +19073,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 +19158,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 +19283,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 +19328,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 +19392,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 {
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index b644dd1..c559e54 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -284,14 +284,14 @@
     public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
 
     /**
-     * The user has performed a two finger tap gesture on the touch screen.
+     * The user has performed a double tap gesture on the touch screen.
      */
-    public static final int GESTURE_TWO_FINGER_TAP = 17;
+    public static final int GESTURE_DOUBLE_TAP = 17;
 
     /**
-     * The user has performed a two finger long press gesture on the touch screen.
+     * The user has performed a tap and hold gesture on the touch screen.
      */
-    public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18;
+    public static final int GESTURE_TAP_AND_HOLD = 18;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -408,8 +408,8 @@
      * @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
+     * @see #GESTURE_DOUBLE_TAP
+     * @see #GESTURE_TAP_AND_HOLD
      */
     protected boolean onGesture(int gestureId) {
         // TODO: Describe the default gesture processing in the javaDoc once it is finalized.
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index 69195c1..30be374 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.INCLUDE_NOT_IMPORTANT_VIEWS;
 
         try {
             manager.registerUiTestAutomationService(mListener, info);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 64a05a8..4943c9a 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
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 2ca2ae4..01b68d4 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -232,14 +232,15 @@
         if (mInfo != null) {
             padding = getDefaultPaddingForWidget(mContext, mInfo.provider, padding);
         }
+        float density = getResources().getDisplayMetrics().density;
 
-        int xPadding = padding.left + padding.right;
-        int yPadding = padding.top + padding.bottom;
+        int xPaddingDips = (int) ((padding.left + padding.right) / density);
+        int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
 
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth - xPadding);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight - yPadding);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth - xPadding);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight - yPadding);
+        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/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/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/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/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/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..ba8c4c9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1749,6 +1749,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 +2044,7 @@
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
             POINTER_SPEED,
+            VIBRATE_WHEN_RINGING
         };
 
         // Settings moved to Settings.Secure
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..6e6fab2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -408,6 +408,7 @@
 
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mAttachInfo.mScreenOn = powerManager.isScreenOn();
+        loadSystemProperties();
     }
 
     /**
@@ -846,6 +847,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);
     }
@@ -2730,6 +2741,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 +3009,9 @@
             case MSG_DISPATCH_DONE_ANIMATING: {
                 handleDispatchDoneAnimating();
             } break;
+            case MSG_INVALIDATE_WORLD: {
+                invalidateWorld(mView);
+            } break;
             }
         }
     }
@@ -4016,6 +4031,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;
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/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6f33b1e..3aafba5 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;
 
@@ -2121,9 +2128,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;
@@ -5671,6 +5746,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);
@@ -6226,6 +6302,7 @@
                 mScrapViews[viewType].add(scrap);
             }
 
+            scrap.setAccessibilityDelegate(null);
             if (mRecyclerListener != null) {
                 mRecyclerListener.onMovedToScrapHeap(scrap);
             }
@@ -6287,6 +6364,7 @@
                     lp.scrappedFromPosition = mFirstActivePosition + i;
                     scrapViews.add(victim);
 
+                    victim.setAccessibilityDelegate(null);
                     if (hasListener) {
                         mRecyclerListener.onMovedToScrapHeap(victim);
                     }
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/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/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/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/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/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/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/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/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/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/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/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-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/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..ec2abe0 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -45,7 +45,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/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_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/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/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..b908188 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -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/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/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e865b9c..995ee43 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -91,6 +91,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 +207,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
@@ -297,6 +314,7 @@
             mRecentTasksDirty = true;
             mWaitingToShow = false;
             mReadyToShow = false;
+            mRecentsNoApps.setVisibility(View.INVISIBLE);
         }
         if (animate) {
             if (mShowing != show) {
@@ -415,21 +433,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 +575,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 +634,6 @@
         }
     }
 
-    boolean mFirstScreenful;
     public void onTasksLoaded(ArrayList<TaskDescription> tasks) {
         if (!mFirstScreenful && tasks.size() == 0) {
             return;
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..f5f2e28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -106,6 +106,7 @@
             = "com.android.internal.policy.statusbar.START";
 
     private static final boolean ENABLE_INTRUDERS = false;
+    private static final boolean DIM_BEHIND_EXPANDED_PANEL = false;
 
     static final int EXPANDED_LEAVE_ALONE = -10000;
     static final int EXPANDED_FULL_OPEN = -10001;
@@ -212,6 +213,7 @@
 
     Choreographer mChoreographer;
     boolean mAnimating;
+    boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
     float mAnimY;
     float mAnimVel;
     float mAnimAccel;
@@ -311,6 +313,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 +467,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 +485,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 +494,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);
     }
 
@@ -565,8 +574,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)) {
@@ -1270,14 +1278,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 +1305,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 +1334,7 @@
         mPile.setLayerType(View.LAYER_TYPE_NONE, null);
         mVelocityTracker.recycle();
         mVelocityTracker = null;
+        mCloseView.setPressed(false);
     }
 
     void incrementAnim(long frameTimeNanos) {
@@ -1330,6 +1351,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 +1373,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 +1385,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 +1459,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 +1501,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
@@ -1987,11 +2014,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() {
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..b0830ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -704,7 +704,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 +713,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);
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 6e09b7f..6590fb3 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");
         }
@@ -170,10 +180,14 @@
     }
 
     /**
-     * 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();
 
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/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/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/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index e447218..1cb2092 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -259,7 +259,7 @@
                         updateInputFilterLocked();
                         sendStateToClientsLocked();
                     }
-                    
+
                     return;
                 }
 
@@ -1266,16 +1266,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 & INCLUDE_NOT_IMPORTANT_VIEWS) != 0;
             }
 
             synchronized (mLock) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ab35ac2..aa7de82 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) {
@@ -11057,7 +11082,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/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..e710b33 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() {
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 2e817ca..5536559 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,
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 6caa3e8..8957edf 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3430,9 +3430,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 +3822,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) {
@@ -4237,7 +4235,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 +6671,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 +7155,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;
@@ -7866,8 +7851,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();
@@ -8415,9 +8402,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 +9250,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();
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 4f08d92..642de73 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -177,6 +177,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;
@@ -363,19 +370,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) {
+            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 +1008,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/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