Merge "DHCP core classes, defining data, behavior, and state transitions for the DHCP protocol.  The DHCP client and DHCP server classes are not included in this commit: still working out some integration issues with ethernet & wifi services"
diff --git a/api/current.xml b/api/current.xml
index e76bd65..e2ceb3f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -4215,7 +4215,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843592"
+ value="16843593"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -4233,6 +4233,17 @@
  visibility="public"
 >
 </field>
+<field name="fastScrollPreviewBackgroundRight"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843591"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="fastScrollThumbDrawable"
  type="int"
  transient="false"
@@ -4248,7 +4259,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843591"
+ value="16843592"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -22167,6 +22178,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="prefix" type="java.lang.String">
+</parameter>
 <parameter name="fd" type="java.io.FileDescriptor">
 </parameter>
 <parameter name="writer" type="java.io.PrintWriter">
@@ -24426,6 +24439,17 @@
  visibility="public"
 >
 </field>
+<field name="RECENT_IGNORE_UNAVAILABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="RECENT_WITH_EXCLUDED"
  type="int"
  transient="false"
@@ -24437,6 +24461,17 @@
  visibility="public"
 >
 </field>
+<field name="TASKS_GET_THUMBNAILS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4096"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ActivityManager.MemoryInfo"
  extends="java.lang.Object"
@@ -24805,6 +24840,16 @@
  visibility="public"
 >
 </field>
+<field name="description"
+ type="java.lang.CharSequence"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="id"
  type="int"
  transient="false"
@@ -24825,6 +24870,16 @@
  visibility="public"
 >
 </field>
+<field name="thumbnail"
+ type="android.graphics.Bitmap"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ActivityManager.RunningAppProcessInfo"
  extends="java.lang.Object"
@@ -32145,6 +32200,25 @@
  visibility="public"
 >
 </constructor>
+<method name="dump"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="prefix" type="java.lang.String">
+</parameter>
+<parameter name="fd" type="java.io.FileDescriptor">
+</parameter>
+<parameter name="writer" type="java.io.PrintWriter">
+</parameter>
+<parameter name="args" type="java.lang.String[]">
+</parameter>
+</method>
 <method name="getLoader"
  return="android.content.Loader&lt;D&gt;"
  abstract="true"
@@ -48096,6 +48170,17 @@
  visibility="public"
 >
 </field>
+<field name="NFC_SERVICE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;nfc&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="NOTIFICATION_SERVICE"
  type="java.lang.String"
  transient="false"
@@ -50659,6 +50744,32 @@
  visibility="public"
 >
 </method>
+<method name="makeMainActivity"
+ return="android.content.Intent"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mainActivity" type="android.content.ComponentName">
+</parameter>
+</method>
+<method name="makeRestartActivityTask"
+ return="android.content.Intent"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mainActivity" type="android.content.ComponentName">
+</parameter>
+</method>
 <method name="parseIntent"
  return="android.content.Intent"
  abstract="false"
@@ -116831,6 +116942,19 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="context" type="android.content.Context">
+</parameter>
+</method>
+<method name="getDefaultAdapter"
+ return="android.nfc.NfcAdapter"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
 </method>
 <method name="isEnabled"
  return="boolean"
@@ -116877,6 +117001,26 @@
 >
 </field>
 </class>
+<class name="NfcManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getDefaultAdapter"
+ return="android.nfc.NfcAdapter"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
 </package>
 <package name="android.opengl"
 >
@@ -139382,6 +139526,39 @@
 <parameter name="tag" type="java.lang.String">
 </parameter>
 </method>
+<field name="ACTION_DROPBOX_ENTRY_ADDED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.DROPBOX_ENTRY_ADDED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TAG"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;tag&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TIME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;time&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="IS_EMPTY"
  type="int"
  transient="false"
@@ -162493,6 +162670,17 @@
  visibility="public"
 >
 </field>
+<field name="INPUT_METHOD_SELECTOR_VISIBILITY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;input_method_selector_visibility&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="INSTALL_NON_MARKET_APPS"
  type="java.lang.String"
  transient="false"
@@ -197894,6 +198082,17 @@
  visibility="public"
 >
 </method>
+<method name="getModifierMetaStateMask"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getNumber"
  return="char"
  abstract="false"
@@ -197951,6 +198150,30 @@
 <parameter name="metaState" type="int">
 </parameter>
 </method>
+<method name="hasModifiers"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modifiers" type="int">
+</parameter>
+</method>
+<method name="hasNoModifiers"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isAltPressed"
  return="boolean"
  abstract="false"
@@ -198118,6 +198341,47 @@
  visibility="public"
 >
 </method>
+<method name="metaStateHasModifiers"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metaState" type="int">
+</parameter>
+<parameter name="modifiers" type="int">
+</parameter>
+</method>
+<method name="metaStateHasNoModifiers"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metaState" type="int">
+</parameter>
+</method>
+<method name="normalizeMetaState"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="metaState" type="int">
+</parameter>
+</method>
 <method name="startTracking"
  return="void"
  abstract="false"
@@ -240987,6 +241251,17 @@
  visibility="public"
 >
 </method>
+<method name="isSplitTouchEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isTouchable"
  return="boolean"
  abstract="false"
@@ -241139,6 +241414,19 @@
 <parameter name="mode" type="int">
 </parameter>
 </method>
+<method name="setSplitTouchEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
 <method name="setTouchInterceptor"
  return="void"
  abstract="false"
@@ -286368,11 +286656,11 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="buf" type="byte[]">
+<parameter name="data" type="byte[]">
 </parameter>
-<parameter name="anOffset" type="int">
+<parameter name="offset" type="int">
 </parameter>
-<parameter name="aLength" type="int">
+<parameter name="byteCount" type="int">
 </parameter>
 </method>
 <method name="setData"
@@ -286398,7 +286686,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="len" type="int">
+<parameter name="length" type="int">
 </parameter>
 </method>
 <method name="setPort"
@@ -295171,7 +295459,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="chseq" type="java.lang.CharSequence">
+<parameter name="cs" type="java.lang.CharSequence">
 </parameter>
 <parameter name="start" type="int">
 </parameter>
@@ -347221,7 +347509,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347232,7 +347520,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347258,7 +347546,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347273,7 +347561,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347307,7 +347595,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347322,7 +347610,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347509,7 +347797,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -347550,7 +347838,7 @@
  native="false"
  synchronized="false"
  static="true"
- final="true"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
@@ -353679,7 +353967,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="c" type="java.util.Collection&lt;? extends E&gt;">
+<parameter name="collection" type="java.util.Collection&lt;? extends E&gt;">
 </parameter>
 </constructor>
 <constructor name="CopyOnWriteArrayList"
@@ -353696,7 +353984,7 @@
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -353709,7 +353997,7 @@
  return="void"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -353724,20 +354012,20 @@
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="c" type="java.util.Collection&lt;? extends E&gt;">
+<parameter name="collection" type="java.util.Collection&lt;? extends E&gt;">
 </parameter>
 </method>
 <method name="addAll"
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -353745,40 +354033,40 @@
 >
 <parameter name="index" type="int">
 </parameter>
-<parameter name="c" type="java.util.Collection&lt;? extends E&gt;">
+<parameter name="collection" type="java.util.Collection&lt;? extends E&gt;">
 </parameter>
 </method>
 <method name="addAllAbsent"
  return="int"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="c" type="java.util.Collection&lt;? extends E&gt;">
+<parameter name="collection" type="java.util.Collection&lt;? extends E&gt;">
 </parameter>
 </method>
 <method name="addIfAbsent"
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="e" type="E">
+<parameter name="object" type="E">
 </parameter>
 </method>
 <method name="clear"
  return="void"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -353819,7 +354107,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="c" type="java.util.Collection&lt;?&gt;">
+<parameter name="collection" type="java.util.Collection&lt;?&gt;">
 </parameter>
 </method>
 <method name="get"
@@ -353845,9 +354133,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="e" type="E">
+<parameter name="object" type="E">
 </parameter>
-<parameter name="index" type="int">
+<parameter name="from" type="int">
 </parameter>
 </method>
 <method name="indexOf"
@@ -353860,7 +354148,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="o" type="java.lang.Object">
+<parameter name="object" type="java.lang.Object">
 </parameter>
 </method>
 <method name="isEmpty"
@@ -353895,9 +354183,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="e" type="E">
+<parameter name="object" type="E">
 </parameter>
-<parameter name="index" type="int">
+<parameter name="to" type="int">
 </parameter>
 </method>
 <method name="lastIndexOf"
@@ -353910,7 +354198,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="o" type="java.lang.Object">
+<parameter name="object" type="java.lang.Object">
 </parameter>
 </method>
 <method name="listIterator"
@@ -353923,25 +354211,25 @@
  deprecated="not deprecated"
  visibility="public"
 >
-</method>
-<method name="listIterator"
- return="java.util.ListIterator&lt;E&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
 <parameter name="index" type="int">
 </parameter>
 </method>
+<method name="listIterator"
+ return="java.util.ListIterator&lt;E&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="remove"
  return="E"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -353954,7 +354242,7 @@
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -353967,33 +354255,33 @@
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="c" type="java.util.Collection&lt;?&gt;">
+<parameter name="collection" type="java.util.Collection&lt;?&gt;">
 </parameter>
 </method>
 <method name="retainAll"
  return="boolean"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="c" type="java.util.Collection&lt;?&gt;">
+<parameter name="collection" type="java.util.Collection&lt;?&gt;">
 </parameter>
 </method>
 <method name="set"
  return="E"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -354025,9 +354313,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="fromIndex" type="int">
+<parameter name="from" type="int">
 </parameter>
-<parameter name="toIndex" type="int">
+<parameter name="to" type="int">
 </parameter>
 </method>
 <method name="toArray"
@@ -354051,7 +354339,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="a" type="T[]">
+<parameter name="contents" type="T[]">
 </parameter>
 </method>
 </class>
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f62db1c..a236a3c 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -152,6 +152,7 @@
      * pm list permission-groups
      * pm list permissions
      * pm list features
+     * pm list libraries
      * pm list instrumentation
      */
     private void runList() {
@@ -169,6 +170,8 @@
             runListPermissions();
         } else if ("features".equals(type)) {
             runListFeatures();
+        } else if ("libraries".equals(type)) {
+            runListLibraries();
         } else if ("instrumentation".equals(type)) {
             runListInstrumentation();
         } else {
@@ -181,6 +184,8 @@
      * Lists all the installed packages.
      */
     private void runListPackages(boolean showApplicationPackage) {
+        int getFlags = 0;
+        boolean listDisabled = false, listEnabled = false;
         try {
             String opt;
             while ((opt=nextOption()) != null) {
@@ -190,6 +195,12 @@
                     showApplicationPackage = true;
                 } else if (opt.equals("-f")) {
                     showApplicationPackage = true;
+                } else if (opt.equals("-d")) {
+                    listDisabled = true;
+                } else if (opt.equals("-e")) {
+                    listEnabled = true;
+                } else if (opt.equals("-u")) {
+                    getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
                 } else {
                     System.err.println("Error: Unknown option: " + opt);
                     showUsage();
@@ -202,18 +213,26 @@
             return;
         }
 
+        String filter = nextArg();
+
         try {
-            List<PackageInfo> packages = mPm.getInstalledPackages(0 /* all */);
+            List<PackageInfo> packages = mPm.getInstalledPackages(getFlags);
 
             int count = packages.size();
             for (int p = 0 ; p < count ; p++) {
                 PackageInfo info = packages.get(p);
-                System.out.print("package:");
-                if (showApplicationPackage) {
-                    System.out.print(info.applicationInfo.sourceDir);
-                    System.out.print("=");
+                if (filter != null && !info.packageName.contains(filter)) {
+                    continue;
                 }
-                System.out.println(info.packageName);
+                if ((!listDisabled || !info.applicationInfo.enabled) &&
+                        (!listEnabled || info.applicationInfo.enabled)) {
+                    System.out.print("package:");
+                    if (showApplicationPackage) {
+                        System.out.print(info.applicationInfo.sourceDir);
+                        System.out.print("=");
+                    }
+                    System.out.println(info.packageName);
+                }
             }
         } catch (RemoteException e) {
             System.err.println(e.toString());
@@ -260,6 +279,42 @@
     }
 
     /**
+     * Lists all of the libraries supported by the current device.
+     *
+     * pm list libraries
+     */
+    private void runListLibraries() {
+        try {
+            List<String> list = new ArrayList<String>();
+            String[] rawList = mPm.getSystemSharedLibraryNames();
+            for (int i=0; i<rawList.length; i++) {
+                list.add(rawList[i]);
+            }
+
+
+            // Sort by name
+            Collections.sort(list, new Comparator<String>() {
+                public int compare(String o1, String o2) {
+                    if (o1 == o2) return 0;
+                    if (o1 == null) return -1;
+                    if (o2 == null) return 1;
+                    return o1.compareTo(o2);
+                }
+            });
+
+            int count = (list != null) ? list.size() : 0;
+            for (int p = 0; p < count; p++) {
+                String lib = list.get(p);
+                System.out.print("library:");
+                System.out.println(lib);
+            }
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+    }
+
+    /**
      * Lists all of the installed instrumentation, or all for a given package
      *
      * pm list instrumentation [package] [-f]
@@ -882,11 +937,12 @@
 
     private static void showUsage() {
         System.err.println("usage: pm [list|path|install|uninstall]");
-        System.err.println("       pm list packages [-f]");
+        System.err.println("       pm list packages [-f] [-d] [-e] [-u] [FILTER]");
         System.err.println("       pm list permission-groups");
         System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
         System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
         System.err.println("       pm list features");
+        System.err.println("       pm list libraries");
         System.err.println("       pm path PACKAGE");
         System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
@@ -894,8 +950,12 @@
         System.err.println("       pm disable PACKAGE_OR_COMPONENT");
         System.err.println("       pm setInstallLocation [0/auto] [1/internal] [2/external]");
         System.err.println("");
-        System.err.println("The list packages command prints all packages.  Options:");
+        System.err.println("The list packages command prints all packages, optionally only");
+        System.err.println("those whose package name contains the text in FILTER.  Options:");
         System.err.println("  -f: see their associated file.");
+        System.err.println("  -d: filter to include disbled packages.");
+        System.err.println("  -e: filter to include enabled packages.");
+        System.err.println("  -u: also include uninstalled packages.");
         System.err.println("");
         System.err.println("The list permission-groups command prints all known");
         System.err.println("permission groups.");
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index d843737..cb06c89 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -147,13 +147,14 @@
     private TimeInterpolator mChangingDisappearingInterpolator = new DecelerateInterpolator();
 
     /**
-     * This hashmap is used to store the animations that are currently running as part of
+     * These hashmaps are used to store the animations that are currently running as part of
      * the transition. The reason for this is that a further layout event should cause
      * existing animations to stop where they are prior to starting new animations. So
      * we cache all of the current animations in this map for possible cancellation on
      * another layout event.
      */
-    private HashMap<View, Animator> currentAnimations = new HashMap<View, Animator>();
+    private HashMap<View, Animator> currentChangingAnimations = new HashMap<View, Animator>();
+    private HashMap<View, Animator> currentVisibilityAnimations = new HashMap<View, Animator>();
 
     /**
      * This hashmap is used to track the listeners that have been added to the children of
@@ -542,17 +543,17 @@
             if (child != newView) {
 
                 // If there's an animation running on this view already, cancel it
-                Animator currentAnimation = currentAnimations.get(child);
+                Animator currentAnimation = currentChangingAnimations.get(child);
                 if (currentAnimation != null) {
                     currentAnimation.cancel();
-                    currentAnimations.remove(child);
+                    currentChangingAnimations.remove(child);
                 }
 
                 // Make a copy of the appropriate animation
                 final Animator anim = baseAnimator.clone();
 
                 // Cache the animation in case we need to cancel it later
-                currentAnimations.put(child, anim);
+                currentChangingAnimations.put(child, anim);
 
                 // Set the target object for the animation
                 anim.setTarget(child);
@@ -606,7 +607,7 @@
                     }
                     public void onAnimationEnd(Animator animator) {
                         if (!canceled) {
-                            currentAnimations.remove(child);
+                            currentChangingAnimations.remove(child);
                         }
                     }
                 });
@@ -640,6 +641,10 @@
      * @param child The View being added to the ViewGroup.
      */
     private void runAppearingTransition(final ViewGroup parent, final View child) {
+        Animator currentAnimation = currentVisibilityAnimations.get(child);
+        if (currentAnimation != null) {
+            currentAnimation.cancel();
+        }
         if (mAppearingAnim == null) {
             if (mListeners != null) {
                 for (TransitionListener listener : mListeners) {
@@ -658,12 +663,14 @@
         if (mListeners != null) {
             anim.addListener(new AnimatorListenerAdapter() {
                 public void onAnimationEnd() {
+                    currentVisibilityAnimations.remove(child);
                     for (TransitionListener listener : mListeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
                     }
                 }
             });
         }
+        currentVisibilityAnimations.put(child, anim);
         anim.start();
     }
 
@@ -674,6 +681,10 @@
      * @param child The View being removed from the ViewGroup.
      */
     private void runDisappearingTransition(final ViewGroup parent, final View child) {
+        Animator currentAnimation = currentVisibilityAnimations.get(child);
+        if (currentAnimation != null) {
+            currentAnimation.cancel();
+        }
         if (mDisappearingAnim == null) {
             if (mListeners != null) {
                 for (TransitionListener listener : mListeners) {
@@ -690,6 +701,7 @@
             anim.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator anim) {
+                    currentVisibilityAnimations.remove(child);
                     for (TransitionListener listener : mListeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
                     }
@@ -699,6 +711,7 @@
         if (anim instanceof ObjectAnimator) {
             ((ObjectAnimator) anim).setCurrentPlayTime(0);
         }
+        currentVisibilityAnimations.put(child, anim);
         anim.start();
     }
 
diff --git a/core/java/android/animation/TimeAnimator.java b/core/java/android/animation/TimeAnimator.java
new file mode 100644
index 0000000..0a96d59
--- /dev/null
+++ b/core/java/android/animation/TimeAnimator.java
@@ -0,0 +1,78 @@
+package android.animation;
+
+/**
+ * This class provides a simple callback mechanism to listeners that is synchronized with other
+ * animators in the system. There is no duration, interpolation, or object value-setting
+ * with this Animator. Instead, it is simply started and proceeds to send out events on every
+ * animation frame to its TimeListener (if set), with information about this animator,
+ * the total elapsed time, and the time since the last animation frame.
+ *
+ * @hide
+ */
+public class TimeAnimator extends ValueAnimator {
+
+    private TimeListener mListener;
+    private long mPreviousTime = -1;
+
+    @Override
+    boolean animationFrame(long currentTime) {
+        if (mPlayingState == STOPPED) {
+            mPlayingState = RUNNING;
+            if (mSeekTime < 0) {
+                mStartTime = currentTime;
+            } else {
+                mStartTime = currentTime - mSeekTime;
+                // Now that we're playing, reset the seek time
+                mSeekTime = -1;
+            }
+        }
+        if (mListener != null) {
+            long totalTime = currentTime - mStartTime;
+            long deltaTime = (mPreviousTime < 0) ? 0 : (currentTime - mPreviousTime);
+            mPreviousTime = currentTime;
+            mListener.onTimeUpdate(this, totalTime, deltaTime);
+        }
+        return false;
+    }
+
+    /**
+     * Sets a listener that is sent update events throughout the life of
+     * an animation.
+     *
+     * @param listener the listener to be set.
+     */
+    public void setTimeListener(TimeListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    void animateValue(float fraction) {
+        // Noop
+    }
+
+    @Override
+    void initAnimation() {
+        // noop
+    }
+
+    /**
+     * Implementors of this interface can set themselves as update listeners
+     * to a <code>TimeAnimator</code> instance to receive callbacks on every animation
+     * frame to receive the total time since the animator started and the delta time
+     * since the last frame. The first time the listener is called, totalTime and
+     * deltaTime should both be zero.
+     *
+     * @hide
+     */
+    public static interface TimeListener {
+        /**
+         * <p>Notifies listeners of the occurrence of another frame of the animation,
+         * along with information about the elapsed time.</p>
+         *
+         * @param animation The animator sending out the notification.
+         * @param totalTime The
+         */
+        void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime);
+
+    }
+}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 1542c49..50082f9 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -60,9 +60,9 @@
      * Values used with internal variable mPlayingState to indicate the current state of an
      * animation.
      */
-    private static final int STOPPED    = 0; // Not yet playing
-    private static final int RUNNING    = 1; // Playing normally
-    private static final int SEEKED     = 2; // Seeked to some time value
+    static final int STOPPED    = 0; // Not yet playing
+    static final int RUNNING    = 1; // Playing normally
+    static final int SEEKED     = 2; // Seeked to some time value
 
     /**
      * Internal variables
@@ -74,13 +74,13 @@
     // The first time that the animation's animateFrame() method is called. This time is used to
     // determine elapsed time (and therefore the elapsed fraction) in subsequent calls
     // to animateFrame()
-    private long mStartTime;
+    long mStartTime;
 
     /**
      * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
      * to a value.
      */
-    private long mSeekTime = -1;
+    long mSeekTime = -1;
 
     // TODO: We access the following ThreadLocal variables often, some of them on every update.
     // If ThreadLocal access is significantly expensive, we may want to put all of these
@@ -178,7 +178,7 @@
      * has been cancel()'d or end()'d since the last animation frame. Possible values are
      * STOPPED, RUNNING, SEEKED.
      */
-    private int mPlayingState = STOPPED;
+    int mPlayingState = STOPPED;
 
     /**
      * Flag that denotes whether the animation is set up and ready to go. Used to
@@ -1051,7 +1051,7 @@
      * @return true if the animation's duration, including any repetitions due to
      * <code>repeatCount</code> has been exceeded and the animation should be ended.
      */
-    private boolean animationFrame(long currentTime) {
+    boolean animationFrame(long currentTime) {
         boolean done = false;
 
         if (mPlayingState == STOPPED) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index aaebbd0..5f460a2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4095,15 +4095,36 @@
 
     /**
      * Print the Activity's state into the given stream.  This gets invoked if
-     * you run "adb shell dumpsys activity <youractivityname>".
+     * you run "adb shell dumpsys activity <activity_component_name>".
      *
+     * @param prefix Desired prefix to prepend at each line of output.
      * @param fd The raw file descriptor that the dump is being sent to.
      * @param writer The PrintWriter to which you should dump your state.  This will be
      * closed for you after you return.
      * @param args additional arguments to the dump request.
      */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        mFragments.dump("", fd, writer, args);
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        writer.print(prefix); writer.print("Local Activity ");
+                writer.print(Integer.toHexString(System.identityHashCode(this)));
+                writer.println(" State:");
+        String innerPrefix = prefix + "  ";
+        writer.print(innerPrefix); writer.print("mResumed=");
+                writer.print(mResumed); writer.print(" mStopped=");
+                writer.print(mStopped); writer.print(" mFinished=");
+                writer.println(mFinished);
+        writer.print(innerPrefix); writer.print("mLoadersStarted=");
+                writer.println(mLoadersStarted);
+        writer.print(innerPrefix); writer.print("mChangingConfigurations=");
+                writer.println(mChangingConfigurations);
+        writer.print(innerPrefix); writer.print("mCurrentConfig=");
+                writer.println(mCurrentConfig);
+        if (mLoaderManager != null) {
+            writer.print(prefix); writer.print("Loader Manager ");
+                    writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager)));
+                    writer.println(":");
+            mLoaderManager.dump(prefix + "  ", fd, writer, args);
+        }
+        mFragments.dump(prefix, fd, writer, args);
     }
 
     /**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e168034..ebdc7fd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -93,6 +93,17 @@
          * implementation that the alias referred to.  Otherwise, this is null.
          */
         public ComponentName origActivity;
+
+        /**
+         * Thumbnail representation of the task's last state.  Must
+         * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
+         */
+        public Bitmap thumbnail;
+
+        /**
+         * Description of the task's last state.
+         */
+        public CharSequence description;
         
         public RecentTaskInfo() {
         }
@@ -110,6 +121,14 @@
                 dest.writeInt(0);
             }
             ComponentName.writeToParcel(origActivity, dest);
+            if (thumbnail != null) {
+                dest.writeInt(1);
+                thumbnail.writeToParcel(dest, 0);
+            } else {
+                dest.writeInt(0);
+            }
+            TextUtils.writeToParcel(description, dest,
+                    Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         }
 
         public void readFromParcel(Parcel source) {
@@ -120,6 +139,12 @@
                 baseIntent = null;
             }
             origActivity = ComponentName.readFromParcel(source);
+            if (source.readInt() != 0) {
+                thumbnail = Bitmap.CREATOR.createFromParcel(source);
+            } else {
+                thumbnail = null;
+            }
+            description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
         }
         
         public static final Creator<RecentTaskInfo> CREATOR
@@ -145,11 +170,16 @@
     public static final int RECENT_WITH_EXCLUDED = 0x0001;
     
     /**
-     * @hide
-     * TODO: Make this public.  Provides a list that does not contain any
+     * Provides a list that does not contain any
      * recent tasks that currently are not available to the user.
      */
     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
+
+    /**
+     * Flag for use with {@link #getRecentTasks}: also return the thumbnail
+     * bitmap (if available) for each recent task.
+     */
+    public static final int TASKS_GET_THUMBNAILS = 0x0001000;
     
     /**
      * Return a list of the tasks that the user has recently launched, with
@@ -158,6 +188,9 @@
      * @param maxNum The maximum number of entries to return in the list.  The
      * actual number returned may be smaller, depending on how many tasks the
      * user has started and the maximum number the system can remember.
+     * @param flags Information about what to return.  May be any combination
+     * of {@link #RECENT_WITH_EXCLUDED}, {@link #RECENT_IGNORE_UNAVAILABLE},
+     * and {@link #TASKS_GET_THUMBNAILS}.
      * 
      * @return Returns a list of RecentTaskInfo records describing each of
      * the recent tasks.
@@ -203,7 +236,8 @@
         public ComponentName topActivity;
 
         /**
-         * Thumbnail representation of the task's current state.
+         * Thumbnail representation of the task's current state.  Must
+         * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
          */
         public Bitmap thumbnail;
 
@@ -273,7 +307,7 @@
             readFromParcel(source);
         }
     }
-
+    
     /**
      * Return a list of the tasks that are currently running, with
      * the most recent being first and older ones after in order.  Note that
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 449992e..43f9d52 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -361,6 +361,7 @@
     private static final class DumpComponentInfo {
         FileDescriptor fd;
         IBinder token;
+        String prefix;
         String[] args;
         boolean dumped;
     }
@@ -680,10 +681,12 @@
             queueOrSendMessage(H.SCHEDULE_CRASH, msg);
         }
 
-        public void dumpActivity(FileDescriptor fd, IBinder activitytoken, String[] args) {
+        public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
+                String prefix, String[] args) {
             DumpComponentInfo data = new DumpComponentInfo();
             data.fd = fd;
             data.token = activitytoken;
+            data.prefix = prefix;
             data.args = args;
             data.dumped = false;
             queueOrSendMessage(H.DUMP_ACTIVITY, data);
@@ -2076,7 +2079,7 @@
             ActivityClientRecord r = mActivities.get(info.token);
             if (r != null && r.activity != null) {
                 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
-                r.activity.dump(info.fd, pw, info.args);
+                r.activity.dump(info.prefix, info.fd, pw, info.args);
                 pw.close();
             }
         } finally {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index abb26e3..7589e99 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -115,8 +115,9 @@
             return null;
         }
         Intent intent = new Intent(intentToResolve);
-        intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
-                            resolveInfo.activityInfo.name);
+        // Note: we do NOT fill in the component name; we'll leave the
+        // Intent unspecified, so if there are multiple matches within the
+        // package something reasonable will happen.
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         return intent;
     }
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 801c3f9..d28e8533 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -434,9 +434,10 @@
             data.enforceInterface(IApplicationThread.descriptor);
             ParcelFileDescriptor fd = data.readFileDescriptor();
             final IBinder activity = data.readStrongBinder();
+            final String prefix = data.readString();
             final String[] args = data.readStringArray();
             if (fd != null) {
-                dumpActivity(fd.getFileDescriptor(), activity, args);
+                dumpActivity(fd.getFileDescriptor(), activity, prefix, args);
                 try {
                     fd.close();
                 } catch (IOException e) {
@@ -906,12 +907,13 @@
         data.recycle();
     }
 
-    public void dumpActivity(FileDescriptor fd, IBinder token, String[] args)
+    public void dumpActivity(FileDescriptor fd, IBinder token, String prefix, String[] args)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeFileDescriptor(fd);
         data.writeStrongBinder(token);
+        data.writeString(prefix);
         data.writeStringArray(args);
         mRemote.transact(DUMP_ACTIVITY_TRANSACTION, data, null, 0);
         data.recycle();
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index e9b6869..33b747c 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -21,6 +21,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 final class BackStackState implements Parcelable {
@@ -196,6 +198,67 @@
     int mBreadCrumbShortTitleRes;
     CharSequence mBreadCrumbShortTitleText;
 
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        writer.print(prefix); writer.print("mName="); writer.print(mName);
+                writer.print(" mIndex="); writer.print(mIndex);
+                writer.print(" mCommitted="); writer.println(mCommitted);
+        if (mTransition != FragmentTransaction.TRANSIT_NONE) {
+            writer.print(prefix); writer.print("mTransition=#");
+                    writer.print(Integer.toHexString(mTransition));
+                    writer.print(" mTransitionStyle=#");
+                    writer.println(Integer.toHexString(mTransitionStyle));
+        }
+        if (mEnterAnim != 0 || mExitAnim !=0) {
+            writer.print(prefix); writer.print("mEnterAnim=#");
+                    writer.print(Integer.toHexString(mEnterAnim));
+                    writer.print(" mExitAnim=#");
+                    writer.println(Integer.toHexString(mExitAnim));
+        }
+        if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
+            writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
+                    writer.print(Integer.toHexString(mBreadCrumbTitleRes));
+                    writer.print(" mBreadCrumbTitleText=");
+                    writer.println(mBreadCrumbTitleText);
+        }
+        if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
+            writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
+                    writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
+                    writer.print(" mBreadCrumbShortTitleText=");
+                    writer.println(mBreadCrumbShortTitleText);
+        }
+
+        if (mHead != null) {
+            writer.print(prefix); writer.println("Operations:");
+            String innerPrefix = prefix + "    ";
+            Op op = mHead;
+            int num = 0;
+            while (op != null) {
+                writer.print(prefix); writer.print("  Op #"); writer.print(num);
+                        writer.println(":");
+                writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd);
+                        writer.print(" fragment="); writer.println(op.fragment);
+                if (op.enterAnim != 0 || op.exitAnim != 0) {
+                    writer.print(prefix); writer.print("enterAnim="); writer.print(op.enterAnim);
+                            writer.print(" exitAnim="); writer.println(op.exitAnim);
+                }
+                if (op.removed != null && op.removed.size() > 0) {
+                    for (int i=0; i<op.removed.size(); i++) {
+                        writer.print(innerPrefix);
+                        if (op.removed.size() == 1) {
+                            writer.print("Removed: ");
+                        } else {
+                            writer.println("Removed:");
+                            writer.print(innerPrefix); writer.print("  #"); writer.print(num);
+                                    writer.print(": "); 
+                        }
+                        writer.println(op.removed.get(i));
+                    }
+                }
+                op = op.next;
+            }
+        }
+    }
+
     public BackStackRecord(FragmentManagerImpl manager) {
         mManager = manager;
     }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f1842c6..083612e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -64,6 +64,7 @@
 import android.net.Uri;
 import android.net.wifi.IWifiManager;
 import android.net.wifi.WifiManager;
+import android.nfc.NfcManager;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -313,6 +314,11 @@
                     return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
                 }});
 
+        registerService(NFC_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return new NfcManager(ctx);
+                }});
+
         registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
                 public Object createStaticService() {
                     return createDropBoxManager();
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 4aa4d77..ed4aed2 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -908,7 +908,7 @@
             if (cursor == null) {
                 return null;
             }
-            while (cursor.moveToFirst()) {
+            if (cursor.moveToFirst()) {
                 int status = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STATUS));
                 if (DownloadManager.STATUS_SUCCESSFUL == status) {
                     int indx = cursor.getColumnIndexOrThrow(
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index b103385..348149e 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -526,7 +526,16 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
-        sb.append("Fragment{");
+        String simpleName = getClass().getSimpleName();
+        if (simpleName == null || simpleName.isEmpty()) {
+            simpleName = getClass().getName();
+            int end = simpleName.lastIndexOf('.');
+            if (end > 0) {
+                simpleName = simpleName.substring(end+1);
+            }
+        }
+        sb.append(simpleName);
+        sb.append("{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         if (mIndex >= 0) {
             sb.append(" #");
@@ -1186,8 +1195,10 @@
      * @param args additional arguments to the dump request.
      */
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
-        writer.print(prefix); writer.print("mFragmentId="); writer.print(mFragmentId);
-                writer.print(" mContainerId="); writer.print(mContainerId);
+        writer.print(prefix); writer.print("mFragmentId=#");
+                writer.print(Integer.toHexString(mFragmentId));
+                writer.print(" mContainerId#=");
+                writer.print(Integer.toHexString(mContainerId));
                 writer.print(" mTag="); writer.println(mTag);
         writer.print(prefix); writer.print("mState="); writer.print(mState);
                 writer.print(" mIndex="); writer.print(mIndex);
@@ -1239,10 +1250,8 @@
             writer.print(prefix); writer.print("mView="); writer.println(mView);
         }
         if (mLoaderManager != null) {
-            writer.print(prefix); writer.print("mLoaderManager="); writer.print(mLoaderManager);
-                    writer.print(" mLoadersStarted="); writer.print(mLoadersStarted);
-                    writer.print(" mCheckedForLoaderManager=");
-                    writer.println(mCheckedForLoaderManager);
+            writer.print(prefix); writer.println("Loader Manager:");
+            mLoaderManager.dump(prefix + "  ", fd, writer, args);
         }
     }
 
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 1b2d4df..488b673 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -248,7 +248,7 @@
      * @param prefix Text to print at the front of each line.
      * @param fd The raw file descriptor that the dump is being sent to.
      * @param writer A PrintWriter to which the dump is to be set.
-     * @param args additional arguments to the dump request.
+     * @param args Additional arguments to the dump request.
      */
     public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
 }
@@ -293,7 +293,7 @@
  * Container for fragments associated with an activity.
  */
 final class FragmentManagerImpl extends FragmentManager {
-    static final boolean DEBUG = true;
+    static final boolean DEBUG = false;
     static final String TAG = "FragmentManager";
     
     static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -456,7 +456,9 @@
             return;
         }
 
-        writer.print(prefix); writer.println("Active Fragments:");
+        writer.print(prefix); writer.print("Active Fragments in ");
+                writer.print(Integer.toHexString(System.identityHashCode(this)));
+                writer.println(":");
 
         String innerPrefix = prefix + "    ";
 
@@ -490,6 +492,7 @@
                     BackStackRecord bs = mBackStack.get(i);
                     writer.print(prefix); writer.print("  #"); writer.print(i);
                             writer.print(": "); writer.println(bs.toString());
+                    bs.dump(innerPrefix, fd, writer, args);
                 }
             }
         }
@@ -559,6 +562,7 @@
                         }
                     }
                     f.mActivity = mActivity;
+                    f.mFragmentManager = mActivity.mFragments;
                     f.mCalled = false;
                     f.onAttach(mActivity);
                     if (!f.mCalled) {
@@ -734,6 +738,7 @@
                         }
                         f.mImmediateActivity = null;
                         f.mActivity = null;
+                        f.mFragmentManager = null;
                     }
             }
         }
@@ -1312,6 +1317,10 @@
                 Fragment f = fs.instantiate(mActivity);
                 if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f);
                 mActive.add(f);
+                // Now that the fragment is instantiated (or came from being
+                // retained above), clear mInstance in case we end up re-restoring
+                // from this FragmentState again.
+                fs.mInstance = null;
             } else {
                 if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": (null)");
                 mActive.add(null);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index eca84ef..ecd199c 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -107,7 +107,7 @@
     static final int EXTERNAL_STORAGE_UNAVAILABLE = 1;
     void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException;
     void scheduleCrash(String msg) throws RemoteException;
-    void dumpActivity(FileDescriptor fd, IBinder servicetoken, String[] args)
+    void dumpActivity(FileDescriptor fd, IBinder servicetoken, String prefix, String[] args)
             throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 7ae4b95..0ab987a 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -21,6 +21,9 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 /**
  * Interface associated with an {@link Activity} or {@link Fragment} for managing
  * one or more {@link android.content.Loader} instances associated with it.
@@ -90,6 +93,16 @@
      * is found.
      */
     public abstract <D> Loader<D> getLoader(int id);
+
+    /**
+     * Print the LoaderManager's state into the given stream.
+     *
+     * @param prefix Text to print at the front of each line.
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param writer A PrintWriter to which the dump is to be set.
+     * @param args Additional arguments to the dump request.
+     */
+    public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
 }
 
 class LoaderManagerImpl extends LoaderManager {
@@ -123,7 +136,7 @@
         boolean mRetainingStarted;
         boolean mDestroyed;
         boolean mListenerRegistered;
-        
+
         public LoaderInfo(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callbacks) {
             mId = id;
             mArgs = args;
@@ -271,6 +284,28 @@
             sb.append("}");
             return sb.toString();
         }
+
+        public String toBasicString() {
+            StringBuilder sb = new StringBuilder(64);
+            sb.append("LoaderInfo{");
+            sb.append(Integer.toHexString(System.identityHashCode(this)));
+            sb.append(" #");
+            sb.append(mId);
+            sb.append("}");
+            return sb.toString();
+        }
+
+        public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+            writer.print(prefix); writer.print("mId="); writer.print(mId);
+                    writer.print(" mArgs="); writer.println(mArgs);
+            writer.print(prefix); writer.print("mCallbacks="); writer.println(mCallbacks);
+            writer.print(prefix); writer.print("mLoader="); writer.println(mLoader);
+            writer.print(prefix); writer.print("mData="); writer.println(mData);
+            writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
+                    writer.print(" mRetaining="); writer.print(mRetaining);
+                    writer.print(" mDestroyed="); writer.print(mDestroyed);
+                    writer.print(" mListenerRegistered="); writer.println(mListenerRegistered);
+        }
     }
     
     LoaderManagerImpl(Activity activity, boolean started) {
@@ -443,4 +478,28 @@
         }
         mInactiveLoaders.clear();
     }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (mLoaders.size() > 0) {
+            writer.print(prefix); writer.println("Active Loaders:");
+            String innerPrefix = prefix + "    ";
+            for (int i=0; i < mLoaders.size(); i++) {
+                LoaderInfo li = mLoaders.valueAt(i);
+                writer.print(prefix); writer.print("  #"); writer.print(mLoaders.keyAt(i));
+                        writer.print(": "); writer.println(li.toBasicString());
+                li.dump(innerPrefix, fd, writer, args);
+            }
+        }
+        if (mInactiveLoaders.size() > 0) {
+            writer.print(prefix); writer.println("Inactive Loaders:");
+            String innerPrefix = prefix + "    ";
+            for (int i=0; i < mInactiveLoaders.size(); i++) {
+                LoaderInfo li = mInactiveLoaders.valueAt(i);
+                writer.print(prefix); writer.print("  #"); writer.print(mInactiveLoaders.keyAt(i));
+                        writer.print(": "); writer.println(li.toBasicString());
+                li.dump(innerPrefix, fd, writer, args);
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/backup/FileBackupHelperBase.java b/core/java/android/app/backup/FileBackupHelperBase.java
index 1e3158f..887a2e6 100644
--- a/core/java/android/app/backup/FileBackupHelperBase.java
+++ b/core/java/android/app/backup/FileBackupHelperBase.java
@@ -81,7 +81,7 @@
         }
     }
 
-    void writeFile(File f, BackupDataInputStream in) {
+    boolean writeFile(File f, BackupDataInputStream in) {
         int result = -1;
 
         // Create the enclosing directory.
@@ -98,6 +98,7 @@
                 mExceptionLogged = true;
             }
         }
+        return (result == 0);
     }
 
     public void writeNewStateDescription(ParcelFileDescriptor fd) {
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
new file mode 100644
index 0000000..9808200
--- /dev/null
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.BitmapFactory;
+import android.os.ParcelFileDescriptor;
+import android.util.Slog;
+
+import java.io.File;
+
+/**
+ * Helper for backing up / restoring wallpapers.  Basically an AbsoluteFileBackupHelper,
+ * but with logic for deciding what to do with restored wallpaper images.
+ *
+ * @hide
+ */
+public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper {
+    private static final String TAG = "WallpaperBackupHelper";
+    private static final boolean DEBUG = false;
+
+    // This path must match what the WallpaperManagerService uses
+    private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper";
+
+    // Stage file - should be adjacent to the WALLPAPER_IMAGE location.  The wallpapers
+    // will be saved to this file from the restore stream, then renamed to the proper
+    // location if it's deemed suitable.
+    private static final String STAGE_FILE = "/data/data/com.android.settings/files/wallpaper-tmp";
+
+    Context mContext;
+    String[] mFiles;
+    double mDesiredMinWidth;
+    double mDesiredMinHeight;
+
+    /**
+     * Construct a helper for backing up / restoring the files at the given absolute locations
+     * within the file system.
+     *
+     * @param context
+     * @param files
+     */
+    public WallpaperBackupHelper(Context context, String... files) {
+        super(context);
+
+        mContext = context;
+        mFiles = files;
+
+        WallpaperManager wpm;
+        wpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
+        mDesiredMinWidth = (double) wpm.getDesiredMinimumWidth();
+        mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight();
+    }
+
+    /**
+     * Based on oldState, determine which of the files from the application's data directory
+     * need to be backed up, write them to the data stream, and fill in newState with the
+     * state as it exists now.
+     */
+    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+            ParcelFileDescriptor newState) {
+        performBackup_checked(oldState, data, newState, mFiles, mFiles);
+    }
+
+    /**
+     * Restore one absolute file entity from the restore stream.  If we're restoring the
+     * magic wallpaper file, take specific action to determine whether it is suitable for
+     * the current device.
+     */
+    public void restoreEntity(BackupDataInputStream data) {
+        final String key = data.getKey();
+        if (isKeyInList(key, mFiles)) {
+            if (key.equals(WALLPAPER_IMAGE)) {
+                // restore the file to the stage for inspection
+                File f = new File(STAGE_FILE);
+                if (writeFile(f, data)) {
+
+                    // Preflight the restored image's dimensions without loading it
+                    BitmapFactory.Options options = new BitmapFactory.Options();
+                    options.inJustDecodeBounds = true;
+                    BitmapFactory.decodeFile(STAGE_FILE, options);
+
+                    if (DEBUG) Slog.v(TAG, "Restoring wallpaper image w=" + options.outWidth
+                            + " h=" + options.outHeight);
+
+                    // how much does the image differ from our preference?
+                    double widthRatio = mDesiredMinWidth / options.outWidth;
+                    double heightRatio = mDesiredMinHeight / options.outHeight;
+                    if (widthRatio > 0.8 && widthRatio < 1.25
+                            && heightRatio > 0.8 && heightRatio < 1.25) {
+                        // sufficiently close to our resolution; go ahead and use it
+                        if (DEBUG) Slog.v(TAG, "wallpaper dimension match; using");
+                        f.renameTo(new File(WALLPAPER_IMAGE));
+                        // TODO: spin a service to copy the restored image to sd/usb storage,
+                        // since it does not exist anywhere other than the private wallpaper
+                        // file.
+                    } else {
+                        if (DEBUG) Slog.v(TAG, "dimensions too far off: wr=" + widthRatio
+                                + " hr=" + heightRatio);
+                        f.delete();
+                    }
+                }
+            } else {
+                // Some other normal file; just decode it to its destination
+                File f = new File(key);
+                writeFile(f, data);
+            }
+        }
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 3eadff9..80a80bd 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -82,7 +82,7 @@
     public static final int TRANSITION_TO_STABLE = 102;
     public static final int CONNECT_OTHER_PROFILES = 103;
 
-    private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs
+    private static final int CONNECT_OTHER_PROFILES_DELAY = 4000; // 4 secs
 
     private BondedDevice mBondedDevice = new BondedDevice();
     private OutgoingHandsfree mOutgoingHandsfree = new OutgoingHandsfree();
@@ -152,7 +152,7 @@
             } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
                 Message msg = new Message();
                 msg.what = AUTO_CONNECT_PROFILES;
-                sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
+                sendMessage(msg);
             } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                 // This is technically not needed, but we can get stuck sometimes.
                 // For example, if incoming A2DP fails, we are not informed by Bluez
@@ -1019,7 +1019,7 @@
                     Message msg = new Message();
                     msg.what = CONNECT_OTHER_PROFILES;
                     msg.arg1 = CONNECT_A2DP_OUTGOING;
-                    sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
+                    sendMessageDelayed(msg, CONNECT_OTHER_PROFILES_DELAY);
                 }
                 break;
             case CONNECT_A2DP_INCOMING:
@@ -1031,7 +1031,7 @@
                     Message msg = new Message();
                     msg.what = CONNECT_OTHER_PROFILES;
                     msg.arg1 = CONNECT_HFP_OUTGOING;
-                    sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
+                    sendMessageDelayed(msg, CONNECT_OTHER_PROFILES_DELAY);
                 }
                 break;
             default:
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 3fbfc70..5962235 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -20,6 +20,7 @@
 
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.UUID;
 
 /**
 * Static helper methods and constants to decode the ParcelUuid of remote devices.
@@ -41,8 +42,12 @@
             ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid HSP =
             ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
+    public static final ParcelUuid HSP_AG =
+            ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid Handsfree =
             ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
+    public static final ParcelUuid Handsfree_AG =
+            ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid AvrcpController =
             ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid AvrcpTarget =
@@ -57,6 +62,8 @@
             ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid BNEP =
             ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
+    public static final ParcelUuid PBAP_PSE =
+            ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
 
     public static final ParcelUuid[] RESERVED_UUIDS = {
         AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
@@ -173,4 +180,16 @@
         return true;
     }
 
+    /**
+     * Extract the Service Identifier or the actual uuid from the Parcel Uuid.
+     * For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
+     * this function will return 110B
+     * @param parcelUuid
+     * @return the service identifier.
+     */
+    public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
+        UUID uuid = parcelUuid.getUuid();
+        long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
+        return (int)value;
+    }
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7ca6270..277dc2f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1610,6 +1610,14 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.nfc.NfcManager} for using NFC.
+     *
+     * @see #getSystemService
+     */
+    public static final String NFC_SERVICE = "nfc";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.net.sip.SipManager} for accessing the SIP related service.
      *
      * @see #getSystemService
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 84cb2fb..22befa8 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2849,6 +2849,54 @@
     }
 
     /**
+     * Create an intent to launch the main (root) activity of a task.  This
+     * is the Intent that is started when the application's is launched from
+     * Home.  For anything else that wants to launch an application in the
+     * same way, it is important that they use an Intent structured the same
+     * way, and can use this function to ensure this is the case.
+     *
+     * <p>The returned Intent has the given Activity component as its explicit
+     * component, {@link #ACTION_MAIN} as its action, and includes the
+     * category {@link #CATEGORY_LAUNCHER}.  This does <em>not</em> have
+     * {@link #FLAG_ACTIVITY_NEW_TASK} set, though typically you will want
+     * to do that through {@link #addFlags(int)} on the returned Intent.
+     *
+     * @param mainActivity The main activity component that this Intent will
+     * launch.
+     * @return Returns a newly created Intent that can be used to launch the
+     * activity as a main application entry.
+     *
+     * @see #setClass
+     * @see #setComponent
+     */
+    public static Intent makeMainActivity(ComponentName mainActivity) {
+        Intent intent = new Intent(ACTION_MAIN);
+        intent.setComponent(mainActivity);
+        intent.addCategory(CATEGORY_LAUNCHER);
+        return intent;
+    }
+
+    /**
+     * Make an Intent that can be used to re-launch an application's task
+     * in its base state.  This is like {@link #makeMainActivity(ComponentName)},
+     * but also sets the flags {@link #FLAG_ACTIVITY_NEW_TASK} and
+     * {@link #FLAG_ACTIVITY_CLEAR_TASK}.
+     *
+     * @param mainActivity The activity component that is the root of the
+     * task; this is the activity that has been published in the application's
+     * manifest as the main launcher icon.
+     *
+     * @return Returns a newly created Intent that can be used to relaunch the
+     * activity's task in its root state.
+     */
+    public static Intent makeRestartActivityTask(ComponentName mainActivity) {
+        Intent intent = makeMainActivity(mainActivity);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        return intent;
+    }
+
+    /**
      * Call {@link #parseUri} with 0 flags.
      * @deprecated Use {@link #parseUri} instead.
      */
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index dde198e..e07dbb8 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -735,14 +735,24 @@
 
         final Pair<Long, Long> previousSettings =
                 mSyncStorageEngine.getBackoff(op.account, op.authority);
-        long newDelayInMs;
-        if (previousSettings == null || previousSettings.second <= 0) {
+        long newDelayInMs = -1;
+        if (previousSettings != null) {
+            // don't increase backoff before current backoff is expired. This will happen for op's
+            // with ignoreBackoff set.
+            if (now < previousSettings.first) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "Still in backoff, do not increase it. "
+                        + "Remaining: " + ((previousSettings.first - now) / 1000) + " seconds.");
+                }
+                return;
+            }
+            // Subsequent delays are the double of the previous delay
+            newDelayInMs = previousSettings.second * 2;
+        }
+        if (newDelayInMs <= 0) {
             // The initial delay is the jitterized INITIAL_SYNC_RETRY_TIME_IN_MS
             newDelayInMs = jitterize(INITIAL_SYNC_RETRY_TIME_IN_MS,
                     (long)(INITIAL_SYNC_RETRY_TIME_IN_MS * 1.1));
-        } else {
-            // Subsequent delays are the double of the previous delay
-            newDelayInMs = previousSettings.second * 2;
         }
 
         // Cap the delay
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index ac7a95a..2c2e7d7 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -926,7 +926,7 @@
      *
      * @param packageName The name of the package to inspect.
      * 
-     * @return Returns either a fully-qualified Intent that can be used to
+     * @return Returns either an Intent that can be used to
      * launch the main activity in the package, or null if the package does
      * not contain such an activity.
      */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 54dbe37..9cfe2db 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -191,7 +191,7 @@
         pi.versionName = p.mVersionName;
         pi.sharedUserId = p.mSharedUserId;
         pi.sharedUserLabel = p.mSharedUserLabel;
-        pi.applicationInfo = p.applicationInfo;
+        pi.applicationInfo = generateApplicationInfo(p, flags);
         pi.installLocation = p.installLocation;
         pi.firstInstallTime = firstInstallTime;
         pi.lastUpdateTime = lastUpdateTime;
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index f607ee9..3e21e2d 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -72,8 +72,9 @@
      * @return true if the transaction was successful.
      */
     public boolean requestTime(String host, int timeout) {
+        DatagramSocket socket = null;
         try {
-            DatagramSocket socket = new DatagramSocket();
+            socket = new DatagramSocket();
             socket.setSoTimeout(timeout);
             InetAddress address = InetAddress.getByName(host);
             byte[] buffer = new byte[NTP_PACKET_SIZE];
@@ -96,7 +97,6 @@
             socket.receive(response);
             long responseTicks = SystemClock.elapsedRealtime();
             long responseTime = requestTime + (responseTicks - requestTicks);
-            socket.close();
 
             // extract the results
             long originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET);
@@ -123,6 +123,10 @@
         } catch (Exception e) {
             if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
             return false;
+        } finally {
+            if (socket != null) {
+                socket.close();
+            }
         }
 
         return true;
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index f5c79e7..0f96d6b 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -25,17 +25,18 @@
 {
     int close(int nativeHandle);
     int connect(int nativeHandle);
+    int reconnect(int nativeHandle);
     int[] getTechList(int nativeHandle);
     byte[] getUid(int nativeHandle);
     boolean isNdef(int nativeHandle);
     boolean isPresent(int nativeHandle);
-    byte[] transceive(int nativeHandle, in byte[] data);
+    byte[] transceive(int nativeHandle, in byte[] data, boolean raw);
 
     int getLastError(int nativeHandle);
 
-    NdefMessage read(int nativeHandle);
-    int write(int nativeHandle, in NdefMessage msg);
-    int makeReadOnly(int nativeHandle);
-    int getModeHint(int nativeHandle);
+    NdefMessage ndefRead(int nativeHandle);
+    int ndefWrite(int nativeHandle, in NdefMessage msg);
+    int ndefMakeReadOnly(int nativeHandle);
+    boolean ndefIsWritable(int nativeHandle);
     int formatNdef(int nativeHandle, in byte[] key);
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index a1c22bf..758c8a0 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -19,6 +19,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.ActivityThread;
+import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.os.IBinder;
@@ -29,11 +30,38 @@
 /**
  * Represents the device's local NFC adapter.
  * <p>
- * Use the static {@link #getDefaultAdapter} method to get the default NFC
- * Adapter for this Android device. Most Android devices will have only one NFC
- * Adapter, and {@link #getDefaultAdapter} returns the singleton object.
+ * Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC
+ * adapter for this Android device.
  */
 public final class NfcAdapter {
+    private static final String TAG = "NFC";
+
+    /**
+     * Intent to start an activity when a tag with NDEF payload is discovered.
+     * If the tag has and NDEF payload this intent is started before
+     * {@link #ACTION_TECHNOLOGY_DISCOVERED}.
+     *
+     * If any activities respond to this intent neither
+     * {@link #ACTION_TECHNOLOGY_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
+
+    /**
+     * Intent to started when a tag is discovered. The data URI is formated as
+     * {@code vnd.android.nfc://tag/} with the path having a directory entry for each technology
+     * in the {@link Tag#getTechnologyList()} is ascending order.
+     *
+     * This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
+     * {@link #ACTION_TAG_DISCOVERED}
+     *
+     * If any activities respond to this intent {@link #ACTION_TAG_DISCOVERED} will not be started.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_TECHNOLOGY_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
+
     /**
      * Intent to start an activity when a tag is discovered.
      */
@@ -161,30 +189,18 @@
      */
     private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
 
-    private static final String TAG = "NFC";
 
-    // Both guarded by NfcAdapter.class:
+    // Guarded by NfcAdapter.class
     private static boolean sIsInitialized = false;
-    private static NfcAdapter sAdapter;
 
-    // Final after construction, except for attemptDeadServiceRecovery()
-    // when NFC crashes.
-    // Not locked - we accept a best effort attempt when NFC crashes.
-    /*package*/ INfcAdapter mService;
+    // Final after first constructor, except for
+    // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
+    // recovery
+    private static INfcAdapter sService;
 
-    private NfcAdapter(INfcAdapter service) {
-        mService = service;
-    }
+    private final Context mContext;
 
     /**
-     * Returns the binder interface to the service.
-     * @hide
-     */
-    public INfcAdapter getService() {
-        return mService;
-    }
-    
-    /**
      * Helper to check if this device has FEATURE_NFC, but without using
      * a context.
      * Equivalent to
@@ -204,8 +220,27 @@
         }
     }
 
+    private static synchronized INfcAdapter setupService() {
+        if (!sIsInitialized) {
+            sIsInitialized = true;
+
+            /* is this device meant to have NFC */
+            if (!hasNfcFeature()) {
+                Log.v(TAG, "this device does not have NFC support");
+                return null;
+            }
+
+            sService = getServiceInterface();
+            if (sService == null) {
+                Log.e(TAG, "could not retrieve NFC service");
+                return null;
+            }
+        }
+        return sService;
+    }
+
     /** get handle to NFC service interface */
-    private static synchronized INfcAdapter getServiceInterface() {
+    private static INfcAdapter getServiceInterface() {
         /* get a handle to NFC service */
         IBinder b = ServiceManager.getService("nfc");
         if (b == null) {
@@ -215,34 +250,54 @@
     }
 
     /**
+     * Helper to get the default NFC Adapter.
+     * <p>
+     * Most Android devices will only have one NFC Adapter (NFC Controller).
+     * <p>
+     * This helper is the equivalent of:
+     * <pre>{@code
+     * NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
+     * NfcAdapter adapter = manager.getDefaultAdapter();
+     * }</pre>
+     * @param context the calling application's context
+     *
+     * @return the default NFC adapter, or null if no NFC adapter exists
+     */
+    public static NfcAdapter getDefaultAdapter(Context context) {
+        /* use getSystemService() instead of just instantiating to take
+         * advantage of the context's cached NfcManager & NfcAdapter */
+        NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
+        return manager.getDefaultAdapter();
+    }
+
+    /**
      * Get a handle to the default NFC Adapter on this Android device.
      * <p>
      * Most Android devices will only have one NFC Adapter (NFC Controller).
      *
      * @return the default NFC adapter, or null if no NFC adapter exists
+     * @deprecated use {@link #getDefaultAdapter(Context)}
      */
+    @Deprecated
     public static NfcAdapter getDefaultAdapter() {
-        synchronized (NfcAdapter.class) {
-            if (sIsInitialized) {
-                return sAdapter;
-            }
-            sIsInitialized = true;
+        Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " +
+                "NfcAdapter.getDefaultAdapter(Context) instead", new Exception());
+        return new NfcAdapter(null);
+    }
 
-            /* is this device meant to have NFC */
-            if (!hasNfcFeature()) {
-                Log.v(TAG, "this device does not have NFC support");
-                return null;
-            }
-
-            INfcAdapter service = getServiceInterface();
-            if (service == null) {
-                Log.e(TAG, "could not retrieve NFC service");
-                return null;
-            }
-
-            sAdapter = new NfcAdapter(service);
-            return sAdapter;
+    /*package*/ NfcAdapter(Context context) {
+        if (setupService() == null) {
+            throw new UnsupportedOperationException();
         }
+        mContext = context;
+    }
+
+    /**
+     * Returns the binder interface to the service.
+     * @hide
+     */
+    public INfcAdapter getService() {
+        return sService;
     }
 
     /**
@@ -256,9 +311,9 @@
             Log.e(TAG, "could not retrieve NFC service during service recovery");
             return;
         }
-        /* assigning to mService is not thread-safe, but this is best-effort code
+        /* assigning to sService is not thread-safe, but this is best-effort code
          * and on a well-behaved system should never happen */
-        mService = service;
+        sService = service;
         return;
     }
 
@@ -275,7 +330,7 @@
      */
     public boolean isEnabled() {
         try {
-            return mService.isEnabled();
+            return sService.isEnabled();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             return false;
@@ -292,7 +347,7 @@
      */
     public boolean enable() {
         try {
-            return mService.enable();
+            return sService.enable();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             return false;
@@ -311,7 +366,7 @@
      */
     public boolean disable() {
         try {
-            return mService.disable();
+            return sService.disable();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             return false;
@@ -338,7 +393,7 @@
      */
     public void setLocalNdefMessage(NdefMessage message) {
         try {
-            mService.localSet(message);
+            sService.localSet(message);
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
         }
@@ -353,7 +408,7 @@
      */
     public NdefMessage getLocalNdefMessage() {
         try {
-            return mService.localGet();
+            return sService.localGet();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             return null;
@@ -366,7 +421,7 @@
      */
     public NfcSecureElement createNfcSecureElementConnection() {
         try {
-            return new NfcSecureElement(mService.getNfcSecureElementInterface());
+            return new NfcSecureElement(sService.getNfcSecureElementInterface());
         } catch (RemoteException e) {
             Log.e(TAG, "createNfcSecureElementConnection failed", e);
             return null;
diff --git a/core/java/android/nfc/NfcManager.java b/core/java/android/nfc/NfcManager.java
new file mode 100644
index 0000000..5fa6483
--- /dev/null
+++ b/core/java/android/nfc/NfcManager.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.content.Context;
+
+/**
+ * High level manager used to obtain an instance of an {@link NfcAdapter}.
+ * <p>
+ * Use {@link android.content.Context#getSystemService(java.lang.String)}
+ * with {@link Context#NFC_SERVICE} to create an {@link NfcManager},
+ * then call {@link #getDefaultAdapter} to obtain the {@link NfcAdapter}.
+ * <p>
+ * Alternately, you can just call the static helper
+ * {@link NfcAdapter#getDefaultAdapter(android.content.Context)}.
+ *
+ * @see Context#getSystemService
+ * @see NfcAdapter#getDefaultAdapter(android.content.Context)
+ */
+public final class NfcManager {
+    private final NfcAdapter mAdapter;
+
+    /**
+     * @hide
+     */
+    public NfcManager(Context context) {
+        NfcAdapter adapter;
+        try {
+            adapter = new NfcAdapter(context);
+        } catch (UnsupportedOperationException e) {
+            adapter = null;
+        }
+        mAdapter = adapter;
+    }
+
+    /**
+     * Get the default NFC Adapter for this device.
+     *
+     * @return the default NFC Adapter
+     */
+    public NfcAdapter getDefaultAdapter() {
+        return mAdapter;
+    }
+}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 36de915..d042634 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -127,7 +127,7 @@
     /**
      * Returns the technology, or null if not present
      */
-    public TagTechnology getTechnology(int tech) {
+    public TagTechnology getTechnology(NfcAdapter adapter, int tech) {
         int pos = -1;
         for (int idx = 0; idx < mTechList.length; idx++) {
           if (mTechList[idx] == tech) {
@@ -140,7 +140,6 @@
         }
 
         Bundle extras = mTechExtras[pos];
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter();
         try {
             switch (tech) {
                 case TagTechnology.NFC_A: {
diff --git a/core/java/android/nfc/package.html b/core/java/android/nfc/package.html
index b054d1c..97bb29d 100644
--- a/core/java/android/nfc/package.html
+++ b/core/java/android/nfc/package.html
@@ -6,9 +6,13 @@
 <p>Here's a summary of the classes:</p>
 
 <dl>
+  <dt>{@link android.nfc.NfcManager}</dt>
+  <dd>This is the high level manager, used to obtain this device's {@link android.nfc.NfcAdapter}. You can
+acquire an instance using {@link android.content.Context#getSystemService}.</dd>
   <dt>{@link android.nfc.NfcAdapter}</dt>
   <dd>This represents the device's NFC adapter, which is your entry-point to performing NFC
-operations. You can acquire an instance with {@link android.nfc.NfcAdapter#getDefaultAdapter}.</dd>
+operations. You can acquire an instance with {@link android.nfc.NfcManager#getDefaultAdapter}, or
+{@link android.nfc.NfcAdapter#getDefaultAdapter(android.content.Context)}.</dd>
   <dt>{@link android.nfc.NdefMessage}</dt>
   <dd>Represents an NDEF data message, which is the standard format in which "records"
 carrying data are transmitted between devices and tags. Your application can receive these
diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java
index 6b281b9..a50c10b 100644
--- a/core/java/android/nfc/technology/BasicTagTechnology.java
+++ b/core/java/android/nfc/technology/BasicTagTechnology.java
@@ -162,7 +162,10 @@
     public void close() {
         mIsConnected = false;
         try {
-            mTagService.close(mTag.getServiceHandle());
+            /* Note that we don't want to physically disconnect the tag,
+             * but just reconnect to it to reset its state
+             */
+            mTagService.reconnect(mTag.getServiceHandle());
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
         }
@@ -181,9 +184,9 @@
      */
     public byte[] transceive(byte[] data) throws IOException {
         try {
-            byte[] response = mTagService.transceive(mTag.getServiceHandle(), data);
+            byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, true);
             if (response == null) {
-                throw new IOException("transcieve failed");
+                throw new IOException("transceive failed");
             }
             return response;
         } catch (RemoteException e) {
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
index ba3a425..defdcf2 100644
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -74,7 +74,7 @@
         super(adapter, tag, TagTechnology.MIFARE_CLASSIC);
 
         // Check if this could actually be a Mifare
-        NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A);
+        NfcA a = (NfcA) tag.getTechnology(adapter, TagTechnology.NFC_A);
         //short[] ATQA = getATQA(tag);
 
         mIsEmulated = false;
@@ -285,5 +285,30 @@
     public void writeSectorAccessControl(int sector, int access);
     public void increment(int block);
     public void decrement(int block);
+
 */
+    /**
+     * Send data to a tag and receive the response.
+     * <p>
+     * This method will block until the response is received. It can be canceled
+     * with {@link #close}.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    @Override
+    public byte[] transceive(byte[] data) throws IOException {
+        try {
+            byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
+            if (response == null) {
+                throw new IOException("transceive failed");
+            }
+            return response;
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            throw new IOException("NFC service died");
+        }
+    }
 }
diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java
index dd1dae9..58d2645 100644
--- a/core/java/android/nfc/technology/MifareUltralight.java
+++ b/core/java/android/nfc/technology/MifareUltralight.java
@@ -16,13 +16,13 @@
 
 package android.nfc.technology;
 
+import java.io.IOException;
+
 import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.os.Bundle;
 import android.os.RemoteException;
 
-import java.io.IOException;
-
 /**
  * Concrete class for TagTechnology.MIFARE_ULTRALIGHT
  *
@@ -39,7 +39,7 @@
     public static final int TYPE_ULTRALIGHT_C = 2;
     public static final int TYPE_UNKNOWN = 10;
 
-		private static final int NXP_MANUFACTURER_ID = 0x04;
+    private static final int NXP_MANUFACTURER_ID = 0x04;
 
     private int mType;
 
@@ -47,13 +47,13 @@
         super(adapter, tag, TagTechnology.MIFARE_ULTRALIGHT);
 
         // Check if this could actually be a Mifare
-        NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A);
+        NfcA a = (NfcA) tag.getTechnology(adapter, TagTechnology.NFC_A);
 
         mType = TYPE_UNKNOWN;
 
         if( a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID ) {
-					// could be UL or UL-C
-					mType = TYPE_ULTRALIGHT;
+            // could be UL or UL-C
+            mType = TYPE_ULTRALIGHT;
         }
     }
 
@@ -71,11 +71,36 @@
     }
 
     /**
+     * Send data to a tag and receive the response.
+     * <p>
+     * This method will block until the response is received. It can be canceled
+     * with {@link #close}.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    @Override
+    public byte[] transceive(byte[] data) throws IOException {
+        try {
+            byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
+            if (response == null) {
+                throw new IOException("transceive failed");
+            }
+            return response;
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            throw new IOException("NFC service died");
+        }
+    }
+
+    /**
      * @throws IOException
      */
-/*
+    /*
     public byte[] readOTP();
     public void writePage(int block, byte[] data);
     public void writeBlock(int block, byte[] data);
-*/
+     */
 }
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index c856646..7e194aa 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -38,11 +38,12 @@
  * permission.
  */
 public final class Ndef extends BasicTagTechnology {
-    public static final int NDEF_MODE_READ_ONCE = 1;
-    public static final int NDEF_MODE_READ_ONLY = 2;
-    public static final int NDEF_MODE_WRITE_ONCE = 3;
-    public static final int NDEF_MODE_WRITE_MANY = 4;
-    public static final int NDEF_MODE_UNKNOWN = 5;
+    /** @hide */
+    public static final int NDEF_MODE_READ_ONLY = 1;
+    /** @hide */
+    public static final int NDEF_MODE_READ_WRITE = 2;
+    /** @hide */
+    public static final int NDEF_MODE_UNKNOWN = 3;
 
     /** @hide */
     public static final String EXTRA_NDEF_MSG = "ndefmsg";
@@ -50,7 +51,12 @@
     /** @hide */
     public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength";
 
-    private final int maxNdefSize;
+    /** @hide */
+    public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate";
+
+    private final int mMaxNdefSize;
+    private final int mCardState;
+    private final NdefMessage mNdefMsg;
 
     /**
      * Internal constructor, to be used by NfcAdapter
@@ -59,37 +65,21 @@
     public Ndef(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
         super(adapter, tag, tech);
         if (extras != null) {
-            maxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
+            mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
+            mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
+            mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG);
         } else {
-            maxNdefSize = 0;  //TODO: throw exception
+            throw new NullPointerException("NDEF tech extras are null.");
         }
+
     }
 
     /**
      * Get the primary NDEF message on this tag. This data is read at discovery time
      * and does not require a connection.
      */
-    public NdefMessage getNdefMessage() throws IOException, FormatException {
-        try {
-            int serviceHandle = mTag.getServiceHandle();
-            NdefMessage msg = mTagService.read(serviceHandle);
-            if (msg == null) {
-                int errorCode = mTagService.getLastError(serviceHandle);
-                switch (errorCode) {
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new FormatException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-            return msg;
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return null;
-        }
+    public NdefMessage getCachedNdefMessage() {
+        return mNdefMsg;
     }
 
     /**
@@ -104,45 +94,57 @@
     /**
      * Get maximum NDEF message size in bytes
      */
-    public int getSize() {
-        return maxNdefSize;
+    public int getMaxSize() {
+        return mMaxNdefSize;
     }
 
     /**
-     * Read/Write mode hint.
-     * Provides a hint if further reads or writes are likely to succeed.
+     * Provides a hint on whether writes are likely to succeed.
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     * @return one of NDEF_MODE
-     * @throws IOException if the target is lost or connection closed
+     * @return true if write is likely to succeed
      */
-    public int getModeHint() throws IOException {
-        try {
-            int result = mTagService.getModeHint(mTag.getServiceHandle());
-            if (ErrorCodes.isError(result)) {
-                switch (result) {
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-            return result;
-
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return NDEF_MODE_UNKNOWN;
-        }
+    public boolean isWritable() {
+        return (mCardState == NDEF_MODE_READ_WRITE);
     }
 
     // Methods that require connect()
     /**
+     * Get the primary NDEF message on this tag. This data is read actively
+     * and requires a connection.
+     */
+    public NdefMessage getNdefMessage() throws IOException, FormatException {
+        try {
+            int serviceHandle = mTag.getServiceHandle();
+            if (mTagService.isNdef(serviceHandle)) {
+                NdefMessage msg = mTagService.ndefRead(serviceHandle);
+                if (msg == null) {
+                    int errorCode = mTagService.getLastError(serviceHandle);
+                    switch (errorCode) {
+                        case ErrorCodes.ERROR_IO:
+                            throw new IOException();
+                        case ErrorCodes.ERROR_INVALID_PARAM:
+                            throw new FormatException();
+                        default:
+                            // Should not happen
+                            throw new IOException();
+                    }
+                }
+                return msg;
+            } else {
+                return null;
+            }
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            return null;
+        }
+    }
+    /**
      * Overwrite the primary NDEF message
      * @throws IOException
      */
     public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
         try {
-            int errorCode = mTagService.write(mTag.getServiceHandle(), msg);
+            int errorCode = mTagService.ndefWrite(mTag.getServiceHandle(), msg);
             switch (errorCode) {
                 case ErrorCodes.SUCCESS:
                     break;
@@ -179,7 +181,7 @@
      */
     public boolean makeReadonly() throws IOException {
         try {
-            int errorCode = mTagService.makeReadOnly(mTag.getServiceHandle());
+            int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
             switch (errorCode) {
                 case ErrorCodes.SUCCESS:
                     return true;
@@ -205,4 +207,9 @@
     public void makeLowLevelReadonly() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public byte[] transceive(byte[] data) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
index 3ed37a5..bd21e58 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -73,20 +73,30 @@
                     // Should not happen
                     throw new IOException();
             }
-            errorCode = mTagService.write(serviceHandle, firstMessage);
-            switch (errorCode) {
-                case ErrorCodes.SUCCESS:
-                    break;
-                case ErrorCodes.ERROR_IO:
-                    throw new IOException();
-                case ErrorCodes.ERROR_INVALID_PARAM:
-                    throw new FormatException();
-                default:
-                    // Should not happen
-                    throw new IOException();
+            // Now check and see if the format worked
+            if (mTagService.isNdef(serviceHandle)) {
+                errorCode = mTagService.ndefWrite(serviceHandle, firstMessage);
+                switch (errorCode) {
+                    case ErrorCodes.SUCCESS:
+                        break;
+                    case ErrorCodes.ERROR_IO:
+                        throw new IOException();
+                    case ErrorCodes.ERROR_INVALID_PARAM:
+                        throw new FormatException();
+                    default:
+                        // Should not happen
+                        throw new IOException();
+                }
+            } else {
+                throw new IOException();
             }
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
         }
     }
+
+    @Override
+    public byte[] transceive(byte[] data) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
index 4704f2b..bef1cc4 100644
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -39,42 +39,32 @@
     /**
      * This object is an instance of {@link NfcF}
      */
-    public static final int NFC_F = 11;
+    public static final int NFC_F = 4;
 
     /**
      * This object is an instance of {@link NfcV}
      */
-    public static final int NFC_V = 21;
+    public static final int NFC_V = 5;
 
     /**
      * This object is an instance of {@link Ndef}
      */
-    public static final int NDEF = 101;
+    public static final int NDEF = 6;
 
     /**
      * This object is an instance of {@link NdefFormatable}
      */
-    public static final int NDEF_FORMATABLE = 110;
+    public static final int NDEF_FORMATABLE = 7;
 
     /**
      * This object is an instance of {@link MifareClassic}
      */
-    public static final int MIFARE_CLASSIC = 200;
-
-    /**
-     * A Mifare Classic tag with NDEF data
-     */
-    public static final int MIFARE_CLASSIC_NDEF = 201;
+    public static final int MIFARE_CLASSIC = 8;
 
     /**
      * This object is an instance of {@link MifareUltralight}
      */
-    public static final int MIFARE_ULTRALIGHT = 202;
-
-    /**
-     * A Mifare DESFire tag
-     */
-    public static final int MIFARE_DESFIRE = 203;
+    public static final int MIFARE_ULTRALIGHT = 9;
 
     /**
      * Returns the technology type for this tag connection.
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 44f1757..7dd5e31 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -17,9 +17,12 @@
 package android.os;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Formatter;
+import java.util.List;
 import java.util.Map;
 
+import android.content.pm.ApplicationInfo;
 import android.util.Log;
 import android.util.Printer;
 import android.util.SparseArray;
@@ -120,6 +123,7 @@
     private static final long BYTES_PER_GB = 1073741824; //1024^3
     
 
+    private static final String UID_DATA = "uid";
     private static final String APK_DATA = "apk";
     private static final String PROCESS_DATA = "pr";
     private static final String SENSOR_DATA = "sr";
@@ -1463,7 +1467,7 @@
 
         for (int iu=0; iu<NU; iu++) {
             final int uid = uidStats.keyAt(iu);
-            if (reqUid >= 0 && uid != reqUid) {
+            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
                 continue;
             }
             
@@ -1880,7 +1884,7 @@
     }
     
     @SuppressWarnings("unused")
-    public void dumpCheckinLocked(PrintWriter pw, String[] args) {
+    public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
         boolean isUnpluggedOnly = false;
         
         for (String arg : args) {
@@ -1890,6 +1894,33 @@
             }
         }
         
+        if (apps != null) {
+            SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
+            for (int i=0; i<apps.size(); i++) {
+                ApplicationInfo ai = apps.get(i);
+                ArrayList<String> pkgs = uids.get(ai.uid);
+                if (pkgs == null) {
+                    pkgs = new ArrayList<String>();
+                    uids.put(ai.uid, pkgs);
+                }
+                pkgs.add(ai.packageName);
+            }
+            SparseArray<? extends Uid> uidStats = getUidStats();
+            final int NU = uidStats.size();
+            String[] lineArgs = new String[2];
+            for (int i=0; i<NU; i++) {
+                int uid = uidStats.keyAt(i);
+                ArrayList<String> pkgs = uids.get(uid);
+                if (pkgs != null) {
+                    for (int j=0; j<pkgs.size(); j++) {
+                        lineArgs[0] = Integer.toString(uid);
+                        lineArgs[1] = pkgs.get(j);
+                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
+                                (Object[])lineArgs);
+                    }
+                }
+            }
+        }
         if (isUnpluggedOnly) {
             dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
         }
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index 47a7696..e1c1678 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -58,6 +58,30 @@
     private static final int HAS_BYTE_ARRAY = 8;
 
     /**
+     * Broadcast Action: This is broadcast when a new entry is added in the dropbox.
+     * You must hold the {@link android.Manifest.permission#READ_LOGS} permission
+     * in order to receive this broadcast.
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     */
+    public static final String ACTION_DROPBOX_ENTRY_ADDED =
+        "android.intent.action.DROPBOX_ENTRY_ADDED";
+
+    /**
+     * Extra for {@link android.os.DropBoxManager#ACTION_DROPBOX_ENTRY_ADDED}:
+     * string containing the dropbox tag.
+     */
+    public static final String EXTRA_TAG = "tag";
+
+    /**
+     * Extra for {@link android.os.DropBoxManager#ACTION_DROPBOX_ENTRY_ADDED}:
+     * long integer value containing time (in milliseconds since January 1, 1970 00:00:00 UTC)
+     * when the entry was created.
+     */
+    public static final String EXTRA_TIME = "time";
+
+    /**
      * A single entry retrieved from the drop box.
      * This may include a reference to a stream, so you must call
      * {@link #close()} when you are done using it.
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 156da47..efb8415 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -18,8 +18,6 @@
 
 import android.util.Log;
 
-import com.android.internal.os.RuntimeInit;
-
 /**
  * This class gives you control of the power state of the device.  
  * 
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ba97dcf..b00b9c9 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -274,7 +274,7 @@
         }
 
         /**
-         * Creates ThreadPolicy instances.  Methods whose names start
+         * Creates {@link ThreadPolicy} instances.  Methods whose names start
          * with {@code detect} specify what problems we should look
          * for.  Methods whose names start with {@code penalty} specify what
          * we should do when we detect a problem.
@@ -285,11 +285,11 @@
          *
          * <p>For example, detect everything and log anything that's found:
          * <pre>
-         * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
+         * StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
          *     .detectAll()
          *     .penaltyLog()
          *     .build();
-         * StrictMode.setVmPolicy(policy);
+         * StrictMode.setThreadPolicy(policy);
          * </pre>
          */
         public static final class Builder {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1e80da7..873674d2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2410,6 +2410,12 @@
                 "input_methods_subtype_history";
 
         /**
+         * Setting to record the visibility of input method selector
+         */
+        public static final String INPUT_METHOD_SELECTOR_VISIBILITY =
+                "input_method_selector_visibility";
+
+        /**
          * Whether the device has been provisioned (0 = false, 1 = true)
          */
         public static final String DEVICE_PROVISIONED = "device_provisioned";
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 4f56281..529e6b8 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -293,7 +293,7 @@
                 intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
             }
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("Devices")) {
+        } else if (name.equals("Devices") || name.equals("UUIDs")) {
             String value = null;
             int len = Integer.valueOf(propValues[1]);
             if (len > 0) {
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 398b5ae..1f19f9e 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -97,6 +97,8 @@
     private boolean mRestart = false;  // need to call enable() after disable()
     private boolean mIsDiscovering;
     private boolean mTetheringOn;
+    private int[] mAdapterSdpUuids;
+    private int[] mAdapterSdpHandles;
 
     private BluetoothAdapter mAdapter;  // constant after init()
     private final BondState mBondState = new BondState();  // local cache of bondings
@@ -112,11 +114,10 @@
     private static final String SHARED_PREFERENCE_DOCK_ADDRESS = "dock_bluetooth_address";
     private static final String SHARED_PREFERENCES_NAME = "bluetooth_service_settings";
 
-    private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
-    private static final int MESSAGE_FINISH_DISABLE = 2;
-    private static final int MESSAGE_UUID_INTENT = 3;
-    private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 4;
-    private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 5;
+    private static final int MESSAGE_FINISH_DISABLE = 1;
+    private static final int MESSAGE_UUID_INTENT = 2;
+    private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 3;
+    private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 4;
 
     // The time (in millisecs) to delay the pairing attempt after the first
     // auto pairing attempt fails. We use an exponential delay with
@@ -378,8 +379,10 @@
         if (mEnableThread != null && mEnableThread.isAlive()) {
             return false;
         }
+
         setBluetoothState(BluetoothAdapter.STATE_TURNING_OFF);
-        mHandler.removeMessages(MESSAGE_REGISTER_SDP_RECORDS);
+
+        if (mAdapterSdpHandles != null) removeReservedServiceRecordsNative(mAdapterSdpHandles);
         setBluetoothTetheringNative(false, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
 
         // Allow 3 seconds for profiles to gracefully disconnect
@@ -417,6 +420,11 @@
                                     BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
         }
 
+        // Stop the profile state machine for bonded devices.
+        for (String address : mBondState.listInState(BluetoothDevice.BOND_BONDED)) {
+            removeProfileState(address);
+        }
+
         // update mode
         Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
         intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
@@ -516,43 +524,6 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case MESSAGE_REGISTER_SDP_RECORDS:
-                if (!isEnabledInternal()) {
-                    return;
-                }
-                // SystemService.start() forks sdptool to register service
-                // records. It can fail to register some records if it is
-                // forked multiple times in a row, probably because there is
-                // some race in sdptool or bluez when operated in parallel.
-                // As a workaround, delay 500ms between each fork of sdptool.
-                // TODO: Don't fork sdptool in order to register service
-                // records, use a DBUS call instead.
-                switch (msg.arg1) {
-                case 1:
-                    Log.d(TAG, "Registering hfag record");
-                    SystemService.start("hfag");
-                    mHandler.sendMessageDelayed(
-                            mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 2, -1), 500);
-                    break;
-                case 2:
-                    Log.d(TAG, "Registering hsag record");
-                    SystemService.start("hsag");
-                    mHandler.sendMessageDelayed(
-                            mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 3, -1), 500);
-                    break;
-                case 3:
-                    Log.d(TAG, "Registering pbap record");
-                    SystemService.start("pbap");
-                    mHandler.sendMessageDelayed(
-                        mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 500);
-
-                    break;
-                case 4:
-                    Log.d(TAG, "Registering opush record");
-                    SystemService.start("opush");
-                    break;
-                }
-                break;
             case MESSAGE_FINISH_DISABLE:
                 finishDisable(msg.arg1 != 0);
                 break;
@@ -625,24 +596,41 @@
                 if (mSaveSetting) {
                     persistBluetoothOnSetting(true);
                 }
+                //Register SDP records.
+                if (mContext.getResources().
+                        getBoolean(com.android.internal.R.bool.config_voice_capable)) {
+                     int[] uuids = {
+                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                            BluetoothUuid.Handsfree_AG),
+                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                            BluetoothUuid.HSP_AG),
+                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                             BluetoothUuid.PBAP_PSE),
+                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                             BluetoothUuid.ObexObjectPush),
+                        };
+                     mAdapterSdpUuids = uuids;
+
+                } else {
+                     int[] uuids = {
+                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                             BluetoothUuid.HSP_AG),
+                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                             BluetoothUuid.PBAP_PSE),
+                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
+                             BluetoothUuid.ObexObjectPush),
+                         };
+                      mAdapterSdpUuids = uuids;
+                }
+
+                mAdapterSdpHandles = addReservedServiceRecordsNative(mAdapterSdpUuids);
+                setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
+
                 mIsDiscovering = false;
                 mBondState.readAutoPairingData();
                 mBondState.loadBondState();
                 initProfileState();
 
-                //Register SDP records.
-                if (mContext.getResources().
-                        getBoolean(com.android.internal.R.bool.config_voice_capable)) {
-                    mHandler.sendMessageDelayed(
-                        mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
-                } else {
-                    // Register only OPP.
-                    mHandler.sendMessageDelayed(
-                        mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 3000);
-                }
-                setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
-
-
                 // Log bluetooth on to battery stats.
                 long ident = Binder.clearCallingIdentity();
                 try {
@@ -2731,10 +2719,9 @@
         for (String path : bonds) {
             String address = getAddressFromObjectPath(path);
             BluetoothDeviceProfileState state = addProfileState(address);
-            // Allow 8 secs for SDP records to get registered.
             Message msg = new Message();
             msg.what = BluetoothDeviceProfileState.AUTO_CONNECT_PROFILES;
-            state.sendMessageDelayed(msg, 8000);
+            state.sendMessage(msg);
         }
     }
 
@@ -2908,4 +2895,7 @@
     private native boolean setBluetoothTetheringNative(boolean value, String nap, String bridge);
     private native boolean connectPanDeviceNative(String path, String srcRole, String dstRole);
     private native boolean disconnectPanDeviceNative(String path);
+
+    private native int[] addReservedServiceRecordsNative(int[] uuuids);
+    private native boolean removeReservedServiceRecordsNative(int[] handles);
 }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 5bb8c50..63490ee 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -478,35 +478,35 @@
                     startTime = SystemClock.elapsedRealtime();
                 }
 
-                checkCurrent();
-
-                onPreDraw();
-
-                Canvas canvas = mCanvas;
-                int saveCount = canvas.save();
-                callbacks.onHardwarePreDraw(canvas);
-
-                try {
-                    view.draw(canvas);
-                } finally {
-                    callbacks.onHardwarePostDraw(canvas);
-                    canvas.restoreToCount(saveCount);
+                if (checkCurrent()) {
+                    onPreDraw();
+    
+                    Canvas canvas = mCanvas;
+                    int saveCount = canvas.save();
+                    callbacks.onHardwarePreDraw(canvas);
+    
+                    try {
+                        view.draw(canvas);
+                    } finally {
+                        callbacks.onHardwarePostDraw(canvas);
+                        canvas.restoreToCount(saveCount);
+                    }
+    
+                    onPostDraw();
+    
+                    if (ViewDebug.DEBUG_PROFILE_DRAWING) {
+                        EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
+                    }
+    
+                    attachInfo.mIgnoreDirtyState = false;
+    
+                    sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
+                    checkEglErrors();
                 }
-
-                onPostDraw();
-
-                if (ViewDebug.DEBUG_PROFILE_DRAWING) {
-                    EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
-                }
-
-                attachInfo.mIgnoreDirtyState = false;
-
-                sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-                checkEglErrors();
             }
         }
 
-        private void checkCurrent() {
+        private boolean checkCurrent() {
             // TODO: Don't check the current context when we have one per UI thread
             // TODO: Use a threadlocal flag to know whether the surface has changed
             if (sEgl.eglGetCurrentContext() != sEglContext ||
@@ -515,8 +515,10 @@
                     fallback(true);
                     Log.e(LOG_TAG, "eglMakeCurrent failed " +
                             getEGLErrorString(sEgl.eglGetError()));
+                    return false;
                 }
             }
+            return true;
         }
 
         static abstract class EglConfigChooser {
@@ -649,6 +651,11 @@
         GLES20Canvas createCanvas() {
             return mGlCanvas = new GLES20Canvas(mTranslucent);
         }
+        
+        @Override
+        boolean canDraw() {
+            return super.canDraw() && mGlCanvas != null;
+        }                
 
         @Override
         void onPreDraw() {
@@ -662,9 +669,12 @@
 
         @Override
         void destroy(boolean full) {
-            super.destroy(full);
-            if (full && mGlCanvas != null) {
-                mGlCanvas = null;
+            try {
+                super.destroy(full);
+            } finally {
+                if (full && mGlCanvas != null) {
+                    mGlCanvas = null;
+                }
             }
         }
 
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 2c8ca8b..8bdc1f8 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -186,5 +186,5 @@
 	/**
 	 * Create a screenshot of the applications currently displayed.
 	 */
-	Bitmap screenshotApplications(int maxWidth, int maxHeight);
+	Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight);
 }
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 5c4abd5..7ca5a19 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -208,7 +208,7 @@
      * @return The associated character or combining accent, or 0 if none.
      */
     public int get(int keyCode, int metaState) {
-        metaState = applyLockedModifiers(metaState);
+        metaState = KeyEvent.normalizeMetaState(metaState);
         char ch = nativeGetCharacter(mPtr, keyCode, metaState);
 
         int map = COMBINING.get(ch);
@@ -243,7 +243,7 @@
             throw new IllegalArgumentException("fallbackAction must not be null");
         }
 
-        metaState = applyLockedModifiers(metaState);
+        metaState = KeyEvent.normalizeMetaState(metaState);
         return nativeGetFallbackAction(mPtr, keyCode, metaState, outFallbackAction);
     }
 
@@ -303,7 +303,7 @@
             throw new IllegalArgumentException("chars must not be null.");
         }
 
-        metaState = applyLockedModifiers(metaState);
+        metaState = KeyEvent.normalizeMetaState(metaState);
         return nativeGetMatch(mPtr, keyCode, chars, metaState);
     }
 
@@ -536,16 +536,6 @@
         return ret;
     }
 
-    private static int applyLockedModifiers(int metaState) {
-        if ((metaState & MetaKeyKeyListener.META_CAP_LOCKED) != 0) {
-            metaState |= KeyEvent.META_CAPS_LOCK_ON;
-        }
-        if ((metaState & MetaKeyKeyListener.META_ALT_LOCKED) != 0) {
-            metaState |= KeyEvent.META_ALT_ON;
-        }
-        return metaState;
-    }
-
     /**
      * Maps Unicode combining diacritical to display-form dead key
      * (display character shifted left 16 bits).
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 43b77e6..97d7ad5 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -20,6 +20,7 @@
 import android.os.Parcelable;
 import android.text.method.MetaKeyKeyListener;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseIntArray;
 import android.view.KeyCharacterMap;
 import android.view.KeyCharacterMap.KeyData;
@@ -351,7 +352,7 @@
     public static final int KEYCODE_CTRL_LEFT       = 113;
     /** Key code constant: Right Control modifier key. */
     public static final int KEYCODE_CTRL_RIGHT      = 114;
-    /** Key code constant: Caps Lock modifier key. */
+    /** Key code constant: Caps Lock key. */
     public static final int KEYCODE_CAPS_LOCK       = 115;
     /** Key code constant: Scroll Lock key. */
     public static final int KEYCODE_SCROLL_LOCK     = 116;
@@ -415,9 +416,9 @@
     public static final int KEYCODE_F11             = 141;
     /** Key code constant: F12 key. */
     public static final int KEYCODE_F12             = 142;
-    /** Key code constant: Num Lock modifier key.
+    /** Key code constant: Num Lock key.
      * This is the Num Lock key; it is different from {@link #KEYCODE_NUM}.
-     * This key generally modifies the behavior of other keys on the numeric keypad. */
+     * This key alters the behavior of other keys on the numeric keypad. */
     public static final int KEYCODE_NUM_LOCK        = 143;
     /** Key code constant: Numeric keypad '0' key. */
     public static final int KEYCODE_NUMPAD_0        = 144;
@@ -1621,15 +1622,66 @@
         return mFlags;
     }
 
+    // Mask of all modifier key meta states.  Specifically excludes locked keys like caps lock.
+    private static final int META_MODIFIER_MASK =
+            META_SHIFT_ON | META_SHIFT_LEFT_ON | META_SHIFT_RIGHT_ON
+            | META_ALT_ON | META_ALT_LEFT_ON | META_ALT_RIGHT_ON
+            | META_CTRL_ON | META_CTRL_LEFT_ON | META_CTRL_RIGHT_ON
+            | META_META_ON | META_META_LEFT_ON | META_META_RIGHT_ON
+            | META_SYM_ON | META_FUNCTION_ON;
+
+    // Mask of all lock key meta states.
+    private static final int META_LOCK_MASK =
+            META_CAPS_LOCK_ON | META_NUM_LOCK_ON | META_SCROLL_LOCK_ON;
+
+    // Mask of all valid meta states.
+    private static final int META_ALL_MASK = META_MODIFIER_MASK | META_LOCK_MASK;
+
+    // Mask of all synthetic meta states that are reserved for API compatibility with
+    // historical uses in MetaKeyKeyListener.
+    private static final int META_SYNTHETIC_MASK =
+            META_CAP_LOCKED | META_ALT_LOCKED | META_SYM_LOCKED | META_SELECTING;
+
+    // Mask of all meta states that are not valid use in specifying a modifier key.
+    // These bits are known to be used for purposes other than specifying modifiers.
+    private static final int META_INVALID_MODIFIER_MASK =
+            META_LOCK_MASK | META_SYNTHETIC_MASK;
+
+    /**
+     * Gets a mask that includes all valid modifier key meta state bits.
+     * <p>
+     * For the purposes of this function, {@link #KEYCODE_CAPS_LOCK},
+     * {@link #KEYCODE_SCROLL_LOCK}, and {@link #KEYCODE_NUM_LOCK} are
+     * not considered modifier keys.  Consequently, the mask specifically excludes
+     * {@link #META_CAPS_LOCK_ON}, {@link #META_SCROLL_LOCK_ON} and {@link #META_NUM_LOCK_ON}.
+     * </p>
+     *
+     * @return The modifier meta state mask which is a combination of
+     * {@link #META_SHIFT_ON}, {@link #META_SHIFT_LEFT_ON}, {@link #META_SHIFT_RIGHT_ON},
+     * {@link #META_ALT_ON}, {@link #META_ALT_LEFT_ON}, {@link #META_ALT_RIGHT_ON},
+     * {@link #META_CTRL_ON}, {@link #META_CTRL_LEFT_ON}, {@link #META_CTRL_RIGHT_ON},
+     * {@link #META_META_ON}, {@link #META_META_LEFT_ON}, {@link #META_META_RIGHT_ON},
+     * {@link #META_SYM_ON}, {@link #META_FUNCTION_ON}.
+     */
+    public static int getModifierMetaStateMask() {
+        return META_MODIFIER_MASK;
+    }
+
     /**
      * Returns true if this key code is a modifier key.
+     * <p>
+     * For the purposes of this function, {@link #KEYCODE_CAPS_LOCK},
+     * {@link #KEYCODE_SCROLL_LOCK}, and {@link #KEYCODE_NUM_LOCK} are
+     * not considered modifier keys.  Consequently, this function return false
+     * for those keys.
+     * </p>
      *
-     * @return whether the provided keyCode is one of
+     * @return True if the key code is one of
      * {@link #KEYCODE_SHIFT_LEFT} {@link #KEYCODE_SHIFT_RIGHT},
      * {@link #KEYCODE_ALT_LEFT}, {@link #KEYCODE_ALT_RIGHT},
-     * {@link #KEYCODE_SYM}, {@link #KEYCODE_NUM}, {@link #KEYCODE_FUNCTION},
      * {@link #KEYCODE_CTRL_LEFT}, {@link #KEYCODE_CTRL_RIGHT},
-     * {@link #KEYCODE_META_LEFT}, or {@link #KEYCODE_META_RIGHT}.
+     * {@link #KEYCODE_META_LEFT}, or {@link #KEYCODE_META_RIGHT},
+     * {@link #KEYCODE_SYM}, {@link #KEYCODE_NUM}, {@link #KEYCODE_FUNCTION}.
      */
     public static boolean isModifierKey(int keyCode) {
         switch (keyCode) {
@@ -1637,13 +1689,13 @@
             case KEYCODE_SHIFT_RIGHT:
             case KEYCODE_ALT_LEFT:
             case KEYCODE_ALT_RIGHT:
-            case KEYCODE_SYM:
-            case KEYCODE_NUM:
-            case KEYCODE_FUNCTION:
             case KEYCODE_CTRL_LEFT:
             case KEYCODE_CTRL_RIGHT:
             case KEYCODE_META_LEFT:
             case KEYCODE_META_RIGHT:
+            case KEYCODE_SYM:
+            case KEYCODE_NUM:
+            case KEYCODE_FUNCTION:
                 return true;
             default:
                 return false;
@@ -1651,6 +1703,195 @@
     }
 
     /**
+     * Normalizes the specified meta state.
+     * <p>
+     * The meta state is normalized such that if either the left or right modifier meta state
+     * bits are set then the result will also include the universal bit for that modifier.
+     * </p><p>
+     * If the specified meta state contains {@link #META_ALT_LEFT_ON} then
+     * the result will also contain {@link #META_ALT_ON} in addition to {@link #META_ALT_LEFT_ON}
+     * and the other bits that were specified in the input.  The same is process is
+     * performed for shift, control and meta.
+     * </p><p>
+     * If the specified meta state contains synthetic meta states defined by
+     * {@link MetaKeyKeyListener}, then those states are translated here and the original
+     * synthetic meta states are removed from the result.
+     * {@link MetaKeyKeyListener#META_CAP_LOCKED} is translated to {@link #META_CAPS_LOCK_ON}.
+     * {@link MetaKeyKeyListener#META_ALT_LOCKED} is translated to {@link #META_ALT_ON}.
+     * {@link MetaKeyKeyListener#META_SYM_LOCKED} is translated to {@link #META_SYM_ON}.
+     * </p><p>
+     * Undefined meta state bits are removed.
+     * </p>
+     *
+     * @param metaState The meta state.
+     * @return The normalized meta state.
+     */
+    public static int normalizeMetaState(int metaState) {
+        if ((metaState & (META_SHIFT_LEFT_ON | META_SHIFT_RIGHT_ON)) != 0) {
+            metaState |= META_SHIFT_ON;
+        }
+        if ((metaState & (META_ALT_LEFT_ON | META_ALT_RIGHT_ON)) != 0) {
+            metaState |= META_ALT_ON;
+        }
+        if ((metaState & (META_CTRL_LEFT_ON | META_CTRL_RIGHT_ON)) != 0) {
+            metaState |= META_CTRL_ON;
+        }
+        if ((metaState & (META_META_LEFT_ON | META_META_RIGHT_ON)) != 0) {
+            metaState |= META_META_ON;
+        }
+        if ((metaState & MetaKeyKeyListener.META_CAP_LOCKED) != 0) {
+            metaState |= META_CAPS_LOCK_ON;
+        }
+        if ((metaState & MetaKeyKeyListener.META_ALT_LOCKED) != 0) {
+            metaState |= META_ALT_ON;
+        }
+        if ((metaState & MetaKeyKeyListener.META_SYM_LOCKED) != 0) {
+            metaState |= META_SYM_ON;
+        }
+        return metaState & META_ALL_MASK;
+    }
+
+    /**
+     * Returns true if no modifiers keys are pressed according to the specified meta state.
+     * <p>
+     * For the purposes of this function, {@link #KEYCODE_CAPS_LOCK},
+     * {@link #KEYCODE_SCROLL_LOCK}, and {@link #KEYCODE_NUM_LOCK} are
+     * not considered modifier keys.  Consequently, this function ignores
+     * {@link #META_CAPS_LOCK_ON}, {@link #META_SCROLL_LOCK_ON} and {@link #META_NUM_LOCK_ON}.
+     * </p><p>
+     * The meta state is normalized prior to comparison using {@link #normalizeMetaState(int)}.
+     * </p>
+     *
+     * @param metaState The meta state to consider.
+     * @return True if no modifier keys are pressed.
+     * @see #hasNoModifiers()
+     */
+    public static boolean metaStateHasNoModifiers(int metaState) {
+        return (normalizeMetaState(metaState) & META_MODIFIER_MASK) == 0;
+    }
+
+    /**
+     * Returns true if only the specified modifier keys are pressed according to
+     * the specified meta state.  Returns false if a different combination of modifier
+     * keys are pressed.
+     * <p>
+     * For the purposes of this function, {@link #KEYCODE_CAPS_LOCK},
+     * {@link #KEYCODE_SCROLL_LOCK}, and {@link #KEYCODE_NUM_LOCK} are
+     * not considered modifier keys.  Consequently, this function ignores
+     * {@link #META_CAPS_LOCK_ON}, {@link #META_SCROLL_LOCK_ON} and {@link #META_NUM_LOCK_ON}.
+     * </p><p>
+     * If the specified modifier mask includes directional modifiers, such as
+     * {@link #META_SHIFT_LEFT_ON}, then this method ensures that the
+     * modifier is pressed on that side.
+     * If the specified modifier mask includes non-directional modifiers, such as
+     * {@link #META_SHIFT_ON}, then this method ensures that the modifier
+     * is pressed on either side.
+     * If the specified modifier mask includes both directional and non-directional modifiers
+     * for the same type of key, such as {@link #META_SHIFT_ON} and {@link #META_SHIFT_LEFT_ON},
+     * then this method throws an illegal argument exception.
+     * </p>
+     *
+     * @param metaState The meta state to consider.
+     * @param modifiers The meta state of the modifier keys to check.  May be a combination
+     * of modifier meta states as defined by {@link #getModifierMetaStateMask()}.  May be 0 to
+     * ensure that no modifier keys are pressed.
+     * @return True if only the specified modifier keys are pressed.
+     * @throws IllegalArgumentException if the modifiers parameter contains invalid modifiers
+     * @see #hasModifiers
+     */
+    public static boolean metaStateHasModifiers(int metaState, int modifiers) {
+        // Note: For forward compatibility, we allow the parameter to contain meta states
+        //       that we do not recognize but we explicitly disallow meta states that
+        //       are not valid modifiers.
+        if ((modifiers & META_INVALID_MODIFIER_MASK) != 0) {
+            throw new IllegalArgumentException("modifiers must not contain "
+                    + "META_CAPS_LOCK_ON, META_NUM_LOCK_ON, META_SCROLL_LOCK_ON, "
+                    + "META_CAP_LOCKED, META_ALT_LOCKED, META_SYM_LOCKED, "
+                    + "or META_SELECTING");
+        }
+
+        metaState = normalizeMetaState(metaState) & META_MODIFIER_MASK;
+        metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
+                META_SHIFT_ON, META_SHIFT_LEFT_ON, META_SHIFT_RIGHT_ON);
+        metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
+                META_ALT_ON, META_ALT_LEFT_ON, META_ALT_RIGHT_ON);
+        metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
+                META_CTRL_ON, META_CTRL_LEFT_ON, META_CTRL_RIGHT_ON);
+        metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
+                META_META_ON, META_META_LEFT_ON, META_META_RIGHT_ON);
+        return metaState == modifiers;
+    }
+
+    private static int metaStateFilterDirectionalModifiers(int metaState,
+            int modifiers, int basic, int left, int right) {
+        final boolean wantBasic = (modifiers & basic) != 0;
+        final int directional = left | right;
+        final boolean wantLeftOrRight = (modifiers & directional) != 0;
+
+        if (wantBasic) {
+            if (wantLeftOrRight) {
+                throw new IllegalArgumentException("modifiers must not contain "
+                        + metaStateToString(basic) + " combined with "
+                        + metaStateToString(left) + " or " + metaStateToString(right));
+            }
+            return metaState & ~directional;
+        } else if (wantLeftOrRight) {
+            return metaState & ~basic;
+        } else {
+            return metaState;
+        }
+    }
+
+    /**
+     * Returns true if no modifier keys are pressed.
+     * <p>
+     * For the purposes of this function, {@link #KEYCODE_CAPS_LOCK},
+     * {@link #KEYCODE_SCROLL_LOCK}, and {@link #KEYCODE_NUM_LOCK} are
+     * not considered modifier keys.  Consequently, this function ignores
+     * {@link #META_CAPS_LOCK_ON}, {@link #META_SCROLL_LOCK_ON} and {@link #META_NUM_LOCK_ON}.
+     * </p><p>
+     * The meta state is normalized prior to comparison using {@link #normalizeMetaState(int)}.
+     * </p>
+     *
+     * @return True if no modifier keys are pressed.
+     * @see #metaStateHasNoModifiers
+     */
+    public final boolean hasNoModifiers() {
+        return metaStateHasNoModifiers(mMetaState);
+    }
+
+    /**
+     * Returns true if only the specified modifiers keys are pressed.
+     * Returns false if a different combination of modifier keys are pressed.
+     * <p>
+     * For the purposes of this function, {@link #KEYCODE_CAPS_LOCK},
+     * {@link #KEYCODE_SCROLL_LOCK}, and {@link #KEYCODE_NUM_LOCK} are
+     * not considered modifier keys.  Consequently, this function ignores
+     * {@link #META_CAPS_LOCK_ON}, {@link #META_SCROLL_LOCK_ON} and {@link #META_NUM_LOCK_ON}.
+     * </p><p>
+     * If the specified modifier mask includes directional modifiers, such as
+     * {@link #META_SHIFT_LEFT_ON}, then this method ensures that the
+     * modifier is pressed on that side.
+     * If the specified modifier mask includes non-directional modifiers, such as
+     * {@link #META_SHIFT_ON}, then this method ensures that the modifier
+     * is pressed on either side.
+     * If the specified modifier mask includes both directional and non-directional modifiers
+     * for the same type of key, such as {@link #META_SHIFT_ON} and {@link #META_SHIFT_LEFT_ON},
+     * then this method throws an illegal argument exception.
+     * </p>
+     *
+     * @param modifiers The meta state of the modifier keys to check.  May be a combination
+     * of modifier meta states as defined by {@link #getModifierMetaStateMask()}.  May be 0 to
+     * ensure that no modifier keys are pressed.
+     * @return True if only the specified modifier keys are pressed.
+     * @throws IllegalArgumentException if the modifiers parameter contains invalid modifiers
+     * @see #metaStateHasModifiers
+     */
+    public final boolean hasModifiers(int modifiers) {
+        return metaStateHasModifiers(mMetaState, modifiers);
+    }
+
+    /**
      * <p>Returns the pressed state of the ALT meta key.</p>
      *
      * @return true if the ALT key is pressed, false otherwise
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 86cd3b0..b8d72a6 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -377,17 +377,29 @@
     }
     
     /**
+     * Like {@link #screenshot(int, int, int, int)} but includes all
+     * Surfaces in the screenshot.
+     *
+     * @hide
+     */
+    public static native Bitmap screenshot(int width, int height);
+    
+    /**
      * Copy the current screen contents into a bitmap and return it.
      *
      * @param width The desired width of the returned bitmap; the raw
      * screen will be scaled down to this size.
      * @param height The desired height of the returned bitmap; the raw
      * screen will be scaled down to this size.
+     * @param minLayer The lowest (bottom-most Z order) surface layer to
+     * include in the screenshot.
+     * @param maxLayer The highest (top-most Z order) surface layer to
+     * include in the screenshot.
      * @return Returns a Bitmap containing the screen contents.
      *
      * @hide
      */
-    public static native Bitmap screenshot(int width, int height);
+    public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);
 
     /**
      * set surface parameters.
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 18a0bda..d83fc42 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -848,7 +848,7 @@
 
         public AutoCompleteAdapter(Context context, ArrayList<String> entries) {
             super(context, com.android.internal.R.layout
-                    .search_dropdown_item_1line, entries);
+                    .web_text_view_dropdown, entries);
         }
 
         /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c6cf918..0959bfa 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1952,21 +1952,6 @@
         }
     }
 
-    /**
-     * Deletes any files that were created as a part of the last private
-     * browsing session and clears any internal state associated with that
-     * session. The consequences of calling this method while a private
-     * browsing session is active are unspecified.
-     * @return True if the private browsing files were successfully deleted,
-     *         false otherwise.
-     * @hide pending API council approval.
-     */
-    public static boolean cleanupPrivateBrowsingFiles() {
-        return nativeCleanupPrivateBrowsingFiles();
-    }
-
-    private static native boolean nativeCleanupPrivateBrowsingFiles();
-
     private boolean extendScroll(int y) {
         int finalY = mScroller.getFinalY();
         int newY = pinLocY(finalY + y);
@@ -6248,7 +6233,12 @@
         // resumes during this effect we will take a performance hit. See computeScroll;
         // we resume webcore there when the animation is finished.
         final int time = mScroller.getDuration();
-        awakenScrollBars(time);
+
+        // Suppress scrollbars for layer scrolling.
+        if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
+            awakenScrollBars(time);
+        }
+
         invalidate();
     }
 
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 230cc51..c55d180 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -673,10 +673,9 @@
 
         public boolean onScale(ScaleGestureDetector detector) {
             // Prevent scaling beyond overview scale.
-            float scale = Math.max(
-                Math.round(detector.getScaleFactor() * mActualScale * 100) * 0.01f,
-                getZoomOverviewScale());
-            if (willScaleTriggerZoom(scale)) {
+            float scale = Math.max(detector.getScaleFactor() * mActualScale,
+                    getZoomOverviewScale());
+            if (mPinchToZoomAnimating || willScaleTriggerZoom(scale)) {
                 mPinchToZoomAnimating = true;
                 // limit the scale change per step
                 if (scale > mActualScale) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 87e4b5a..0b4e6c3 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3573,7 +3573,9 @@
                         overScrollBy(0, overshoot, 0, mScrollY, 0, 0,
                                 0, mOverflingDistance, false);
                     }
-                    edgeReached(delta);
+                    if (more) {
+                        edgeReached(delta);
+                    }
                     break;
                 }
 
diff --git a/core/java/android/widget/Adapter.java b/core/java/android/widget/Adapter.java
index 9b6c5a4..88b54bf 100644
--- a/core/java/android/widget/Adapter.java
+++ b/core/java/android/widget/Adapter.java
@@ -17,7 +17,6 @@
 package android.widget;
 
 import android.database.DataSetObserver;
-import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -91,6 +90,9 @@
      * @param convertView The old view to reuse, if possible. Note: You should check that this view
      *        is non-null and of an appropriate type before using. If it is not possible to convert
      *        this view to display the correct data, this method can create a new view.
+     *        Heterogeneous lists can specify their number of view types, so that this View is
+     *        always of the right type (see {@link #getViewTypeCount()} and
+     *        {@link #getItemViewType(int)}).
      * @param parent The parent that this view will eventually be attached to
      * @return A View corresponding to the data at the specified position.
      */
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 4e3ef0c..6ff671a 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -58,11 +58,11 @@
 
     private static final int[] ATTRS = new int[] {
         android.R.attr.textColorPrimary,
-        com.android.internal.R.attr.fastScrollThumbDrawable,
-        com.android.internal.R.attr.fastScrollTrackDrawable,
-        com.android.internal.R.attr.fastScrollPreviewBackgroundLeft,
-        com.android.internal.R.attr.fastScrollPreviewBackgroundRight,
-        com.android.internal.R.attr.fastScrollOverlayPosition
+        android.R.attr.fastScrollThumbDrawable,
+        android.R.attr.fastScrollTrackDrawable,
+        android.R.attr.fastScrollPreviewBackgroundLeft,
+        android.R.attr.fastScrollPreviewBackgroundRight,
+        android.R.attr.fastScrollOverlayPosition
     };
 
     private static final int PRIMARY_TEXT_COLOR = 0;
@@ -227,14 +227,13 @@
 
     private void init(Context context) {
         // Get both the scrollbar states drawables
-        final Resources res = context.getResources();
         TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS);
-        useThumbDrawable(context, ta.getDrawable(ta.getIndex(THUMB_DRAWABLE)));
-        mTrackDrawable = ta.getDrawable(ta.getIndex(TRACK_DRAWABLE));
+        useThumbDrawable(context, ta.getDrawable(THUMB_DRAWABLE));
+        mTrackDrawable = ta.getDrawable(TRACK_DRAWABLE);
         
-        mOverlayDrawableLeft = ta.getDrawable(ta.getIndex(PREVIEW_BACKGROUND_LEFT));
-        mOverlayDrawableRight = ta.getDrawable(ta.getIndex(PREVIEW_BACKGROUND_RIGHT));
-        mOverlayPosition = ta.getInt(ta.getIndex(OVERLAY_POSITION), OVERLAY_FLOATING);
+        mOverlayDrawableLeft = ta.getDrawable(PREVIEW_BACKGROUND_LEFT);
+        mOverlayDrawableRight = ta.getDrawable(PREVIEW_BACKGROUND_RIGHT);
+        mOverlayPosition = ta.getInt(OVERLAY_POSITION, OVERLAY_FLOATING);
         
         mScrollCompleted = true;
 
@@ -249,7 +248,7 @@
         mPaint.setTextAlign(Paint.Align.CENTER);
         mPaint.setTextSize(mOverlaySize / 2);
 
-        ColorStateList textColor = ta.getColorStateList(ta.getIndex(PRIMARY_TEXT_COLOR));
+        ColorStateList textColor = ta.getColorStateList(PRIMARY_TEXT_COLOR);
         int textColorNormal = textColor.getDefaultColor();
         mPaint.setColor(textColorNormal);
         mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 0f61cd4..591a2d4 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -600,7 +600,6 @@
      * @return true if the touch splitting is enabled, false otherwise
      * 
      * @see #setSplitTouchEnabled(boolean)
-     * @hide
      */
     public boolean isSplitTouchEnabled() {
         if (mSplitTouchEnabled < 0 && mContext != null) {
@@ -621,7 +620,6 @@
      *
      * @param enabled true if the split touches should be enabled, false otherwise
      * @see #isSplitTouchEnabled()
-     * @hide
      */
     public void setSplitTouchEnabled(boolean enabled) {
         mSplitTouchEnabled = enabled ? 1 : 0;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1dbb03d..7fc7e54 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -918,9 +918,10 @@
             drawableLeft, drawableTop, drawableRight, drawableBottom);
         setCompoundDrawablePadding(drawablePadding);
 
-        // Same as setSingleLine, but make sure the transformation method is unchanged.
+        // Same as setSingleLine(), but make sure the transformation method and the maximum number
+        // of lines of height (for multi-line only) are unchanged.
         setInputTypeSingleLine(singleLine);
-        applySingleLine(singleLine, false);
+        applySingleLine(singleLine, false, false);
 
         if (singleLine && mInput == null && ellipsize < 0) {
                 ellipsize = 3; // END
@@ -2156,7 +2157,10 @@
     }
 
     /**
-     * Makes the TextView at least this many lines tall
+     * Makes the TextView at least this many lines tall.
+     *
+     * Setting this value overrides any other (minimum) height setting. A single line TextView will
+     * set this value to 1.
      *
      * @attr ref android.R.styleable#TextView_minLines
      */
@@ -2170,7 +2174,9 @@
     }
 
     /**
-     * Makes the TextView at least this many pixels tall
+     * Makes the TextView at least this many pixels tall.
+     *
+     * Setting this value overrides any other (minimum) number of lines setting.
      *
      * @attr ref android.R.styleable#TextView_minHeight
      */
@@ -2184,7 +2190,9 @@
     }
 
     /**
-     * Makes the TextView at most this many lines tall
+     * Makes the TextView at most this many lines tall.
+     *
+     * Setting this value overrides any other (maximum) height setting.
      *
      * @attr ref android.R.styleable#TextView_maxLines
      */
@@ -2198,7 +2206,10 @@
     }
 
     /**
-     * Makes the TextView at most this many pixels tall
+     * Makes the TextView at most this many pixels tall.  This option is mutually exclusive with the
+     * {@link #setMaxLines(int)} method.
+     *
+     * Setting this value overrides any other (maximum) number of lines setting.
      *
      * @attr ref android.R.styleable#TextView_maxHeight
      */
@@ -2212,7 +2223,10 @@
     }
 
     /**
-     * Makes the TextView exactly this many lines tall
+     * Makes the TextView exactly this many lines tall.
+     *
+     * Note that setting this value overrides any other (minimum / maximum) number of lines or
+     * height setting. A single line TextView will set this value to 1.
      *
      * @attr ref android.R.styleable#TextView_lines
      */
@@ -2230,6 +2244,9 @@
      * You could do the same thing by specifying this number in the
      * LayoutParams.
      *
+     * Note that setting this value overrides any other (minimum / maximum) number of lines or
+     * height setting.
+     *
      * @attr ref android.R.styleable#TextView_height
      */
     @android.view.RemotableViewMethod
@@ -3027,12 +3044,14 @@
     }
 
     /**
-     * Set the type of the content with a constant as defined for
-     * {@link EditorInfo#inputType}.  This will take care of changing
-     * the key listener, by calling {@link #setKeyListener(KeyListener)}, to
-     * match the given content type.  If the given content type is
-     * {@link EditorInfo#TYPE_NULL} then a soft keyboard will
-     * not be displayed for this text view.
+     * Set the type of the content with a constant as defined for {@link EditorInfo#inputType}. This
+     * will take care of changing the key listener, by calling {@link #setKeyListener(KeyListener)},
+     * to match the given content type.  If the given content type is {@link EditorInfo#TYPE_NULL}
+     * then a soft keyboard will not be displayed for this text view.
+     *
+     * Note that the maximum number of displayed lines (see {@link #setMaxLines(int)}) will be
+     * modified if you change the {@link EditorInfo#TYPE_TEXT_FLAG_MULTI_LINE} flag of the input
+     * type.
      *
      * @see #getInputType()
      * @see #setRawInputType(int)
@@ -3069,7 +3088,7 @@
         if (mSingleLine != singleLine || forceUpdate) {
             // Change single line mode, but only change the transformation if
             // we are not in password mode.
-            applySingleLine(singleLine, !isPassword);
+            applySingleLine(singleLine, !isPassword, true);
         }
         
         InputMethodManager imm = InputMethodManager.peekInstance();
@@ -4083,8 +4102,9 @@
      *
      * Use {@link #setTextIsSelectable(boolean)} or the
      * {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
-     * selectable (the text is not selectable by default). Note that the content of an EditText is
-     * always selectable.
+     * selectable (the text is not selectable by default). 
+     *
+     * Note that the content of an EditText is always selectable.
      *
      * @return True if the text displayed in this TextView can be selected by the user.
      *
@@ -4096,6 +4116,11 @@
 
     /**
      * Sets whether or not (default) the content of this view is selectable by the user.
+     * 
+     * Note that this methods affect the {@link #setFocusableInTouchMode(boolean)},
+     * {@link #setFocusable(boolean)}, {@link #setClickable(boolean)} and
+     * {@link #setLongClickable(boolean)} states and you may want to restore these if they were
+     * customized.
      *
      * See {@link #isTextSelectable} for details.
      *
@@ -6302,19 +6327,21 @@
     }
 
     /**
-     * If true, sets the properties of this field (lines, horizontally
-     * scrolling, transformation method) to be for a single-line input;
-     * if false, restores these to the default conditions.
-     * Note that calling this with false restores default conditions,
-     * not necessarily those that were in effect prior to calling
-     * it with true.
+     * If true, sets the properties of this field (number of lines, horizontally scrolling,
+     * transformation method) to be for a single-line input; if false, restores these to the default
+     * conditions.
+     *
+     * Note that the default conditions are not necessarily those that were in effect prior this
+     * method, and you may want to reset these properties to your custom values.
      *
      * @attr ref android.R.styleable#TextView_singleLine
      */
     @android.view.RemotableViewMethod
     public void setSingleLine(boolean singleLine) {
+        // Could be used, but may break backward compatibility.
+        // if (mSingleLine == singleLine) return;
         setInputTypeSingleLine(singleLine);
-        applySingleLine(singleLine, true);
+        applySingleLine(singleLine, true, true);
     }
 
     /**
@@ -6331,7 +6358,8 @@
         }
     }
 
-    private void applySingleLine(boolean singleLine, boolean applyTransformation) {
+    private void applySingleLine(boolean singleLine, boolean applyTransformation,
+            boolean changeMaxLines) {
         mSingleLine = singleLine;
         if (singleLine) {
             setLines(1);
@@ -6341,7 +6369,9 @@
             }
             setBackgroundDrawable(mEditTextSingleLineBackground);
         } else {
-            setMaxLines(Integer.MAX_VALUE);
+            if (changeMaxLines) {
+                setMaxLines(Integer.MAX_VALUE);
+            }
             setHorizontallyScrolling(false);
             if (applyTransformation) {
                 setTransformationMethod(null);
@@ -7616,7 +7646,7 @@
             if (start == end) {
                 // Cases where the text ends with a '.' and we select from the end of the line
                 // (right after the dot), or when we select from the space character in "aaa, bbb".
-                final char c = mTransformed.charAt(start);
+                final char c = mTransformed.charAt(start - 1);
                 final int type = Character.getType(c);
                 if (type == Character.OTHER_PUNCTUATION) continue;
             }
@@ -8435,13 +8465,6 @@
         public static final int CENTER = 1;
         public static final int RIGHT = 2;
 
-        class LongPressCallback implements Runnable {
-            public void run() {
-                mController.hide();
-                startSelectionActionMode();
-            }
-        }
-
         public HandleView(CursorController controller, int pos) {
             super(TextView.this.mContext);
             mController = controller;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 9b26aeb..3a58867 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -326,7 +326,7 @@
     }
 
     public void setBackgroundDrawable(Drawable d) {
-        mActionView.setBackgroundDrawable(d);
+        mContainerView.setBackgroundDrawable(d);
     }
 
     public View getCustomNavigationView() {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 145feb5..284df1e 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -192,7 +192,8 @@
     StopwatchTimer mVideoOnTimer;
 
     int mPhoneSignalStrengthBin = -1;
-    final StopwatchTimer[] mPhoneSignalStrengthsTimer =
+    int mPhoneSignalStrengthBinRaw = -1;
+    final StopwatchTimer[] mPhoneSignalStrengthsTimer = 
             new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
 
     StopwatchTimer mPhoneSignalScanningTimer;
@@ -252,6 +253,8 @@
     private int mBluetoothPingStart = -1;
 
     private int mPhoneServiceState = -1;
+    private int mPhoneServiceStateRaw = -1;
+    private int mPhoneSimStateRaw = -1;
 
     /*
      * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
@@ -1650,40 +1653,54 @@
         }
     }
 
-    /**
-     * Telephony stack updates the phone state.
-     * @param state phone state from ServiceState.getState()
-     */
-    public void notePhoneStateLocked(int state) {
-        boolean scanning = false;
+    private int fixPhoneServiceState(int state, int signalBin) {
+        if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
+            // In this case we will always be STATE_OUT_OF_SERVICE, so need
+            // to infer that we are scanning from other data.
+            if (state == ServiceState.STATE_OUT_OF_SERVICE
+                    && signalBin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                state = ServiceState.STATE_IN_SERVICE;
+            }
+        }
 
-        int bin = mPhoneSignalStrengthBin;
+        return state;
+    }
+
+    private void updateAllPhoneStateLocked(int state, int simState, int bin) {
+        boolean scanning = false;
+        boolean newHistory = false;
+
+        mPhoneServiceStateRaw = state;
+        mPhoneSimStateRaw = simState;
+        mPhoneSignalStrengthBinRaw = bin;
+
+        if (simState == TelephonyManager.SIM_STATE_ABSENT) {
+            // In this case we will always be STATE_OUT_OF_SERVICE, so need
+            // to infer that we are scanning from other data.
+            if (state == ServiceState.STATE_OUT_OF_SERVICE
+                    && bin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                state = ServiceState.STATE_IN_SERVICE;
+            }
+        }
 
         // If the phone is powered off, stop all timers.
         if (state == ServiceState.STATE_POWER_OFF) {
-            stopAllSignalStrengthTimersLocked(-1);
+            bin = -1;
 
-        // If we're back in service or continuing in service, restart the old timer.
-        } if (state == ServiceState.STATE_IN_SERVICE) {
-            if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-            if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
-                mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
-            }
+        // If we are in service, make sure the correct signal string timer is running.
+        } else if (state == ServiceState.STATE_IN_SERVICE) {
+            // Bin will be changed below.
 
         // If we're out of service, we are in the lowest signal strength
         // bin and have the scanning bit set.
         } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
             scanning = true;
-            mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-            stopAllSignalStrengthTimersLocked(mPhoneSignalStrengthBin);
-            if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
-                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
-            }
+            bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
             if (!mPhoneSignalScanningTimer.isRunningLocked()) {
                 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
+                newHistory = true;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
                 mPhoneSignalScanningTimer.startRunningLocked(this);
             }
         }
@@ -1694,7 +1711,7 @@
                 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                newHistory = true;
                 mPhoneSignalScanningTimer.stopRunningLocked(this);
             }
         }
@@ -1702,21 +1719,48 @@
         if (mPhoneServiceState != state) {
             mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
                     | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + bin + " to: "
+            if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            newHistory = true;
             mPhoneServiceState = state;
         }
+
+        if (mPhoneSignalStrengthBin != bin) {
+            if (mPhoneSignalStrengthBin >= 0) {
+                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
+            }
+            if (bin >= 0) {
+                if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
+                    mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
+                }
+                mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
+                        | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
+                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
+                        + Integer.toHexString(mHistoryCur.states));
+                newHistory = true;
+            } else {
+                stopAllSignalStrengthTimersLocked(-1);
+            }
+            mPhoneSignalStrengthBin = bin;
+        }
+
+        if (newHistory) {
+            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+        }
+    }
+
+    /**
+     * Telephony stack updates the phone state.
+     * @param state phone state from ServiceState.getState()
+     */
+    public void notePhoneStateLocked(int state, int simState) {
+        updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
     }
 
     public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
         // Bin the strength.
         int bin;
-        if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
-                || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
-            // Ignore any signal strength changes when radio was turned off or out of service.
-            return;
-        }
+
         if (!signalStrength.isGsm()) {
             int dBm = signalStrength.getCdmaDbm();
             if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
@@ -1732,18 +1776,8 @@
             else if (asu >= 4)  bin = SIGNAL_STRENGTH_MODERATE;
             else bin = SIGNAL_STRENGTH_POOR;
         }
-        if (mPhoneSignalStrengthBin != bin) {
-            mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
-                    | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
-            if (mPhoneSignalStrengthBin >= 0) {
-                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
-            }
-            mPhoneSignalStrengthBin = bin;
-            mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
-        }
+
+        updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
     }
 
     public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
@@ -3983,6 +4017,9 @@
             }
             mKernelWakelockStats.clear();
         }
+        
+        mLowDischargeAmountSinceCharge = 0;
+        mHighDischargeAmountSinceCharge = 0;
 
         clearHistoryLocked();
     }
@@ -4005,12 +4042,10 @@
                 // level to a now very high level).
                 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
                         || level >= 95
-                        || (mDischargeCurrentLevel < 30 && level >= 90)) {
+                        || (mDischargeCurrentLevel < 20 && level >= 80)) {
                     doWrite = true;
                     resetAllStatsLocked();
                     mDischargeStartLevel = level;
-                    mLowDischargeAmountSinceCharge = 0;
-                    mHighDischargeAmountSinceCharge = 0;
                 }
                 updateKernelWakelocksLocked();
                 mHistoryCur.batteryLevel = (byte)level;
@@ -4100,11 +4135,13 @@
                 mHistoryCur.batteryPlugType = (byte)plugType;
                 changed = true;
             }
-            if (mHistoryCur.batteryTemperature != temp) {
+            if (temp >= (mHistoryCur.batteryTemperature+10)
+                    || temp <= (mHistoryCur.batteryTemperature-10)) {
                 mHistoryCur.batteryTemperature = (char)temp;
                 changed = true;
             }
-            if (mHistoryCur.batteryVoltage != volt) {
+            if (volt > (mHistoryCur.batteryVoltage+20)
+                    || volt < (mHistoryCur.batteryVoltage-20)) {
                 mHistoryCur.batteryVoltage = (char)volt;
                 changed = true;
             }
@@ -4300,20 +4337,28 @@
     }
 
     public int getDischargeCurrentLevelLocked() {
-            return mDischargeCurrentLevel;
+        return mDischargeCurrentLevel;
     }
 
     @Override
     public int getLowDischargeAmountSinceCharge() {
         synchronized(this) {
-            return mLowDischargeAmountSinceCharge;
+            int val = mLowDischargeAmountSinceCharge;
+            if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
+                val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
+            }
+            return val;
         }
     }
 
     @Override
     public int getHighDischargeAmountSinceCharge() {
         synchronized(this) {
-            return mHighDischargeAmountSinceCharge;
+            int val = mHighDischargeAmountSinceCharge;
+            if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
+                val += mDischargeUnplugLevel-mDischargeCurrentLevel;
+            }
+            return val;
         }
     }
 
@@ -4815,9 +4860,9 @@
         out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
         out.writeInt(mDischargeUnplugLevel);
         out.writeInt(mDischargeCurrentLevel);
-        out.writeInt(mLowDischargeAmountSinceCharge);
-        out.writeInt(mHighDischargeAmountSinceCharge);
-
+        out.writeInt(getLowDischargeAmountSinceCharge());
+        out.writeInt(getHighDischargeAmountSinceCharge());
+        
         mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
             mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 60c3487..5ae3616 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -159,7 +159,9 @@
     }
 
     public void initForMode(final ActionMode mode) {
-        finishAnimation();
+        if (mAnimationMode == ANIMATE_OUT) {
+            killMode();
+        }
 
         if (mClose == null) {
             LayoutInflater inflater = LayoutInflater.from(mContext);
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 07505a5..2dfebe5 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -20,6 +20,7 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <binder/IBinder.h>
+#include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
@@ -431,6 +432,20 @@
     LOG_PRI_VA(ANDROID_LOG_INFO, "vm-printf", format, ap);
 }
 
+/**
+ * The VM calls this when mutex contention debugging is enabled to
+ * determine whether or not the blocked thread was a "sensitive thread"
+ * for user responsiveness/smoothess.
+ *
+ * Our policy for this is whether or not we're tracing any StrictMode
+ * events on this thread (which we might've inherited via Binder calls
+ * into us)
+ */
+static bool runtime_isSensitiveThread() {
+    IPCThreadState* state = IPCThreadState::selfOrNull();
+    return state && state->getStrictModePolicy() != 0;
+}
+
 
 /**
  * Add VM arguments to the to-be-executed VM
@@ -618,6 +633,11 @@
     opt.optionString = "vfprintf";
     mOptions.add(opt);
 
+    /* register the framework-specific "is sensitive thread" hook */
+    opt.extraInfo = (void*) runtime_isSensitiveThread;
+    opt.optionString = "sensitiveThread";
+    mOptions.add(opt);
+
     opt.extraInfo = NULL;
 
     /* enable verbose; standard options are { jni, gc, class } */
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 8956e39..29c6ba2 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -429,7 +429,15 @@
 

     size_t size = bitmap->getSize();

     bitmap->lockPixels();

-    memcpy(p->writeInplace(size), bitmap->getPixels(), size);

+    void* pDst = p->writeInplace(size);

+

+    const void* pSrc =  bitmap->getPixels();

+

+    if (pSrc == NULL) {

+        memset(pDst, 0, size);

+    } else {

+        memcpy(pDst, pSrc, size);

+    }

     bitmap->unlockPixels();

     return true;

 }

diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 0663e98..6737501 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -173,14 +173,17 @@
     return doBooleanCommand(cmdstr, "OK");
 }
 
-static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz, jstring bssid, int apPin)
+static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz,
+        jstring bssid, jstring apPin)
 {
     char cmdstr[BUF_SIZE];
     jboolean isCopy;
 
     const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
-    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_REG %s %d", bssidStr, apPin);
+    const char *apPinStr = env->GetStringUTFChars(apPin, &isCopy);
+    int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_REG %s %s", bssidStr, apPinStr);
     env->ReleaseStringUTFChars(bssid, bssidStr);
+    env->ReleaseStringUTFChars(apPin, apPinStr);
 
     if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
         return false;
@@ -188,7 +191,7 @@
     return doBooleanCommand(cmdstr, "OK");
 }
 
-static jint android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid)
+static jstring android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid)
 {
     char cmdstr[BUF_SIZE];
     jboolean isCopy;
@@ -198,9 +201,9 @@
     env->ReleaseStringUTFChars(bssid, bssidStr);
 
     if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
-        return -1;
+        return NULL;
     }
-    return doIntCommand(cmdstr);
+    return doStringCommand(env, cmdstr);
 }
 
 static jboolean android_net_wifi_setCountryCodeCommand(JNIEnv* env, jobject clazz, jstring country)
@@ -648,9 +651,9 @@
     { "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
     { "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
     { "startWpsPbcCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_wpsPbcCommand },
-    { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;I)Z",
+    { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
         (void*) android_net_wifi_wpsPinFromAccessPointCommand },
-    { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)I",
+    { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)Ljava/lang/String;",
         (void*) android_net_wifi_wpsPinFromDeviceCommand },
     { "setSuspendOptimizationsCommand", "(Z)Z",
         (void*) android_net_wifi_setSuspendOptimizationsCommand},
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 848b8f5..b9ae526 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -928,6 +928,78 @@
     return JNI_FALSE;
 }
 
+#ifdef HAVE_BLUETOOTH
+static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
+    jint *handles;
+    jintArray handleArray = NULL;
+    int len;
+
+    DBusError err;
+    dbus_error_init(&err);
+
+    if (dbus_message_get_args(reply, &err,
+                              DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
+                              DBUS_TYPE_INVALID)) {
+        handleArray = env->NewIntArray(len);
+        if (handleArray) {
+            env->SetIntArrayRegion(handleArray, 0, len, handles);
+        } else {
+            LOGE("Null array in extract_handles");
+        }
+    } else {
+        LOG_AND_FREE_DBUS_ERROR(&err);
+    }
+    return handleArray;
+}
+#endif
+
+static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
+                                                jintArray uuids) {
+    LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+    DBusMessage *reply = NULL;
+
+    native_data_t *nat = get_native_data(env, object);
+
+    jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
+    if (!svc_classes) return NULL;
+
+    int len = env->GetArrayLength(uuids);
+    reply = dbus_func_args(env, nat->conn,
+                            get_adapter_path(env, object),
+                            DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
+                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
+                            &svc_classes, len, DBUS_TYPE_INVALID);
+    env->ReleaseIntArrayElements(uuids, svc_classes, 0);
+    return reply ? extract_handles(env, reply) : NULL;
+
+#endif
+    return NULL;
+}
+
+static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
+                                                   jintArray handles) {
+    LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+    native_data_t *nat = get_native_data(env, object);
+    jint *values = env->GetIntArrayElements(handles, NULL);
+    DBusMessage *msg = NULL;
+    DBusMessage *reply = NULL;
+    if (values == NULL) return JNI_FALSE;
+
+    jsize len = env->GetArrayLength(handles);
+
+    reply = dbus_func_args(env, nat->conn,
+                            get_adapter_path(env, object),
+                            DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
+                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
+                            &values, len, DBUS_TYPE_INVALID);
+    env->ReleaseIntArrayElements(handles, values, NULL);
+    return reply ? JNI_TRUE : JNI_FALSE;
+#endif
+    return JNI_FALSE;
+}
+
 static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
         jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
     LOGV(__FUNCTION__);
@@ -1193,6 +1265,8 @@
     {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
     {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
     {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
+    {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
+    {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
     {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
     // HID functions
     {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 206e320..8c30987 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -449,9 +449,11 @@
         SkSafeUnref(fCTable);
     }
 
-    status_t update(int width, int height) {
+    status_t update(int width, int height, int minLayer, int maxLayer, bool allLayers) {
         status_t res = (width > 0 && height > 0)
-                ? mScreenshot.update(width, height)
+                ? (allLayers
+                        ? mScreenshot.update(width, height)
+                        : mScreenshot.update(width, height, minLayer, maxLayer))
                 : mScreenshot.update();
         if (res != NO_ERROR) {
             return res;
@@ -493,10 +495,11 @@
     typedef SkPixelRef INHERITED;
 };
 
-static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height)
+static jobject doScreenshot(JNIEnv* env, jobject clazz, jint width, jint height,
+        jint minLayer, jint maxLayer, bool allLayers)
 {
     ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
-    if (pixels->update(width, height) != NO_ERROR) {
+    if (pixels->update(width, height, minLayer, maxLayer, allLayers) != NO_ERROR) {
         delete pixels;
         return 0;
     }
@@ -525,6 +528,17 @@
     return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
 }
 
+static jobject Surface_screenshotAll(JNIEnv* env, jobject clazz, jint width, jint height)
+{
+    return doScreenshot(env, clazz, width, height, 0, 0, true);
+}
+
+static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height,
+        jint minLayer, jint maxLayer, bool allLayers)
+{
+    return doScreenshot(env, clazz, width, height, minLayer, maxLayer, false);
+}
+
 static void Surface_setLayer(
         JNIEnv* env, jobject clazz, jint zorder)
 {
@@ -750,7 +764,8 @@
     {"setOrientation",      "(III)V", (void*)Surface_setOrientation },
     {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },
     {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },
-    {"screenshot",          "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
+    {"screenshot",          "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll },
+    {"screenshot",          "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
     {"setLayer",            "(I)V", (void*)Surface_setLayer },
     {"setPosition",         "(II)V",(void*)Surface_setPosition },
     {"setSize",             "(II)V",(void*)Surface_setSize },
diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml
index 82d990c..69437b8 100644
--- a/core/res/res/anim/activity_close_enter.xml
+++ b/core/res/res/anim/activity_close_enter.xml
@@ -13,19 +13,19 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 		android:zAdjustment="normal"
         android:shareInterpolator="false">
-    <scale android:fromXScale="0.98" android:toXScale="1.0"
-            android:fromYScale="0.98" android:toYScale="1.0"
+    <scale android:fromXScale="0.975" android:toXScale="1.0"
+            android:fromYScale="0.975" android:toYScale="1.0"
             android:pivotX="50%p" android:pivotY="50%p"
             android:interpolator="@anim/decelerate_quint_interpolator"
             android:duration="@android:integer/config_activityDefaultDur" />
     <alpha android:fromAlpha=".75" android:toAlpha="1.0"
-            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:interpolator="@anim/decelerate_cubic_interpolator"
             android:duration="@android:integer/config_activityDefaultDur"/>
-</set>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml
index 13768b5..c73bc3a 100644
--- a/core/res/res/anim/activity_close_exit.xml
+++ b/core/res/res/anim/activity_close_exit.xml
@@ -13,20 +13,19 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 		android:zAdjustment="top"
         android:shareInterpolator="false">
-    <scale android:fromXScale="1.0" android:toXScale="1.04"
-            android:fromYScale="1.0" android:toYScale="1.04"
+    <scale android:fromXScale="1.0" android:toXScale="1.075"
+            android:fromYScale="1.0" android:toYScale="1.075"
             android:pivotX="50%p" android:pivotY="50%p"
             android:interpolator="@anim/decelerate_quint_interpolator"
             android:duration="@android:integer/config_activityDefaultDur" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:interpolator="@anim/decelerate_cubic_interpolator"
             android:duration="@android:integer/config_activityDefaultDur"/>
-
-</set>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml
index 4841910..7b6a7f0 100644
--- a/core/res/res/anim/activity_open_enter.xml
+++ b/core/res/res/anim/activity_open_enter.xml
@@ -13,20 +13,19 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 		android:zAdjustment="top"
         android:shareInterpolator="false">
-    <scale android:fromXScale="1.04" android:toXScale="1.0"
-            android:fromYScale="1.04" android:toYScale="1.0"
+    <scale android:fromXScale="1.125" android:toXScale="1.0"
+            android:fromYScale="1.125" android:toYScale="1.0"
             android:pivotX="50%p" android:pivotY="50%p"
             android:interpolator="@anim/decelerate_quint_interpolator"
             android:duration="@android:integer/config_activityDefaultDur" />
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:interpolator="@anim/decelerate_cubic_interpolator"
             android:duration="@android:integer/config_activityDefaultDur"/>
-
-</set>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml
index 81e902f..b07ab2b 100644
--- a/core/res/res/anim/activity_open_exit.xml
+++ b/core/res/res/anim/activity_open_exit.xml
@@ -13,20 +13,19 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 		android:zAdjustment="normal"
         android:shareInterpolator="false">
-    <scale android:fromXScale="1.0" android:toXScale="0.98"
-            android:fromYScale="1.0" android:toYScale="0.98"
+    <scale android:fromXScale="1.0" android:toXScale="0.975"
+            android:fromYScale="1.0" android:toYScale="0.975"
             android:pivotX="50%p" android:pivotY="50%p"
-            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:interpolator="@anim/linear_interpolator"
             android:duration="@android:integer/config_activityDefaultDur" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0.75"
-            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:interpolator="@anim/decelerate_cubic_interpolator"
             android:duration="@android:integer/config_activityDefaultDur"/>
-
-</set>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_close_enter.xml b/core/res/res/anim/fragment_close_enter.xml
index c1b564b..eaa192f 100644
--- a/core/res/res/anim/fragment_close_enter.xml
+++ b/core/res/res/anim/fragment_close_enter.xml
@@ -13,32 +13,27 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 	android:zAdjustment="normal">
-
     <objectAnimator
         android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="0.98"
-        android:valueTo="1.0"
+        android:valueFrom="0.975" android:valueTo="1.0"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="0.98"
-        android:valueTo="1.0"
+        android:valueFrom="0.975" android:valueTo="1.0"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_cubic_interpolator"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
+        android:valueFrom="0.0" android:valueTo="1.0"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_activityDefaultDur"/>
-
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_close_exit.xml b/core/res/res/anim/fragment_close_exit.xml
index 2ce358f..8851e3a 100644
--- a/core/res/res/anim/fragment_close_exit.xml
+++ b/core/res/res/anim/fragment_close_exit.xml
@@ -13,31 +13,27 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
 	android:zAdjustment="top">
     <objectAnimator
         android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="1.0"
-        android:valueTo="1.04"
+        android:valueFrom="1.0" android:valueTo="1.075"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="1.0"
-        android:valueTo="1.04"
+        android:valueFrom="1.0" android:valueTo="1.075"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_cubic_interpolator"
-        android:valueFrom="1.0"
-        android:valueTo="0.0"
+        android:valueFrom="1.0" android:valueTo="0.0"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_activityDefaultDur"/>
-
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_open_enter.xml b/core/res/res/anim/fragment_open_enter.xml
index e3bde46..bac75a5 100644
--- a/core/res/res/anim/fragment_open_enter.xml
+++ b/core/res/res/anim/fragment_open_enter.xml
@@ -13,30 +13,26 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <objectAnimator
         android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="1.04"
-        android:valueTo="1.0"
+        android:valueFrom="1.125" android:valueTo="1.0"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="1.04"
-        android:valueTo="1.0"
+        android:valueFrom="1.125" android:valueTo="1.0"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_cubic_interpolator"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
+        android:valueFrom="0.0" android:valueTo="1.0"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_activityDefaultDur"/>
-
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_open_exit.xml b/core/res/res/anim/fragment_open_exit.xml
index b4c2194..57f1f9f 100644
--- a/core/res/res/anim/fragment_open_exit.xml
+++ b/core/res/res/anim/fragment_open_exit.xml
@@ -13,30 +13,26 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <objectAnimator
-        android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="1.0"
-        android:valueTo="0.98"
+        android:interpolator="@anim/linear_interpolator"
+        android:valueFrom="1.0" android:valueTo="0.975"
         android:valueType="floatType"
         android:propertyName="scaleY"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
-        android:interpolator="@anim/decelerate_quint_interpolator"
-        android:valueFrom="1.0"
-        android:valueTo="0.98"
+        android:interpolator="@anim/linear_interpolator"
+        android:valueFrom="1.0" android:valueTo="0.975"
         android:valueType="floatType"
         android:propertyName="scaleX"
         android:duration="@android:integer/config_activityDefaultDur"/>
     <objectAnimator
         android:interpolator="@anim/decelerate_cubic_interpolator"
-        android:valueFrom="1.0"
-        android:valueTo="0.0"
+        android:valueFrom="1.0" android:valueTo="0.0"
         android:valueType="floatType"
         android:propertyName="alpha"
         android:duration="@android:integer/config_activityDefaultDur"/>
-
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml
index bfc8c6d..a050d9b 100644
--- a/core/res/res/anim/screen_rotate_180_enter.xml
+++ b/core/res/res/anim/screen_rotate_180_enter.xml
@@ -13,7 +13,7 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
@@ -21,7 +21,14 @@
         android:shareInterpolator="false">
     <scale android:fromXScale="1.0" android:toXScale="1.0"
             android:fromYScale=".9" android:toYScale="1.0"
-            android:pivotX="50%" android:pivotY="50%"
+            android:pivotX="50%p" android:pivotY="50%p"
+            android:fillEnabled="true" android:fillBefore="true"
             android:interpolator="@anim/decelerate_quint_interpolator"
-            android:duration="@android:integer/config_mediumAnimTime" />
-</set>
+            android:startOffset="160"
+            android:duration="300" />
+    <alpha android:fromAlpha="0" android:toAlpha="1.0"
+            android:fillEnabled="true" android:fillBefore="true"
+            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:startOffset="160"
+            android:duration="300"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml
index f1ce1cf..f6a6572 100644
--- a/core/res/res/anim/screen_rotate_180_exit.xml
+++ b/core/res/res/anim/screen_rotate_180_exit.xml
@@ -13,18 +13,18 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
     <scale android:fromXScale="1.0" android:toXScale="1.0"
-            android:fromYScale="1.0" android:toYScale=".9"
-            android:pivotX="50%" android:pivotY="50%"
-            android:interpolator="@anim/decelerate_quint_interpolator"
-            android:duration="@android:integer/config_mediumAnimTime" />
+            android:fromYScale="1.0" android:toYScale="0.0"
+            android:pivotX="50%p" android:pivotY="50%p"
+            android:interpolator="@anim/accelerate_cubic_interpolator"
+            android:duration="160" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:interpolator="@anim/decelerate_quint_interpolator"
-            android:duration="@android:integer/config_mediumAnimTime" />
-</set>
+            android:interpolator="@anim/decelerate_cubic_interpolator"
+            android:duration="160"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index 5057eed..1e29309 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -13,7 +13,7 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
@@ -24,11 +24,11 @@
             android:pivotX="50%p" android:pivotY="50%p"
 			android:fillEnabled="true" android:fillBefore="true"
             android:interpolator="@anim/decelerate_quint_interpolator"
-            android:startOffset="300"
+            android:startOffset="160"
             android:duration="300" />
     <alpha 	android:fromAlpha="0" android:toAlpha="1.0"
-            android:interpolator="@anim/decelerate_cubic_interpolator"
             android:fillEnabled="true" android:fillBefore="true"
-			android:startOffset="300"
+            android:interpolator="@anim/decelerate_quint_interpolator"
+            android:startOffset="160"
             android:duration="300"/>
 </set>
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index 169f846..b232e42 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -13,20 +13,20 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:detachWallpaper="true" android:shareInterpolator="false">
     <scale android:fromXScale="1.0" android:toXScale="1.0"
-			android:fillEnabled="true" android:fillAfter="true"
             android:fromYScale="1.0" android:toYScale="0.0"
             android:pivotX="50%p" android:pivotY="50%p"
-            android:interpolator="@anim/linear_interpolator"
-            android:duration="300" />
+			android:fillEnabled="true" android:fillAfter="true"
+            android:interpolator="@anim/accelerate_cubic_interpolator"
+            android:duration="160" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
 			android:fillEnabled="true" android:fillAfter="true"
             android:interpolator="@anim/decelerate_cubic_interpolator"
-            android:duration="150"/>
-</set>
+            android:duration="160"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index 8f8515a..4a2ae3b 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -13,22 +13,22 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:shareInterpolator="false">
     <scale android:fromXScale="1.0" android:toXScale="1.0"
-            android:fromYScale="0.95" android:toYScale="1.0"
+            android:fromYScale=".9" android:toYScale="1.0"
             android:pivotX="50%p" android:pivotY="50%p"
             android:fillEnabled="true" android:fillBefore="true"
             android:interpolator="@anim/decelerate_quint_interpolator"
-            android:startOffset="300"
+            android:startOffset="160"
             android:duration="300" />
     <alpha android:fromAlpha="0" android:toAlpha="1.0"
             android:fillEnabled="true" android:fillBefore="true"
             android:interpolator="@anim/decelerate_quint_interpolator"
-            android:startOffset="300"
+            android:startOffset="160"
             android:duration="300"/>
-</set>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index 7d2b1b1..a213bdf 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -13,20 +13,20 @@
 ** 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.
+** limitations under the License. 
 */
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:detachWallpaper="true" android:shareInterpolator="false">
+        android:shareInterpolator="false">
     <scale android:fromXScale="1.0" android:toXScale="1.0"
             android:fromYScale="1.0" android:toYScale="0.0"
             android:pivotX="50%p" android:pivotY="50%p"
-            android:fillEnabled="true" android:fillAfter="true"
-            android:interpolator="@anim/linear_interpolator"
-            android:duration="300" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:fillEnabled="true" android:fillAfter="true"
+			android:fillEnabled="true" android:fillAfter="true"
+            android:interpolator="@anim/accelerate_cubic_interpolator"
+            android:duration="160" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"		
+			android:fillEnabled="true" android:fillAfter="true"
             android:interpolator="@anim/decelerate_cubic_interpolator"
-            android:duration="150"/>
+            android:duration="160"/>
 </set>
\ No newline at end of file
diff --git a/core/res/res/layout/web_text_view_dropdown.xml b/core/res/res/layout/web_text_view_dropdown.xml
new file mode 100644
index 0000000..1dce5cb
--- /dev/null
+++ b/core/res/res/layout/web_text_view_dropdown.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2010, The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License"); 
+you may not use this file except in compliance with the License. 
+You may obtain a copy of the License at 
+
+http://www.apache.org/licenses/LICENSE-2.0 
+
+Unless required by applicable law or agreed to in writing, software 
+distributed under the License is distributed on an "AS IS" BASIS, 
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+See the License for the specific language governing permissions and 
+limitations under the License.
+
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:id="@android:id/text1"
+    style="?android:attr/dropDownItemStyle"
+    android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
+    android:textColor="#ff000000"
+    android:background="#ffffffff"
+    android:singleLine="true"
+    android:layout_width="match_parent"
+    android:layout_height="?android:attr/searchResultListItemHeight" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 6c76f57..dcc88f0 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1405,6 +1405,7 @@
   <public type="attr" name="fastScrollAlwaysVisible" />
   <public type="attr" name="fastScrollThumbDrawable" />
   <public type="attr" name="fastScrollPreviewBackgroundLeft" />
+  <public type="attr" name="fastScrollPreviewBackgroundRight" />
   <public type="attr" name="fastScrollTrackDrawable" />
   <public type="attr" name="fastScrollOverlayPosition" />
 
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 4d30a68..d34c6c1 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -287,6 +287,7 @@
         <item name="dayPickerWeekDayViewStyle">@style/TextAppearance.Small.DayPickerWeekDayView</item>
 
         <item name="fastScrollThumbDrawable">@android:drawable/scrollbar_handle_accelerated_anim2</item>
+        <item name="fastScrollTrackDrawable">@null</item>
         <item name="fastScrollPreviewBackgroundRight">@android:drawable/menu_submenu_background</item>
         <item name="fastScrollPreviewBackgroundLeft">@android:drawable/menu_submenu_background</item>
         <item name="fastScrollOverlayPosition">floating</item>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 2548128..e91d362 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -490,9 +490,31 @@
                <span class="en">UI Guidelines</span>
              </a></div>
         <ul>
-          <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design.html">
-                <span class="en">Icon Design</span>
-              </a></li>
+          <li class="toggle-list">
+            <div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design.html">
+                   <span class="en">Icon Design</span>
+                 </a></div>
+            <ul>
+              <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_launcher.html">
+                    <span class="en">Launcher Icons</span>
+                  </a></li>
+              <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_menu.html">
+                    <span class="en">Menu Icons</span>
+                  </a></li>
+              <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_status_bar.html">
+                    <span class="en">Status Bar Icons</span>
+                  </a></li>
+              <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_tab.html">
+                    <span class="en">Tab Icons</span>
+                  </a></li>
+              <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_dialog.html">
+                    <span class="en">Dialog Icons</span>
+                  </a></li>
+              <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_list.html">
+                    <span class="en">List View Icons</span>
+                  </a></li>
+            </ul>
+          </li>
           <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/widget_design.html">
                 <span class="en">App Widget Design</span>
               </a></li>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 389d5fa..d3b702d 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -1,4 +1,6 @@
-page.title=Icon Design Guidelines, Android 2.0
+page.title=Icon Design Guidelines
+parent.title=UI Guidelines
+parent.link=index.html
 @jd:body
 
 <div id="qv-wrapper">
@@ -15,37 +17,27 @@
 <h2>In this document</h2>
 
 <ol>
-<li><a href="#launcherstructure">Launcher icon</a></li>
-<li><a href="#menustructure">Menu icon</a></li>
-<li><a href="#statusbarstructure">Status bar icon</a></li>
-<li><a href="#tabstructure">Tab icon</a></li>
-<li><a href="#dialogstructure">Dialog icon</a></li>
-<li><a href="#listviewstructure">List view icon</a></li>
-
-<li style="margin-top:3px;"><a href="#design_tips">Tips for Designers</a></li>
 <li><a href="#templatespack">Using the Icon Templates Pack</a></li>
-
-<li><a href="#iconappendix">Icon appendix</a>
-	<ol>
-	<li><a href="#launcherapx">Standard Launcher icons</a></li>
-	<li><a href="#menuapx">Standard Menu icons</a></li>
-	<li><a href="#statusbarapx">Standard Status bar icons</a></li>
-	</ol>
-</li>
-
+<li><a href="#icon-sets">Providing Density-Specific Icon Sets</a></li>
+<li><a href="#design-tips">Tips for Designers</a></li>
 </ol>
 
-<h2>Older versions</h2>
+<h2>Topics</h2>
 
 <ol>
-<li style="margin-top:4px;"><a
-href="{@docRoot}guide/practices/ui_guidelines/icon_design_1.html">Icon Design
-Guidelines, Android 1.0</a></li>
+<li><a href="icon_design_launcher.html">Launcher Icons</a></li>
+<li><a href="icon_design_menu.html">Menu Icons</a></li>
+<li><a href="icon_design_status_bar.html">Status Bar Icons</a></li>
+<li><a href="icon_design_tab.html">Tab Icons</a></li>
+<li><a href="icon_design_dialog.html">Dialog Icons</a></li>
+<li><a href="icon_design_list.html">List View Icons</a></li>
 </ol>
 
 <h2>Downloads</h2>
 
 <ol>
+<li><a href="{@docRoot}shareables/icon_templates-v2.3.zip">Android Icon
+Templates Pack, v2.3 &raquo;</a></li>
 <li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
 Templates Pack, v2.0 &raquo;</a></li>
 <li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
@@ -72,9 +64,62 @@
 Android 2.x framework. Following these guidelines will help you to create a 
 polished and unified experience for the user.</p>
 
+<p>The following documents discuss detailed guidelines for the common types of
+icons used throughout Android applications:</p>
+
+<dl> 
+  <dt><strong><a href="icon_design_launcher.html">Launcher Icons</a></strong></dt>
+  <dd>A Launcher icon is a graphic that represents your application on the
+  device's Home screen and in the Launcher window.</dd>
+  <dt><strong><a href="icon_design_menu.html">Menu Icons</a></strong></dt>
+  <dd>Menu icons are graphical elements placed in the options menu shown to
+  users when they press the Menu button.</dd>
+  <dt><strong><a href="icon_design_status_bar.html">Status Bar Icons</a></strong></dt>
+  <dd>Status bar icons are used to represent notifications from your
+  application in the status bar.</dd>
+  <dt><strong><a href="icon_design_tab.html">Tab Icons</a></strong></dt>
+  <dd>Tab icons are graphical elements used to represent individual tabs in a
+  multi-tab interface.</dd>
+  <dt><strong><a href="icon_design_dialog.html">Dialog Icons</a></strong></dt>
+  <dd>Dialog icons are shown in pop-up dialog boxes that prompt the user for
+  interaction.</dd>
+  <dt><strong><a href="icon_design_list.html">List View Icons</a></strong></dt>
+  <dd>List view icons are used with {@link android.widget.ListView} to
+  graphically represent list items. An example is the Settings application.</dd>
+</dl>
+
 <p>To get started creating your icons more quickly, you can download 
-the Android Icon Templates Pack. For more information, see 
-<a href="#templatespack">Using the Android Icon Template Pack</a>.</p>
+the Android Icon Templates Pack.</p>
+
+
+
+
+
+<h2 id="templatespack">Using the Android Icon Templates Pack</h2>
+
+<p>The Android Icon Templates Pack is a collection of template designs,
+textures, and layer styles that make it easier for you to create icons that
+conform to the guidelines given in this document. We recommend downloading the
+template pack archive before you start designing your icons.</p>
+
+<p>The icon templates are provided in the Adobe Photoshop file format (.psd),
+which preserves the layers and design treatments we used when creating the
+standard icons for the Android platform. You can load the template files into
+any compatible image-editing program, although your ability to work directly
+with the layers and treatments may vary based on the program you are using.</p>
+
+<p>You can obtain the latest Icon Templates Pack archive using the link below:
+</p>
+
+<p style="margin-left:2em"><a
+href="{@docRoot}shareables/icon_templates-v2.3.zip">Download the Icon Templates
+Pack for Android 2.3 &raquo;</a>
+
+<p>For previous versions of the Icon Templates Pack, see the <em>Downloads</em>
+section in the box at the top-right corner of this page.</p>
+
+
+
 
 
 <h2 id="icon-sets">Providing Density-Specific Icon Sets</h2>
@@ -89,7 +134,7 @@
 regardless of the device's screen size or resolution.</p>
 
 <p>In general, the recommended approach is to create a separate set of icons for
-each of the three generalized screen densities listed in Table 1, below, then
+each of the three generalized screen densities listed in Table 1. Then,
 store them in density-specific resource directories in your application. When
 your application runs, the Android platform will check the characteristics of
 the device screen and load icons from the appropriate density-specific
@@ -98,59 +143,27 @@
 href="{@docRoot}guide/practices/screens_support.html#qualifiers">Resource
 directory qualifiers for screen size and density</a>. </p>
 
-<p>The baseline screen density for Android devices is medium
-(<code>mdpi</code>). For this reason, a recommended approach to creating icon
-sets for multiple screen densities is to:</p>
-
-<ol>
-<li>Design the icons for the baseline density first (see Table 1 for the actual
-pixel dimensions at which to design the icons). </li>
-<li>Place the icons in the application's default drawable resources, then run
-the application on an Android Virtual Device (AVD) or an HVGA device such as the
-T-Mobile G1. </li>
-<li>Test and adjust your baseline icons as needed.</li>
-<li>When you are satisfied with the icons you've developed at the baseline
-density, create scaled copies for the other densities. 
-
-<ul>
-<li>Scale the baseline icons up 150% to create the high-density assets.</li>
-<li>Scale the baseline icons down 75% to create the low-density assets.</li>
-</ul></li>
-
-<li>Place the icons in density-specific resource directories in your
-application. For example:
-<ul>
-<li>Medium-density assets go in a <code>res/drawable-mdpi/</code>
-directory (or in the default <code>res/drawable/</code> directory),</li>
-<li>High-density assets go in a <code>res/drawable-hdpi/</code> directory,
-and</li>
-<li>Low-density assets go in a <code>res/drawable-ldpi/</code>
-directory.</li>
-</ul></li>
-<li>Test and adjust the high- and low-density icons if needed</li>
-</ol>
-
 <p>For tips on how to create and manage icon sets for multiple densities, see 
-<a href="#design_tips">Tips for Designers</a>.</p>
+<a href="#design-tips">Tips for Designers</a>.</p>
 
-<p class="caption" id="screens-table"><strong>Table 1.</strong> Summary of
+<p class="table-caption" id="screens-table"><strong>Table 1.</strong> Summary of
 finished icon dimensions for each of the three generalized screen densities, by
 icon type.</p>
 
-  <table style="margin-top:2em;">
+  <table>
     <tbody>
 <tr>
 <th>Icon Type</th><th colspan="3">Standard Asset Sizes (in Pixels), for
 Generalized Screen Densities</th></tr>
     <tr>
-      <td></td>
+      <td style="background-color:#f3f3f3"></td>
       <th style="background-color:#f3f3f3;font-weight:normal">
         <nobr>Low density screen <em>(ldpi)</em></nobr>
       </th>
       <th style="background-color:#f3f3f3;font-weight:normal">
         <nobr>Medium density screen <em>(mdpi)</em></nobr>
       </th>
-      <th  style="background-color:#f3f3f3;font-weight:normal">
+      <th style="background-color:#f3f3f3;font-weight:normal">
         <nobr>High density screen <em>(hdpi)</em><nobr>
       </th>
     </tr>
@@ -159,14 +172,14 @@
       <th style="background-color:#f3f3f3;font-weight:normal">
         Launcher
       </th>
-      <td style="font-size:.9em;">
+      <td>
           36 x 36 px
       </td>
 
-      <td style="font-size:.9em;">
+      <td>
          48 x 48 px
       </td>
-      <td style="font-size:.9em;">
+      <td>
           72 x 72 px
       </td>
     </tr>
@@ -175,1057 +188,113 @@
       <th style="background-color:#f3f3f3;font-weight:normal">
         Menu
       </th>
-      <td style="font-size:.9em;">
+      <td>
           36 x 36 px
       </td>
 
-      <td style="font-size:.9em;">
+      <td>
          48 x 48 px
       </td>
-      <td style="font-size:.9em;">
+      <td>
           72 x 72 px
       </td>
     </tr>
 
     <tr>
       <th style="background-color:#f3f3f3;font-weight:normal">
-        Status Bar
+        Status Bar (Android 2.3 and later)
       </th>
-      <td style="font-size:.9em;">
-          24 x 24 px
+      <td>
+        12w x 19h px<br>
+        (preferred, width may vary)
       </td>
 
-      <td style="font-size:.9em;">
-         32 x 32 px
+      <td>
+        16w x 25h px<br>
+        (preferred, width may vary)
       </td>
-      <td style="font-size:.9em;">
-          48 x 48 px
+      <td>
+         24w x 38h px<br>
+        (preferred, width may vary)
       </td>
     </tr>
+
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        Status Bar (Android 2.2 and below)
+      </th>
+      <td>
+          19 x 19 px
+      </td>
+
+      <td>
+         25 x 25 px
+      </td>
+      <td>
+          38 x 38 px
+      </td>
+    </tr>
+
     <tr>
       <th style="background-color:#f3f3f3;font-weight:normal">
         Tab
       </th>
-      <td style="font-size:.9em;">
+      <td>
           24 x 24 px
       </td>
 
-      <td style="font-size:.9em;">
+      <td>
          32 x 32 px
       </td>
-      <td style="font-size:.9em;">
+      <td>
           48 x 48 px
       </td>
     </tr>
+
     <tr>
       <th style="background-color:#f3f3f3;font-weight:normal">
         Dialog
       </th>
-      <td style="font-size:.9em;">
+      <td>
           24 x 24 px
       </td>
 
-      <td style="font-size:.9em;">
+      <td>
          32 x 32 px
       </td>
-      <td style="font-size:.9em;">
+      <td>
           48 x 48 px
       </td>
     </tr>
+
     <tr>
       <th style="background-color:#f3f3f3;font-weight:normal">
         List View
       </th>
-      <td style="font-size:.9em;">
+      <td>
           24 x 24 px
       </td>
 
-      <td style="font-size:.9em;">
+      <td>
          32 x 32 px
       </td>
-      <td style="font-size:.9em;">
+      <td>
           48 x 48 px
       </td>
     </tr>
     </tbody>
   </table>
 
-<h2 id="launcherstructure">Launcher Icon</h2>
 
-<p>A Launcher icon is a graphic that represents your application on the device’s
-Home screen and in the Launcher window.  </p>
 
-<p>The user opens the Launcher by touching the icon at the bottom of the Home
-screen. The Launcher opens and exposes the icons for all of the installed 
-applications, which are arranged in a grid. The user selects an application and 
-opens it by touching the Launcher icon or by means of any hardware navigation 
-controls available, such as a trackball or d-pad. </p>
 
-<p>The user can also drag an icon out of the Launcher window and onto the Home
-screen itself, for more convenient access to the application. In this case, the
-system displays your application's Launcher icon against the Home screen
-wallpaper, rendering it at the same dimensions as it is rendered inside the
-Launcher.</p>
-
-<p>The system manages the scaling of all Launcher icons so that they rendered at
-a uniform height and width. The actual pixel dimensions of the rendered Launcher
-icons on any given device varies, based on the size and pixel-density
-characteristics of the device's screen. To ensure the best possible rendering
-for your icons, supply versions of the icons that are designed for low, medium,
-and high density screens. For information, see <a
-href="#icon_sets">Providing Density-Specific Icon Sets</a>, above, or <a
-href="#design_tips">Tips for Designers</a>, below.</p>
-
-<h3 id="style">Style</h3>
-
-<p>The launcher icons that you create should follow the general style principles
-below. The guidelines aren't meant to restrict what you can do with your icons,
-but rather they are meant to emphasize the common approaches that your icons can
-share with others on the device. Figure 1, at right, provides examples.  </p>
-
-<div class="figure" style="padding:3em">
-  <img src="{@docRoot}images/icon_design/IconGraphic_Icons_i.png" 
-    width="340">
-  <p class="caption" style="margin:0;padding:0;margin-left:36px;">
-  <strong>Figure 1.</strong> Illustration of Launcher icon style.</p>
-</div>
-
-<p>Clean and contemporary:</p>
-
-<ul>
-  <li>Launcher icons should be current and sometimes quirky, but they should not
-appear aged or ragged. You should avoid overused symbolic metaphors whenever
-possible.</li>
-</ul>
-
-<p>Simple and iconic:</p>
-<ul>
-  <li> Android Launcher icons are caricatural in nature; your icons should be
-highly simplified and exaggerated, so that they are appropriate for use at small
-sizes. Your icons should not be overly complicated. </li>
-  <li>Try featuring a single part of an application as a symbolic
-representation of the whole (for example, the Music icon features a speaker).
-</li>
-  <li>Consider using natural outlines and shapes, both geometric and organic,
-with a realistic (but never photorealistic) rendering. </li>
-  <li>Your icons <em>should not</em> present a cropped view of a larger
-image.</li>
-</ul>
-
-<p>Tactile and textured:</p>
-<ul>
-  <li>Icons should feature non-glossy, textured material. See
-  <a href="#materials-colors">Materials and colors</a>, below, for more
-  information.</li>
-</ul>
-
-<p>Forward-facing and top-lit:</p>
-<ul>
-  <li><em>New for Android 2.0 and later platforms</em>: Android Launcher
-icons should be forward-facing, with very little perspective, and they
-should be top-lit.</li>
-</ul>
-
-Additionally, note all icons will have separate text labels, so rather than
-working to include embedded text in the design of of your icons, focus your
-efforts on the icon's visual distinctiveness and memorability instead.</p>
-
-<p>To look at more examples of the Launcher icons used by built-in Android
-applications, see <a href="#launcherapx">Standard Launcher Icons</a> in the
-Icons Appendix of this document. </p>
-
-
-
-<h3 id="dodonts">Do's and Don'ts</h3>
-
-<p>Below are some "do and don't" examples to consider when creating icons for
-your application.  </p>
-
-
-<table>
-<tr>
-<td style="border:0;width:50%;">
-
-<h4>Android Launcher icons are...</h4>
-
-<ul>
-<li>Modern, minimal, matte, tactile, and textured</li>
-<li>Forward-facing and top-lit, whole, limited in color
-palette</li>
-</ul>
-</td>
-<td style="border:0;width:50%;">
-
-<h4>Android Launcher icons are not...</h4>
-
-<ul>
-<li>Antique, over-complicated, glossy, flat vector</li>
-<li>Rotated, Cropped, Over-Saturated</li>
-</ul>
-</td>
-</tr>
-<tr>
-</table>
-
-<div style="margin-left:2em">
-<img src="{@docRoot}images/icon_design/IconGraphic_DosDonts.png" alt="Side-by-side examples
-of good/bad icon design." />
-<p class="caption" style="margin-top:.5em;">
-<strong>Figure 2.</strong> Side-by-side examples of "do's and don'ts" for
-Android launcher icons. </p>
-</div>
-
-<h3 id="materials-colors">Materials and colors</h3>
-
-<p>Launcher icons should make use of tactile, top-lit, textured materials. Even
-if your icon is just a simple shape, you should try to render in a way that
-makes it appear to be sculpted from some real-world material.</p>
-
-<p>The Launcher icons for the platform's default applications use the set of
-materials shown in Figure 3, below. Your icons can use these materials or you
-can create new materials.</p>
-
-<p>Android launcher icons usually consist of a smaller shape within a
-larger base shape and combine one neutral and one primary color. Icons may
-use a combination of neutral colors but should maintain a fairly high level of
-contrast. Icons should not use more than one primary color per icon, if
-possible.</p>
-
-<p>Launcher icons should use a limited color palette that includes a range
-of neutral and primary colors. The icons should not be over-saturated.</p>
-
-<p>The recommended color palette to use for Launcher icons is shown in Figure 4.
-You can use elements of the palette for both the base color and the highlight
-color. You can use the colors of the palette in conjunction with a
-white-to-black vertical linear gradient overlay. This creates the impression
-that the icon is lit from above and keeps the color less saturated.</p>
-
-
-
-<div style="margin:2em">
-<img src="{@docRoot}images/icon_design/IconGraphic_Materials.png" width="450" style="padding-top:2px;">
-<p class="caption" style="margin-top:.5em;">
-<strong>Figure 3.</strong> Example materials that you can use to create
-your icons.</p>
-</div>
-
-<div style="margin:2em">
-<img src="{@docRoot}images/icon_design/IconGraphic_AccentColor.png" width="450">
-<p class="caption" xstyle="margin-top:.5em;">
-<strong>Figure 4.</strong> Examples of materials combined with base
-and highlight colors from the recommended palette.</p>
-</div>
-
-
-<p>When you combine the materials above with a color highlight from the
-recommended pallete, you can create materials combinations such as those shown
-in Figure 5. To get you started, the <a href="#templatespack">icons pack</a>
-includes a Photoshop template file (<code>Launcher-icon-template.psd</code>)
-that provides all of the default materials, colors, and gradients. </p>
-
-<div style="margin:2em">
-<img src="{@docRoot}images/icon_design/IconGraphic_Colors.png" width="450" style="padding-top:2px;">
-<p class="caption" style="margin-top:.5em;">
-<strong>Figure 5.</strong> Recommended color palette for icons.</p>
-</div>
-
-
-<h3 id="size">Size and positioning</h3>
-
-<p>Launcher icons should use a variety of shapes and forms and those must be
-scaled and positioned to create consistent visual weight.</p>
-
-<p>Launcher icons should use a variety of shapes and forms and those must be
-scaled and positioned inside the asset to create consistent visual weight with
-other </p>
-
-<p>Figure 6 illustrates various ways of positioning the icon inside the asset.
-As detailed in the table below, you should size the icons <em>smaller than the
-actual bounds of the asset</em>, to create a consistent visual weight and to
-allow for the inclusion of shadows. If your icon is square or nearly square, it
-should be scaled even smaller.</p>
-
-
-<ul>
-<li>The bounding box for the full asset is shown in red.</li>
-<li>The recommended bounding box for the actual icon itself is shown in blue.
-The icon box is sized smaller than the full asset box so that there is space to
-include shadows and special icon treatments. </li>
-<li>The recommended bounding box for an icon that is square is shown in orange.
-The box for square icons is smaller than that for other icons to establish a
-consistent visual weight across the two types.</li>
-</ul>
-
-<table style="margin:2.5em 0 1em 0;">
-<tr>
-
-<td style="border:0;padding-left:72;">
-<ol class="nolist">
-  <li>Icon dimensions for high-density (<code>hdpi</code>) screens:</li>
-  <ol class="nolist">
-    <li>Full Asset: 72 x 72 px</li>
-    <li>Icon: 60 x 60 px</li>
-    <li>Square Icon: 56 x 56 px</li>
-  </ol>
-  </li>
-</ol>
-</td>
-<td style="border:0;">
-  <img src="{@docRoot}images/icon_design/IconGraphic_OpticalSize_l.png"
-   style="padding:0;margin:0;" width="450">
-</td>
-</tr>
-<tr>
-<td style="border:0;">
-  <ol class="nolist">
-  <li>Icon Dimensions for medium-density (<code>mdpi</code>) screens:</li>
-    <ol class="nolist">
-      <li>Full Asset: 48 x 48 px</li>
-      <li>Icon: 40 x 40 px</li>
-      <li>Square Icon: 38 x 38 px</li>
-    </ol>
-  </li>
-</ol>
-</td>
-
-<td style="border:0;padding-left:72;">
- <img src="{@docRoot}images/icon_design/IconGraphic_OpticalSize_s.png"
- style="padding:0;margin:0;" width="450">
-</td>
-</tr>
-<tr>
-<td style="border:0;">
-  <ol class="nolist">
-  <li>Icon Dimensions for low-density (<code>ldpi</code>) screens:</li>
-    <ol class="nolist">
-      <li>Full Asset: 36 x 36 px</li>
-      <li>Icon: 30 x 30 px</li>
-      <li>Square Icon: 28 x 28 px</li>
-    </ol>
-  </li>
-</ol>
-</td>
-
-<td style="border:0;padding-left:72;">
- <img src="{@docRoot}images/icon_design/IconGraphic_OpticalSize_ldpi.png"
- style="padding:0;margin:0;" width="450">
-
- <p class="caption" style="margin:0;padding:0;margin-top:1.5em;"><strong>Figure
- 6.</strong> Icon sizing and positioning inside the bounds of the
- icon asset.</p>
-</td>
-</tr>
-
-</table>
-
-
-
-<h3>Using the Launcher Icon Template</h3>
-
-<p>Included in the Android Icon Templates Pack 2.0 is a template containing
-palettes for default icon materials and colors. The template is provided in .psd
-format for Adobe Photoshop or similar raster image editor. </p>
-
-<p>To get started, first <a
-href="{@docRoot}shareables/icon_templates-v2.0.zip">download the Android Icon
-Templates Pack 2.0 &raquo;</a>. </p>
-
-<p>Once you've downloaded the pack, unzip it and open the file
-<code>Launcher-icon-template.psd</code> in Adobe Photoshop or similar raster
-image editing program. Notice the palettes for materials and colors.  You can
-use as the template as a starting point for creating your Launcher icons. </p>
-
-<p>After you create your icon, you can add a shadow effect according to the
-specification below, as appropriate for the size of image you are creating. </p>
-
-
-<table style="margin:2.5em 0 1em 0;">
-<tr>
-
-<td style="border:0;padding-left:72;">
-  <img src="{@docRoot}images/icon_design/IconGraphic_Shadow_WVGA.png"
-   style="padding:0;margin:0;" width="450">
-</td>
-<td style="border:0;">
-<p style="padding-top:.5em;">Shadow for WVGA (high density) sreens:</p>
-  <ol class="nolist">
-    <li>Effect: Drop Shadow</li>
-    <li>Color: #000000</li>
-    <li>Blend Mode: Multiply</li>
-    <li>Opacity: 75%</li>
-    <li>Angle: 90°</li>
-    <li>Distance: 2px</li>
-    <li>Spread: 0% </li>
-    <li>Size: 5px </li>
-  </ol>
-</li>
-</ol>
-</td>
-</tr>
-<tr>
-<td style="border:0;padding-left:72;">
-  <img src="{@docRoot}images/icon_design/IconGraphic_Shadow_HVGA.png"
-   style="padding:0;margin:0;" width="450">
-</td>
-
-<td style="border:0;">
-<p style="padding-top:.5em;">Shadow for HVGA (medium density) sreens:</p>
-  <ol class="nolist">
-    <li>Effect: Drop Shadow</li>
-    <li>Color: #000000</li>
-    <li>Blend Mode: Multiply</li>
-    <li>Opacity: 75%</li>
-    <li>Angle: 90°</li>
-    <li>Distance: 1px</li>
-    <li>Spread: 0% </li>
-    <li>Size: 3px </li>
-  </ol>
-</li>
-</ol>
-</td>
-</tr>
-</table>
-
-<p>When the shadow is added and the icon is complete, export it as a PNG file
-with transparency enabled, ensuring that you size the icon at 72 x 72px for
-high-density screens and 48 x 48px for medium density screens. For more
-information about why you should provide different Launcher assets for high-,
-medium, and low-density screens, see <a
-href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a>.</p>
-
-
-
-<h2 id="menustructure">Menu icon</h2>
-
-<p>Menu icons are graphical elements placed in the pop-up menu shown to users
-when they press the Menu button. They are drawn in a flat-front perspective.
-Elements in a menu icon must not be visualized in 3D or perspective.</p>
-
-<p>As described in <a href="#icon-sets">Providing Density-Specific Icon
-Sets</a>, above, you should create separate icon sets for low-, normal, and
-high-density screens. This ensures that your icons will display properly across
-the range of devices on which your application can be installed. See <a
-href="#screens-table">Table 1</a> for a listing of the recommended finished icon
-sizes for each density. Also, see <a href="#design-tips">Tips for Designers</a>
-for suggestions on how to work with multiple sets of icons.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>In order to maintain consistency, all menu icons must use the same
-primary palette and the same effects. For more information, see the
-menu icon <a href="#menupalette">color palette</a>. </li>
-
-<li>Menu icons should include rounded corners, but only when logically
-appropriate. For example, in Figure 7 the logical place for rounded corners is
-the roof and not the rest of the building.</span></li>
-
-<li>All dimensions specified on this page are based on a 48x48 pixel artboard 
-size with a 6 pixel safeframe.</li>
-
-<li>The menu icon effect (the outer glow) described in <a
-href="#menulight">Light, effects, and shadows</a> can overlap the 6px safeframe,
-but only when necessary. The base shape must always stay inside the
-safeframe.</li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating menu icons in Adobe Photoshop are available in the 
-Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/menu_structure.png" alt="A view of menu
-icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 7. </strong>Safeframe and corner-rounding for menu
-icons. Icon size is 48x48.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<h4 id="menulight">Light, effects, and shadows</h4>
-
-<p>Menu icons are flat and pictured face on. A slight deboss and some other
-effects, which are shown below, are used to create depth.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/menu_light.png" alt="A view of light, effects, and shadows for menu icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 8. </strong>Light, effects, and shadows for menu icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20 % opacity<br>angle 90° | distance 2px<br>size 2px</td></tr>
-    <tr><td><em>3.</em></td><td>Outer glow:</td><td>white | 55% opacity <br>spread 10% | size 3px</td></tr>
-    <tr><td><em>5.</em></td><td>Inner bevel:</td><td>depth 1% | direction down size 0px<br>angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menupalette">Color palette</h4>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for outer glow and bevel highlight.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png" alt="Color palette, medium gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for inner shadow and bevel shadow.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
-of 48x48 px on a transparent background. Mind the safeframe.</li>
-<li>Add the effects seen as described in Figure 8.</li>
-<li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-<h4 id="dodonts_menu">"Do's and don'ts"</h4>
-
-<p>Below are some "do and don't" examples to consider when creating menu icons for
-your application. </p>
-
-
-<img src="{@docRoot}images/icon_design/do_dont_menuicons.png" style="padding:0;margin:0;padding-right:30%" width="400">
-
-
-<h2 id="statusbarstructure">Status bar icon</h2>
-
-<p>Status bar icons are used to represent notifications from your application in
-the status bar. Graphically, they are very similar to menu icons, but are
-smaller and higher in contrast.</p>
-
-<p>As described in <a href="#icon-sets">Providing Density-Specific Icon
-Sets</a>, above, you should create separate icon sets for low-, normal, and
-high-density screens. This ensures that your icons will display properly across
-the range of devices on which your application can be installed. See <a
-href="#screens-table">Table 1</a> for a listing of the recommended finished icon
-sizes for each density. Also, see <a href="#design-tips">Tips for Designers</a>
-for suggestions on how to work with multiple sets of icons.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>Rounded corners must always be applied to the base shape and to the details
-of a status bar icon shown Figure 9.</li>
-
-<li>All dimensions specified are based on a 25x25 pixel artboard size with a 2
-pixel safeframe.</li>
-
-<li>Status bar icons can overlap the safeframe to the left and right when
-necessary, but must not overlap the safeframe at the top and bottom.</li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating status bar icons using Adobe Photoshop are available
-in the Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/statusbar_structure.png" alt="A view of
-status bar icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 9. </strong>Safeframe and corner-rounding for status bar
-icons. Icon size is 25x25.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<h4 id="statusbarlight">Light, effects, and shadows</h4>
-
-<p>Status bar icons are slightly debossed, high in contrast, and pictured
-face-on to enhance clarity at small sizes.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/statusbar_light.png" alt="A view of
-light, effects, and shadows for status bar icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 10. </strong>Light, effects, and shadows for status bar icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
-    <tr><td><em>2.</em></td><td>Inner bevel:</td><td>depth 100% | direction down<br>size 0px | angle 90° |<br>altitude 30°<br>highlight white 75% opacity<br>shadow black 75% opacity</td></tr>
-    <tr><td><em>3.</em></td><td>Detail:</td><td>white</td></tr>
-    <tr><td><em>4.</em></td><td>Disabled detail:</td><td>grey gradient from palette<br>+ inner bevel: smooth | depth 1% | direction down | size 0px | angle 117° | <br>altitude 42° | highlight white 70% | no shadow</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menupalette">Color palette</h4>
-
-<p>Only status bar icons related to the phone function use full color; all other status bar icons should remain monochromatic.</p>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for details within the icons and bevel highlight.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Grey gradient<br><em>1:&nbsp;&nbsp;</em>r 169 | g 169 | b 169<br><em>2:&nbsp;&nbsp;</em>r 126 | g 126 | b 126<br>Used for disabled details within the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>1 r 105 | g 105 | b 105<br><em>2:&nbsp;&nbsp;</em>r 10   | g 10   | b 10<br>Used as color fill.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for bevel shadow.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>In a tool like Adobe Photoshop, create the base shape within a 25x25 px
-image on a transparent background. Mind the safeframe, and keep the upper and
-lower 2 pixels free.</li>
-<li>Add rounded corners as specified in Figure 9.</li>
-<li>Add light, effects, and shadows as specified in Figure 10.</li>
-<li>Export the icon at 25x25 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h4 id="dodonts_status">"Do's and don'ts"</h4>
-
-<p>Below are some "do and don't" examples to consider when creating status bar icons for
-your application. </p>
-
-
-<img src="{@docRoot}images/icon_design/do_dont_statusicons.png" style="padding:0;margin:0;padding-right:30%" width="400">
-
-
-
-<h2 id="tabstructure">Tab icon</h2>
-
-<p>Tab icons are graphical elements used to represent individual tabs in a
-multi-tab interface. Each tab icon has two states: unselected and selected.</p>
-
-<p>As described in <a href="#icon-sets">Providing Density-Specific Icon
-Sets</a>, above, you should create separate icon sets for low-, normal, and
-high-density screens. This ensures that your icons will display properly across
-the range of devices on which your application can be installed. See <a
-href="#screens-table">Table 1</a> for a listing of the recommended finished icon
-sizes for each density. Also, see <a href="#design-tips">Tips for Designers</a>
-for suggestions on how to work with multiple sets of icons.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>Unselected tab icons have the same fill gradient and effects as menu icons,
-but with no outer glow.</li>
-
-<li>Selected tab icons look just like unselected tab icons, but with a fainter
-inner shadow, and have the same front part gradient as dialog icons.</li>
-
-<li>Tab icons have a 1 px safeframe which should only be overlapped for the edge
-of the anti-alias of a round shape.</li>
-
-<li>All dimensions specified on this page are based on a 32x32 px artboard size.
-Keep 1 px of padding around the bounding box inside the Photoshop template.</li>
-
-<li><strong>Final art must be exported as a 32x32 px transparent PNG
-file.</strong></li>
-
-<li>Templates for creating tab icons in Adobe Photoshop are available in the
-Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/tab_icon_unselected.png" alt="A view of
-unselected tab icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 11. </strong>Safeframe and fill gradient for unselected tab
-icons. Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/tab_icon_selected.png" alt="A view of
-selected tab icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 12. </strong>Safeframe and fill gradient for tab icons in
-selected state. Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-<h3 id="unselectedtabdetails">Unselected tab icon</h3>
-
-<h4 id="unselectedtablight">Light, effects, and shadows</h4>
-
-<p>Unselected tab icons look just like the selected tab icons, but with a
-fainter inner shadow, and the same front part gradient as the dialog icons.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/tab_unselected_light.png" alt="A view
-of light, effects, and shadows for unselected tab icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 13. </strong>Light, effects, and shadows for unselected
-tab icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom color: r 223 | g 223 | b 223<br>top color: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 10 % opacity | angle 90° distance 2px | size 2px</td></tr>
-    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape to a tool like Adobe Photoshop and scale to fit an image of
-32x32 px on a transparent background.</li>
-<li>Add the effects seen in Figure 13 for the unselected state filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-<h3 id="selectedtabdetails">Selected tab icon</h3>
-
-<p>The selected tab icons have the same fill gradient and effects as the menu
-icon, but with no outer glow.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/tab_selected_light.png" alt="A view of
-light, effects, and shadows for selected tab icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 14. </strong>Light, effects, and shadows for selected tab
-icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from color palette.</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20% opacity | <br>angle 90° | distance 2px | <br>size 2px</td></tr>
-    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | <br>altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menupalette">Color palette</h4>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill on unselected tab icons.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shape using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit a 32x32
-px artboard with a transparent background. </li>
-<li>Add the effects seen in Figure 14 for the selected state filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="dialogstructure">Dialog icon</h2>
-
-<p>Dialog icons are shown in pop-up dialog boxes that prompt the user for
-interaction. They use a light gradient and inner
-shadow in order to stand out against a dark background.</p>
-
-<p>As described in <a href="#icon-sets">Providing Density-Specific Icon
-Sets</a>, above, you should create separate icon sets for low-, normal, and
-high-density screens. This ensures that your icons will display properly across
-the range of devices on which your application can be installed. See <a
-href="#screens-table">Table 1</a> for a listing of the recommended finished icon
-sizes for each density. Also, see <a href="#design-tips">Tips for Designers</a>
-for suggestions on how to work with multiple sets of icons.</p>
-<h4>Structure</h4>
-
-<ul>
-<li>Dialog icons have a 1 pixel safeframe. The base shape must fit within the
-safeframe, but the anti-alias of a round shape can overlap the safeframe. <span
-class="body-copy"></li>
-
-<li>All dimensions specified on this page are based on a 32x32 pixel artboard size
-in Adobe Photoshop. Keep 1 pixel of padding around the bounding box inside the
-Photoshop template.</li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating dialog icons in Adobe Photoshop are available in the
-Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/dialog_icon.png" alt="A view of dialog
-icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 15. </strong>Safeframe and fill gradient for dialog icons.
-Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<h4 id="dialoglight">Light, effects, and shadows</h4>
-
-<p>Dialog icons are flat and pictured face-on. In order to stand out against a
-dark background, they are built up using a light gradient and inner shadow.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/dialog_light.png" alt="A view of light,
-effects, and shadows for dialog icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 16. </strong>Light, effects, and shadows for dialog
-icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom: r 223 | g 223 | b 223<br>top: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 25% opacity | <br>angle -90° | distance 1px | size 0px</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
-of 32x32 px on a transparent background. </li>
-<li>Add the effects seen in Figure 16 for the proper filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="listviewstructure">List view icon</h2>
-
-<p>List view icons look a lot like dialog icons, but they use an inner shadow
-effect where the light source is above the object. They are also designed to be
-used only in a {@link android.widget.ListView}. Examples include the Android 
-Market application home screen and the driving directions screen in the Maps
-application.</p>
-
-<p>As described in <a href="#icon-sets">Providing Density-Specific Icon
-Sets</a>, above, you should create separate icon sets for low-, normal, and
-high-density screens. This ensures that your icons will display properly across
-the range of devices on which your application can be installed. See <a
-href="#screens-table">Table 1</a> for a listing of the recommended finished icon
-sizes for each density. Also, see <a href="#design-tips">Tips for Designers</a>
-for suggestions on how to work with multiple sets of icons.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>A list view icon normally has a 1 px safeframe, but it is OK to use the
-safeframe area for the edge of the anti-alias of a round shape. </li>
-
-<li>All dimensions specified are based on a 32x32 pixel artboard size in
-Photoshop. Keep 1 pixel of padding around the bounding box inside the template.
- </li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating list view icons in Adobe Photoshop are available in
-the Icon Templates Pack. </li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/listview_icon.png" alt="A view of list
-view icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 17. </strong>Safeframe and fill gradient for list view
-icons. Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-<h4 id="listviewlight">Light, effects, and shadows</h4>
-
-<p>List view icons are flat and pictured face-on with an inner shadow. Built up
-by a light gradient and inner shadow, they stand out well on a dark
-background.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/listview_icon_details.png" alt="A view
-of light, effects, and shadows for list view icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 18. </strong>Light, effects, and shadows for list view
-icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Inner shadow:</td><td>black | 57 % opacity | angle 120° | blend mode normal | distance 1px | size 1px <td></tr>
-    <tr><td><em>2.</em></td><td>Background:</td><td>black | standard system color <br>These icons are displayed in list views only.</td></tr>
-    <tr><td colspan="2">Note: The list view icon sits on 32x32 px artboard in Photoshop, without a safeframe.</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Add the effects seen in Figure 18 for the proper filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
-of 32x32 px on a transparent background. </li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-<h2 id="design_tips">Tips for Designers</h2>
+<h2 id="design-tips">Tips for Designers</h2>
 
 <p>Here are some tips that you might find useful as you develop icons or other
 drawable assets for your application. The tips assume that you are using
-Photoshop or similar raster image-editing program.</p>
+Adobe Photoshop or a similar raster and vector image-editing program.</p>
 
-<h4>Use common naming conventions for icon assets</h4>
+<h3>Use common naming conventions for icon assets</h3>
 
 <p>Try to name files so that related assets will group together inside a
 directory when they are sorted alphabetically. In particular, it helps to use a
@@ -1254,7 +323,7 @@
 </tr>
 <tr>
 <td>Status bar icons</td>
-<td><code>ic_stat_sys</code> or <code>ic_stat_notify</code></td>
+<td><code>ic_stat_notify</code></td>
 <td><code>ic_stat_notify_msg.png</code></td>
 </tr>
 <tr>
@@ -1273,12 +342,12 @@
 doing so is for your convenience only.</p>
 
 
-<h4>Set up a working space that organizes files for multiple densities</h4>
+<h3>Set up a working space that organizes files for multiple densities</h3>
 
-<p>Developing multiple sets of assets for different screen densities means
-creating multiple copies of files. To help keep the multiple copies of files
-safe and easier to find, we recommend creating a directory structure in your
-working space that organizes asset files per resolution. For example:</p>
+<p>Supporting multiple screen densities means you must create multiple versions
+of the same icon. To help keep the multiple copies of files safe and easier to
+find, we recommend creating a directory structure in your working space that
+organizes asset files per resolution. For example:</p>
 
 <pre>assets/...
     ldpi/...
@@ -1314,148 +383,57 @@
         <em>finished_asset</em>.png</pre>
 
 
-<h4>Create medium-density assets first</h4>
 
-<p>Since medium density is the baseline for Android, begin your designing work
-by creating the <code>mdpi</code> assets. See <a href="#screens-table">Table
-1</a>, above, for the actual pixel dimensions of various icon types. When
-possible, use vector art or paths within Photoshop layers so that it will be
-easier to scale the assets up or down later.</p>
+<h3>Use vector shapes where possible</h3>
 
-<p>For each discreet asset, or set of like assets that share the same bounding
-box dimensions, create a working Photoshop file and save it in the
-<code>_pre_production</code> directory. For example:
-<code>ic_tabs_phone_mdpi.psd</code>. This will make it easier to locate and edit
-individual assets if changes are required. It's also helpful to use a
-density-specific suffix in the filename for the working file, to avoid confusion
-when editing the files. For example: <code>_mdpi.psd</code>.</p>
+<p>Many image-editing programs such as Adobe Photoshop allow you to use a
+combination of vector shapes and raster layers and effects. When possible,
+use vector shapes so that if the need arises, assets can be scaled up without
+loss of detail and edge crispness.</p>
 
-<p>From the <code>mdpi</code> working files, save individual flattened assets to
-the corresponding density-specific resource directory (in this case,
-<code>mdpi/</code>) in your working space.</p>
+<p>Using vectors also makes it easy to align edges and corners to pixel
+boundaries at smaller resolutions.</li>
 
 
-<h4>Create high- and low-density assets from the medium-density sources</h4>
 
-<p>When you are finished working with your medium-density assets, copy the
-working files from the your workspace's <code>mdpi/_pre_production</code>
-directory to the corresponding locations in the <code>ldpi</code> and
-<code>hdpi</code> directories. If any of the working files use a
-density-specific suffix, rename the suffix to match the intended density.</p>
+<h3>Start with large artboards</h3>
 
-<p>Next, open each working file in the high- and low-density directories and
-scale the image up or down to match the intended density. To create an
-<code>hdpi</code> asset, scale the image by 150%. To create an <code>ldpi</code>
-asset, scale the image down by 75%. To scale the images, follow these steps:</p>
+<p>Because you will need to create assets for different screen densities, as
+shown in <a href="#screens-table">Table 1</a>, it is best to start your icon
+designs on large artboards with dimensions that are multiples of the target icon
+sizes. For example, <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design_launcher.html">launcher
+icons</a> are 72, 48, or 36 pixels wide, depending on screen density. If you
+initially draw launcher icons on an 864x864 artboard, it will be easier and
+cleaner to tweak the icons when you scale the artboard down to the target
+sizes for final asset creation.</p>
 
-<ol>
-<li>Open the working file in Photoshop or similar program.</li>
-<li>Under the <strong>Image</strong> menu, choose <strong>Image Size</strong>.</li>
-<li>On the Image Size panel, change the Width pop up menu to "percent."</li>
-<li>Change the Width value to "150" for <code>hdpi</code> assets and "75" for <code>ldpi</code> assets.</li>
-<li>Select the Scale Styles checkbox.</li>
-<li>Select the Constrain Proportions checkbox.</li>
-<li>Select the Resample Image checkbox and set the pop up menu to "Bicubic (Best for smooth gradients)."</li>
-<li>Click <strong>OK</strong>.</li>
-</ol>
+<p>It's also beneficial to add guide lines (also known as guides) to your large
+artboard for the recommended safe margins at the highest target density.
+Continuing with the example above, per the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design_launcher.html#size5">guidelines</a>,
+launcher icon content should be 60x60 pixels (56x56 for square icons) within the
+full 72x72 asset, or a safe margin of 6 pixels on each side. On an 864x864
+artboard, this corresponds to horizontal and vertical guide lines 72 pixels from
+each side of the artboard.</p>
 
-<p>After you scale each image, save it to the target density-specific resource
-directory.</p>
+  
 
-<p>If you are scaling a nine-patch image, see the section below for notes on how
-to handle the tick marks at the edge of the image. </p>
-
-
-<h4>After scaling, redraw bitmap layers as needed</h4>
+<h3>When scaling, redraw bitmap layers as needed</h3>
 
 <p>If you scaled an image up from a bitmap layer, rather than from a vector
-layer, those layers may need to be redrawn manually to accommodate the higher
-density. For example if a 60x60 circle was painted as a bitmap for
+layer, those layers will need to be redrawn manually to appear crisp at higher
+densities. For example if a 60x60 circle was painted as a bitmap for
 <code>mdpi</code> it will need to be repainted as a 90x90 circle for
 <code>hdpi</code>.</p>
 
 
-<h4>When scaling a nine-patch image, crop tick marks before scaling and replace
-them after</h4>
 
-<p>Nine-patch images include tick marks at the outer edge of the image. When you
-scale a nine-patch image, the tick marks are also scaled, which produces an
-inaccurate result. The recommended way to handle the scaling of nine-patch
-images is to remove the tick marks from the source image before scaling and then
-manually replace the tick marks at the proper size after scaling.</p>
+<h3>When saving image assets, remove unnecessary metadata</h3>
 
-<p>To more easily determine the tick marks after the working file has been
-scaled to a new resolution, first create a temporary duplicate flattened image
-which includes the tick marks: </p>
-
-<ol>
-<li>Under the <strong>Select</strong> menu choose <strong>All</strong>.</li>
-<li>Under the <strong>Edit</strong> menu choose 
-<strong>Copy Merged</strong>.</li>
-<li>Under the <strong>File</strong> menu choose <strong>New</strong> and then
-click <strong>OK</strong> on the new panel.</li>
-<li>Under the <strong>Edit</strong> choose <strong>Paste</strong>.</li>
-</ol>
-
-<p>After creating the temporary copy, go back to the working file and crop
-the tick marks out of the working file before scaling the image:</p>
-<ol>
-<li>Under the <strong>Image</strong> menu, choose the 
-<strong>Canvas Size</strong> command.</li>
-<li>On the Canvas Size panel, subtract 2 pixels from the Width and
-Height values.</li>
-<li>Set the Anchor to "Center."</li>
-<li>Click <strong>OK</strong></li>
-</ol>
-
-<p>Scale the working file to the target density. With the working file scaled
-and the canvas enlarged so that the tick marks can be repainted:</p>
-
-<ol>
-<li>Under the <strong>Image</strong> menu, choose the 
-<strong>Canvas Size</strong> command.</li>
-<li>On the <strong>Canvas Size</strong> panel, add 2 pixels to the Width
-and Height values.</li>
-<li>Set the Anchor to "Center."</li>
-<li>Click <strong>OK</strong>.</li>
-</ol>
-
-<p>To determine tick marks, go back to duplicate flattened image and scale it to
-the target resolution. </p>
-
-<p>Copy the scaled duplicate flattened image into a new layer in the working
-file to use as reference. Create a new layer in which to paint new tick marks at
-the single pixel outer edge of the image. Note tickmarks must be 100% opaque
-black, without transparency, and all other areas of the tick mark region must be
-100% transparent, otherwise the system will not interpret the nine-patch image
-correctly. </p>
-
-<p>Using the scaled duplicate flattened image as reference paint new tick marks
-in the new layer that align with the reference layer. Note round up pixels for
-tick marks. Any pixels that are partially opaque in the reference layer should
-be fully opaqe in the new layer.</p>
-
-
-<h4>Adjust stroke and drop shadow after scaling an image</h4>
-
-<p>While it is desirable to scale layer styles for the most part (such as for
-Gradient Overlay or Inner Glow), you may need to manually reset the Stroke and
-Drop Shadow in the scaled image to 1 px before saving, especially when scaling
-to <code>hdpi</code>.
-
-<h4>Save nine-patch images with the appropriate filename suffix</h4>
-
-<p>If an asset is a nine-patch asset (with tick marks), be sure to save the asset
-in PNG format with a filename that includes the <code>.9.png</code> suffix. If
-the filename does not use the suffix, the system won't recognize the image as a
-nine-patch asset and won't resize it as intended. </p>
-
-
-<h4>When saving image assets, remove the Photoshop header</h4>
-
-<p>To help keep each image asset as small as possible, make sure to remove the
-Photoshop headers from the file. To remove the Photoshop header, follow these
-steps: </p>
+<p>To help keep each image asset as small as possible, make sure to remove any
+unnecessary headers from the file, such as Adobe Fireworks metadata or Adobe
+Photoshop headers. To remove the Photoshop header, follow these steps: </p>
 
 <ol>
 <li>Under the <strong>File</strong> menu, choose the <strong>Save for Web &amp;
@@ -1466,250 +444,24 @@
 <li>Select <strong>Save</strong>.</li>
 </ol>
 
-<h4>Make sure that corresponding assets for different densities use the same
-filenames</h4>
+<p>It is also useful to use PNG file size optimization tools such as <a
+href="http://optipng.sourceforge.net/">OptiPNG</a> or <a
+href="http://pmt.sourceforge.net/pngcrush/">Pngcrush</a>.
 
-<p>Corresponding icon asset files for each density must use the same filename,
-but be stored in density-specific resource directories. This allows the system
-to look up and load the proper resource according to the screen characteristics 
-of the device. For this reason, make sure that the set of assets in each 
-directory is consistent and that the files do not use density-specific suffixes. 
-For more information about density-specific resources and how the system uses
-them to meet the needs of different devices, see <a 
+
+
+<h3>Make sure that corresponding assets for different densities use the same
+filenames</h3>
+
+<p>Corresponding icon asset files for each density <strong>must use the same
+filename</strong>, but be stored in density-specific resource directories. This
+allows the system to look up and load the proper resource according to the
+screen characteristics of the device. For this reason, make sure that the set of
+assets in each directory is consistent and that the files do not use
+density-specific suffixes.</p>
+
+<p>For more information about density-specific resources
+and how the system uses them to meet the needs of different devices, see <a
 href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
 Screens</a>.</p>
 
-<h2 id="templatespack">Using the Android Icon Templates Pack</h2>
-
-<p>The Android Icon Templates Pack is a collection of template designs, filters,
-and settings that make it easier for you to create icons that conform to the
-general specifications given in this document. We recommend downloading the
-template pack archive before you get started with your icon design.</p>
-
-<p>The icon templates are provided in Adobe Photoshop and Adobe Illustrator file
-formats, which preserves the layers and design treatments we used when creating the
-standard icons for the Android platform. You can load the template files into any 
-compatible image-editing program, although your ability to work directly with the 
-layers and treatments may vary based on the program you are using.</p>
-
-<p>You can obtain the Icon Templates Pack archive using the link below: </p>
-
-<p style="margin-left:2em"><a
-href="{@docRoot}shareables/icon_templates-v2.0.zip">Download the Icon Templates
-Pack &raquo;</a>
-
-
-<h2 id="iconappendix">Icon appendix</p>
-
-<h3 id="launcherapx">Standard launcher icons</h3>
-
-<p>Shown below are examples of launcher icons used by Android applications. The
-icons are provided for your reference only &mdash; please do not reuse these
-icons in your applications.</code>.
-
-<img src="{@docRoot}images/icon_design/IconGraphic_Icons.png" style="margin-top:2em;" />
-
-
-<h3 id="menuapx">Standard menu icons</h3>
-
-<p>Shown below are standard menu icons that are used in the Android
-system. Because these resources can change between platform versions, you 
-should not reference the system's copy of the resources. If you want
-use any icons or other internal drawable resources, you should store a
-local copy of those icons or drawables in your application resources, 
-then reference the local copy from your application code. In that way, you can
-maintain control over the appearance of your icons, even if the system's
-copy changes. Note that the list below is not intended to be complete.</p>
-
-
-<table class="image-caption">
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_add.png" title="ic_menu_add" alt="Android asset" />
-  <div class="caption">Add</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_call.png" title="ic_menu_call" alt="Android asset" />
-  <div class="caption">Call</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_camera.png" title="ic_menu_camera" alt="Android asset" />
-  <div class="caption">Camera</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_close_clear_cancel.png" title="ic_menu_close_clear_cancel" alt="Android asset" />
-  <div class="caption">Clear / Close / Cancel / Discard </div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_compass.png" title="ic_menu_compass" alt="Android asset" />
-  <div class="caption">Compass</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_delete.png" title="ic_menu_delete" alt="Android asset" />
-  <div class="caption">Delete</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_directions.png" title="ic_menu_directions" alt="Android asset" />
-  <div class="caption">Directions</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_edit.png" title="ic_menu_edit" alt="Android asset" />
-  <div class="caption">Edit</div></td>
-
-
-<td class="image-caption-i image-list">	
-  <img src="{@docRoot}images/icon_design/ic_menu_gallery.png" title="ic_menu_gallery" alt="Android asset" />
-  <div class="caption">Gallery</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_help.png" title="ic_menu_help" alt="Android asset" />
-  <div class="caption">Help</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_info_details.png" title="ic_menu_info_details" alt="Android asset" />
-  <div class="caption">Info / details</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_mapmode.png" title="ic_menu_mapmode" alt="Android asset" />
-  <div class="caption">Map mode</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_mylocation.png" title="ic_menu_mylocation" alt="Android asset" />
-  <div class="caption">My Location</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_more.png" title="ic_menu_more" alt="Android asset" />
-  <div class="caption">More</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_preferences.png" title="ic_menu_preferences" alt="Android asset" />
-  <div class="caption">Preferences</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_rotate.png" title="ic_menu_rotate" alt="Android asset" />
-  <div class="caption">Rotate</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_save.png" title="ic_menu_save" alt="Android asset" />
-  <div class="caption">Save</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_send.png" title="ic_menu_send" alt="Android asset" />
-  <div class="caption">Send</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_search.png" title="ic_menu_search" alt="Android asset" />
-  <div class="caption">Search</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_share.png" title="ic_menu_share" alt="Android asset" />
-  <div class="caption">Share</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_upload.png" title="ic_menu_upload" alt="Android asset" />
-  <div class="caption">Upload</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_view.png" title="ic_menu_view" alt="Android asset" />
-  <div class="caption">View</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_zoom.png" title="ic_menu_zoom" alt="Android asset" />
-  <div class="caption">Zoom</div></td>
-
-</tr>
-</table>
-
-
-<h3 id="statusbarapx">Standard status bar icons</h3>
-
-<p>Shown below are standard status bar icons that are used in the Android
-platform. Because these resources can change between platform versions, you 
-should not reference the system's copy of the resources. If you want
-use any icons or other internal drawable resources, you should store a
-local copy of those icons or drawables in your application resources, 
-then reference the local copy from your application code. In that way, you can
-maintain control over the appearance of your icons, even if the system's
-copy changes. Note that the list below is not intended to be complete.</p>
-
-
-<table class="image-caption">
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_data_bluetooth.png" title="stat_sys_data_bluetooth" alt="Android asset" />
-  <div class="caption">Bluetooth</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_email_generic.png" title="stat_notify_email_generic" alt="Android asset" />
-  <div class="caption">Email</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_chat.png" title="stat_notify_chat" alt="Android asset" />
-  <div class="caption">IM</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_voicemail.png" title="stat_notify_voicemail" alt="Android asset" />
-  <div class="caption">Voicemail</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_warning.png" title="stat_sys_warning" alt="Android asset" />
-  <div class="caption">Warning</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_phone_call.png" title="stat_sys_phone_call" alt="Android asset" />
-  <div class="caption">Call</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_phone_call_forward.png" title="stat_sys_phone_call_forward" alt="Android asset" />
-  <div class="caption">Call forward</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_phone_call_on_hold.png" title="stat_sys_phone_call_on_hold" alt="Android asset" />
-  <div class="caption">Call on hold</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_missed_call.png" title="stat_notify_missed_call" alt="Android asset" />
-  <div class="caption">Missed call</div></td>
-
-</tr>
-</table>
-
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_1.html b/docs/html/guide/practices/ui_guidelines/icon_design_1.html
new file mode 100644
index 0000000..183facf
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_1.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0;url=icon_design.html">
+<title>Redirecting...</title>
+</head>
+<body>
+<a href="icon_design.html">click here</a> if you are not redirected.
+</body>
+</html>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
deleted file mode 100644
index 995cfea..0000000
--- a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
+++ /dev/null
@@ -1,1205 +0,0 @@
-page.title=Icon Design Guidelines, Android 1.0
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>Quickview</h2>
-
-<ul>
-<li>You can use several types of icons in an Android application.</li>
-<li>Your icons should follow the specification in this document.</li>
-<li>A set of standard icons is provided by the Android platform. Your
-application can use the standard icons by referencing them as resources.</li>
-</ul>
-
-<h2>In this document</h2>
-
-<ol>
-<li><a href="#launcherstructure">Launcher icon</a></li>
-<li><a href="#menustructure">Menu icon</a></li>
-<li><a href="#statusbarstructure">Status bar icon</a></li>
-<li><a href="#tabstructure">Tab icon</a></li>
-<li><a href="#dialogstructure">Dialog icon</a></li>
-<li><a href="#listviewstructure">List view icon</a></li>
-
-<li style="margin-top:4px;"><a href="#dodonts">General guidelines</a></li>
-<li><a href="#templatespack">Using the Icon Templates Pack</a></li>
-<li><a href="#iconappendix">Icon appendix</a>
-	<ol>
-	<li><a href="#launcherapx">Launcher icons</a></li>
-	<li><a href="#menuapx">Menu icons</a></li>
-	<li><a href="#statusbarapx">Status bar icons</a></li>
-	</ol>
-</li>
-
-</ol>
-
-<h2>Downloads</h2>
-
-<ol>
-<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
-Templates Pack, v1.0 &raquo;</a></li>
-</ol>
-
-<h2>See also</h2>
-
-<ol>
-<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
-</ol>
-
-
-<h2>Newer versions</h2>
-
-<ol>
-<li style="margin-top:4px;"><a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon Design Guidelines, Android 2.0</a></li>
-<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
-Templates Pack, v2.0 &raquo;</a></li>
-</ol>
-
-</div>
-</div>
-
-<p>Creating a unified look and feel throughout a user interface adds value to
-your product. Streamlining the graphic style will also make the UI seem more
-professional to the user.</p>
-
-<p>This document shows you how to create icons for various parts
-of your application’s user interface that fit the style set by the Android UI
-team. Following these guidelines will help you to create a polished and unified
-experience for the user.</p>
-
-<p>To get started creating conforming icons more quickly, you can download 
-the Android Icon Templates Pack. For more information, see 
-<a href="#templatespack">Using the Android Icon Template Pack</a>.</p>
-
-<h2 id="launcherstructure">Launcher icon</h2>
-
-<p>A launcher icon is the graphic that represents your application on an Android
-device’s Home screen. It is a simplified 3D icon with a fixed perspective. The
-required perspective is shown in Figure 1.</p>
-
-<h4 id="launcherstructure">Structure</h4>
-
-<ul>
-<li>The base of a launcher icon can face either the top view or the front
-view.</li>
-
-<li>The majority of a launcher icon’s surface should be created using the
-launcher icon <a href="#launcherpalette">color palette</a>. To add emphasis, use
-one or more bright accent colors to highlight specific characteristics.</li>
-
-<li>All launcher icons must be created with rounded corners to make them look
-friendly and simple—as shown in Figure 2.</li>
-
-<li>All dimensions specified are based on a 250x250 pixel artboard size
-in a vector graphics editor like Adobe Illustrator, where the icon fits within
-the artboard boundaries.</li>
-
-<li><strong>Final art must be scaled down and exported as a transparent 48x48 px
-PNG file using a raster image editor such as Adobe Photoshop.</strong></li>
-
-<li>Templates for creating launcher icons in Adobe Illustrator and Photoshop are
-available in the Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/launcher_structure.png" alt="A view of
-launcher icon corners and perspective angles" />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 1.</strong> Perspective angles for launcher icons (90° is
-vertical).</p>
-    <div class="image-caption-nested">
-      <table style="margin-top:0;">
-      <tr><td style="padding-right:1em"><em>1.</em></td><td>92°</td></tr>
-      <tr><td><em>2.</em></td><td>92°</td></tr>
-      <tr><td><em>3.</em></td><td>173°</td></tr>
-      <tr><td><em>4.</em></td><td>171°</td></tr>
-      <tr><td><em>5.</em></td><td>49°</td></tr>
-      <tr><td><em>6.</em></td><td>171°</td></tr>
-      <tr><td><em>7.</em></td><td>64°</td></tr>
-      <tr><td><em>8.</em></td><td>97°</td></tr>
-      <tr><td><em>9.</em></td><td>75°</td></tr>
-      <tr><td><em>10.</em></td><td>93°</td></tr>
-      <tr><td><em>11.</em></td><td>169°</td></tr>
-      </table>
-    </div>
-  </div>
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 2.</strong> Rounded corners for launcher icons.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-<h4 id="launcherlight">Light, effects, and shadows</h4>
-
-<p>Launcher icons are simplified 3D icons using light and shadows for
-definition. A light source is placed slightly to the left in front of the icon,
-and therefore the shadow expands to the right and back.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/launcher_light.png" alt="A view of
-light, effects, and shadows for launcher icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 3. </strong>Light, effects, and shadows for launcher icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Edge highlight:</td><td>white</td></tr>
-    <tr><td><em>2.</em></td><td>Icon shadow:</td><td>black | 20px blur<br>50% opacity | angle 67°</td></tr>
-    <tr><td><em>3.</em></td><td>Front part:</td><td>Use light gradient from color palette</td></tr>
-    <tr><td><em>4.</em></td><td>Detail shadow:</td><td>black | 10px blur<br>75% opacity</td></tr>
-    <tr><td><em>5.</em></td><td> Side part:</td><td>Use medium gradient from color palette</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="launcherpalette">Launcher icon color palette</h4>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for highlights on edges.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_light.png" alt="Color palette, light gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Light gradient<br><em>1:&nbsp;&nbsp;</em>r 0  | g 0  | b 0<br><em>2:&nbsp;&nbsp;</em>r 217 | g 217 | b 217<br>Used on the front (lit) part of the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_medium.png" alt="Color palette, medium gradien" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Medium gradient<br><em>1:&nbsp;&nbsp;</em>r 190 | g 190 | b 190<br><em>2:&nbsp;&nbsp;</em>r 115 | g 115 | b 115<br>Used on the side (shaded) part of the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_dark.png" alt="Color palette, dark gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Dark gradient<br><em>1:&nbsp;&nbsp;</em>r 100 | g 100 | b 100<br><em>2:&nbsp;&nbsp;</em>r 25  | g 25  | b 25<br>Used on details and parts in the shade of the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used as base color in shadows.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="launchersteps">Step by step</h4>
-
-<ol>
-  <li>Create the basic shapes with a tool like Adobe Illustrator, using the
-angles described in <a href="#launcherstructure">Launcher icon: structure</a>.
-The shapes and effects must fit within a 250x250 pixel artboard.</li>
-  <li>Add depth to shapes by extruding them and create the rounded corners as
-described for the launcher icon structure.</li>
-  <li>Add details and colors. Gradients should be treated as if there is a light
-source placed slightly to the left in front of the icon.</li>
-  <li>Create the shadows with the correct angle and blur effect.</li>
-  <li>Import the icon into a tool like Adobe Photoshop and scale to fit an image
-size of 48x48 px on a transparent background.</li>
-  <li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-<h2 id="menustructure">Menu icon</h2>
-
-<p>Menu icons are graphical elements placed in the pop-up menu shown to users
-when they press the Menu button. They are drawn in a flat-front perspective.
-Elements in a menu icon must not be visualized in 3D or perspective.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>In order to maintain consistency, all menu icons must use the same
-primary palette and the same effects. For more information, see the
-menu icon <a href="#menupalette">color palette</a>. </li>
-
-<li>Menu icons should include rounded corners, but only when logically
-appropriate. For example, in Figure 3 the logical place for rounded corners is
-the roof and not the rest of the building.</span></li>
-
-<li>All dimensions specified on this page are based on a 48x48 pixel artboard 
-size with a 6 pixel safeframe.</li>
-
-<li>The menu icon effect (the outer glow) described in <a
-href="#menulight">Light, effects, and shadows</a> can overlap the 6px safeframe,
-but only when necessary. The base shape must always stay inside the
-safeframe.</li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating menu icons in Adobe Photoshop are available in the 
-Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/menu_structure.png" alt="A view of menu
-icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 4. </strong>Safeframe and corner-rounding for menu
-icons. Icon size is 48x48.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<h4 id="menulight">Light, effects, and shadows</h4>
-
-<p>Menu icons are flat and pictured face on. A slight deboss and some other
-effects, which are shown below, are used to create depth.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/menu_light.png" alt="A view of light, effects, and shadows for launcher icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 5. </strong>Light, effects, and shadows for launcher icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20 % opacity<br>angle 90° | distance 2px<br>size 2px</td></tr>
-    <tr><td><em>3.</em></td><td>Outer glow:</td><td>white | 55% opacity <br>spread 10% | size 3px</td></tr>
-    <tr><td><em>5.</em></td><td>Inner bevel:</td><td>depth 1% | direction down size 0px<br>angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menupalette">Color palette</h4>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for outer glow and bevel highlight.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png" alt="Color palette, medium gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for inner shadow and bevel shadow.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
-of 48x48 px on a transparent background. Mind the safeframe.</li>
-<li>Add the effects seen as described in Figure 5.</li>
-<li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="statusbarstructure">Status bar icon</h2>
-
-<p>Status bar icons are used to represent notifications from your application in
-the status bar. Graphically, they are very similar to menu icons, but are
-smaller and higher in contrast.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>Rounded corners must always be applied to the base shape and to the details
-of a status bar icon shown Figure 7.</li>
-
-<li>All dimensions specified are based on a 25x25 pixel artboard size with a 2
-pixel safeframe.</li>
-
-<li>Status bar icons can overlap the safeframe to the left and right when
-necessary, but must not overlap the safeframe at the top and bottom.</li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating status bar icons using Adobe Photoshop are available
-in the Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/statusbar_structure.png" alt="A view of
-status bar icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 6. </strong>Safeframe and corner-rounding for status bar
-icons. Icon size is 25x25.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<h4 id="statusbarlight">Light, effects, and shadows</h4>
-
-<p>Status bar icons are slightly debossed, high in contrast, and pictured
-face-on to enhance clarity at small sizes.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/statusbar_light.png" alt="A view of
-light, effects, and shadows for launcher icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 7. </strong>Light, effects, and shadows for launcher icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
-    <tr><td><em>2.</em></td><td>Inner bevel:</td><td>depth 100% | direction down<br>size 0px | angle 90° |<br>altitude 30°<br>highlight white 75% opacity<br>shadow black 75% opacity</td></tr>
-    <tr><td><em>3.</em></td><td>Detail:</td><td>white</td></tr>
-    <tr><td><em>4.</em></td><td>Disabled detail:</td><td>grey gradient from palette<br>+ inner bevel: smooth | depth 1% | direction down | size 0px | angle 117° | <br>altitude 42° | highlight white 70% | no shadow</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menupalette">Color palette</h4>
-
-<p>Only status bar icons related to the phone function use full color; all other status bar icons should remain monochromatic.</p>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for details within the icons and bevel highlight.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Grey gradient<br><em>1:&nbsp;&nbsp;</em>r 169 | g 169 | b 169<br><em>2:&nbsp;&nbsp;</em>r 126 | g 126 | b 126<br>Used for disabled details within the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>1 r 105 | g 105 | b 105<br><em>2:&nbsp;&nbsp;</em>r 10   | g 10   | b 10<br>Used as color fill.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for bevel shadow.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>In a tool like Adobe Photoshop, create the base shape within a 25x25 px
-image on a transparent background. Mind the safeframe, and keep the upper and
-lower 2 pixels free.</li>
-<li>Add rounded corners as specified in Figure 6.</li>
-<li>Add light, effects, and shadows as specified in Figure 7.</li>
-<li>Export the icon at 25x25 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="tabstructure">Tab icon</h2>
-
-<p>Tab icons are graphical elements used to represent individual tabs in a
-multi-tab interface. Each tab icon has two states: unselected and selected.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>Unselected tab icons have the same fill gradient and effects as menu icons,
-but with no outer glow.</li>
-
-<li>Selected tab icons look just like unselected tab icons, but with a fainter
-inner shadow, and have the same front part gradient as dialog icons.</li>
-
-<li>Tab icons have a 1 px safeframe which should only be overlapped for the edge
-of the anti-alias of a round shape.</li>
-
-<li>All dimensions specified on this page are based on a 32x32 px artboard size.
-Keep 1 px of padding around the bounding box inside the Photoshop template.</li>
-
-<li><strong>Final art must be exported as a 32x32 px transparent PNG
-file.</strong></li>
-
-<li>Templates for creating tab icons in Adobe Photoshop are available in the
-Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/tab_icon_unselected.png" alt="A view of
-unselected tab icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 8. </strong>Safeframe and fill gradient for unselected tab
-icons. Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/tab_icon_selected.png" alt="A view of
-selected tab icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 9. </strong>Safeframe and fill gradient for tab icons in
-selected state. Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-<h3 id="unselectedtabdetails">Unselected tab icon</h3>
-
-<h4 id="unselectedtablight">Light, effects, and shadows</h4>
-
-<p>Unselected tab icons look just like the selected tab icons, but with a
-fainter inner shadow, and the same front part gradient as the dialog icons.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/tab_unselected_light.png" alt="A view
-of light, effects, and shadows for unselected tab icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 10. </strong>Light, effects, and shadows for unselected
-tab icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom color: r 223 | g 223 | b 223<br>top color: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 10 % opacity | angle 90° distance 2px | size 2px</td></tr>
-    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape to a tool like Adobe Photoshop and scale to fit an image of
-32x32 px on a transparent background.</li>
-<li>Add the effects seen in Figure 10 for the unselected state filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-<h3 id="selectedtabdetails">Selected tab icon</h3>
-
-<p>The selected tab icons have the same fill gradient and effects as the menu
-icon, but with no outer glow.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/tab_selected_light.png" alt="A view of
-light, effects, and shadows for selected tab icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 11. </strong>Light, effects, and shadows for selected tab
-icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from color palette.</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20% opacity | <br>angle 90° | distance 2px | <br>size 2px</td></tr>
-    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | <br>altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menupalette">Color palette</h4>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill on unselected tab icons.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shape using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit a 32x32
-px artboard with a transparent background. </li>
-<li>Add the effects seen in Figure 11 for the selected state filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="dialogstructure">Dialog icon</h2>
-
-<p>Dialog icons are shown in pop-up dialog boxes that prompt the user for
-interaction. They use a light gradient and inner
-shadow in order to stand out against a dark background.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>Dialog icons have a 1 pixel safeframe. The base shape must fit within the
-safeframe, but the anti-alias of a round shape can overlap the safeframe. <span
-class="body-copy"></li>
-
-<li>All dimensions specified on this page are based on a 32x32 pixel artboard size
-in Adobe Photoshop. Keep 1 pixel of padding around the bounding box inside the
-Photoshop template.</li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating dialog icons in Adobe Photoshop are available in the
-Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/dialog_icon.png" alt="A view of dialog
-icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 12. </strong>Safeframe and fill gradient for dialog icons.
-Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<h4 id="dialoglight">Light, effects, and shadows</h4>
-
-<p>Dialog icons are flat and pictured face-on. In order to stand out against a
-dark background, they are built up using a light gradient and inner shadow.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/dialog_light.png" alt="A view of light,
-effects, and shadows for dialog icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 13. </strong>Light, effects, and shadows for dialog
-icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom: r 223 | g 223 | b 223<br>top: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
-    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 25% opacity | <br>angle -90° | distance 1px | size 0px</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
-of 32x32 px on a transparent background. </li>
-<li>Add the effects seen in Figure 13 for the proper filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="listviewstructure">List view icon</h2>
-
-<p>List view icons look a lot like dialog icons, but they use an inner shadow
-effect where the light source is above the object. They are also designed to be
-used only in a list view. Examples include the Android Market application home
-screen and the driving directions screen in the Maps application.</p>
-
-<h4>Structure</h4>
-
-<ul>
-<li>A list view icon normally has a 1 px safeframe, but it is OK to use the
-safeframe area for the edge of the anti-alias of a round shape. </li>
-
-<li>All dimensions specified are based on a 32x32 pixel artboard size in
-Photoshop. Keep 1 pixel of padding around the bounding box inside the template.
- </li>
-
-<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
-
-<li>Templates for creating list view icons in Adobe Photoshop are available in
-the Icon Templates Pack. </li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/listview_icon.png" alt="A view of list
-view icon structure." />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 14. </strong>Safeframe and fill gradient for list view
-icons. Icon size is 32x32.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-<h4 id="listviewlight">Light, effects, and shadows</h4>
-
-<p>List view icons are flat and pictured face-on with an inner shadow. Built up
-by a light gradient and inner shadow, they stand out well on a dark
-background.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/listview_icon_details.png" alt="A view
-of light, effects, and shadows for list view icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 15. </strong>Light, effects, and shadows for list view
-icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Inner shadow:</td><td>black | 57 % opacity | angle 120° | blend mode normal | distance 1px | size 1px <td></tr>
-    <tr><td><em>2.</em></td><td>Background:</td><td>black | standard system color <br>These icons are displayed in list views only.</td></tr>
-    <tr><td colspan="2">Note: The list view icon sits on 32x32 px artboard in Photoshop, without a safeframe.</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="menusteps">Step by step</h4>
-
-<ol>
-<li>Add the effects seen in Figure 15 for the proper filter.</li>
-<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
-<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
-<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
-of 32x32 px on a transparent background. </li>
-</ol>
-
-</td>
-</tr>
-</table>
-
-
-<h2 id="dodonts">General guidelines</h2>
-
-<p>Below are some "do and don't" guidelines to consider when creating icons for
-your application. By following the guidelines, you can ensure that your icons
-will work well with other parts of the Android platform UI and will meet the
-expectations of your application's users. </p>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4>Do...</h4>
-
-<ul>
-<li>Use a normal perspective. The depth of an object should be realistic.</li>
-<li>Keep it simple! By overdoing an icon, it loses it purpose and
-readability.</li>
-<li>Use colors only when necessary. Mind that the base of a launcher icon should
-be grey and feel solid. </li>
-<li>Use the correct angles for the specific icon types.</li>
-</ul>
-</td>
-<td style="border:0;width:350px;">
-
-<h4>Don’t...</h4>
-
-<ul>
-<li>Use open elements like text alone as icons. Instead place those elements on
-a base shape.</li>
-<li>Use colors for your status bar notifications. Those are reserved for
-specific phone-only functions.</li>
-</ul>
-</td>
-</tr>
-<tr>
-<td colspan="2" style="border:0;">
-<img src="{@docRoot}images/icon_design/do_dont.png" alt="Side-by-side examples
-of good/bad icon design."/>
-</td>
-</table>
-
-<h2 id="templatespack">Using the Android Icon Templates Pack</h2>
-
-<p>The Android Icon Templates Pack is a collection of template designs, filters,
-and settings that make it easier for you to create icons that conform to the
-general specifications given in this document. We recommend downloading the
-template pack archive before you get started with your icon design.</p>
-
-<p>The icon templates are provided in Adobe Photoshop and Adobe Illustrator file
-formats, which preserves the layers and design treatments we used when creating the
-standard icons for the Android platform. You can load the template files into any 
-compatible image-editing program, although your ability to work directly with the 
-layers and treatments may vary based on the program you are using.</p>
-
-<p>You can obtain the Icon Templates Pack archive using the link below: </p>
-
-<p style="margin-left:2em"><a
-href="{@docRoot}shareables/icon_templates-v1.0.zip">Download the Icon Templates
-Pack &raquo;</a>
-
-
-<h2 id="iconappendix">Icon appendix</p>
-
-<h3 id="launcherapx">Standard launcher icons</h3>
-
-<p>Shown below are examples of launcher icons used by Android applications. The
-icons are provided for your reference only &mdash; please do not reuse these
-icons in your applications.</code>.
-
-<table class="image-caption">
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
-  <div class="caption">Alarm Clock</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_browser.png" alt="Android asset" />
-  <div class="caption">Browser</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
-  <div class="caption">Calculator</div></td>
-	
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
-  <div class="caption">Calendar</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
-  <div class="caption">Camcorder</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_camera.png" alt="Android asset" />
-  <div class="caption">Camera</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
-  <div class="caption">Contacts</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
-  <div class="caption">Dialer</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
-  <div class="caption">Email</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
-  <div class="caption">Gallery</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
-  <div class="caption">Generic application</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_email.png" alt="Android asset" />
-  <div class="caption">Gmail</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
-  <div class="caption">Google Talk</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_IM.png" alt="Android asset" />
-  <div class="caption">IM</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_maps.png" alt="Android asset" />
-  <div class="caption">Maps</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
-  <div class="caption">Market </div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
-  <div class="caption">Messaging </div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
-  <div class="caption">Music</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_settings.png" alt="Android asset" />
-  <div class="caption">Settings</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
-  <div class="caption">Voice Dialer</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
-  <div class="caption">Voice Search</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="/images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
-  <div class="caption">YouTube</div></td>
-</tr>
-</table>
-
-<h3 id="menuapx">Standard menu icons</h3>
-
-<p>Shown below are standard menu icons that are included in the Android platform
-(as of Android 1.5). You can reference any of these icon resources from your
-application as needed, but make sure that the action you assign to the icon is
-consistent with that listed. Note that this is not a complete list of icons and
-that the actual appearance of standard icons may change across platform
-versions.</p>
-
-<p>To reference one of the icons from your code, use
-<code>android.R.drawable.&lt;icon_resource_identifier&gt;</code>. For example,
-you can call a menu item's {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable) setIcon()}
-method and pass the resource name:</p> 
-
-<p style="margin-left:2em"><code>.setIcon(android.R.drawable.ic_menu_more);</code>.
-
-<p>You could reference the same icon from a layout file using
-<code>android:icon="@android:drawable/ic_menu_more"></code>.</p>
-
-<p>To determine the resource ID for an icon listed below, hover over the icon or
-simply look at image filenames, which use the format
-"&lt;icon_resource_identifier&gt;.png".</p>
-
-<table class="image-caption">
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_add.png" title="ic_menu_add" alt="Android asset" />
-  <div class="caption">Add</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_call.png" title="ic_menu_call" alt="Android asset" />
-  <div class="caption">Call</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_camera.png" title="ic_menu_camera" alt="Android asset" />
-  <div class="caption">Camera</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_close_clear_cancel.png" title="ic_menu_close_clear_cancel" alt="Android asset" />
-  <div class="caption">Clear / Close / Cancel / Discard </div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_compass.png" title="ic_menu_compass" alt="Android asset" />
-  <div class="caption">Compass</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_delete.png" title="ic_menu_delete" alt="Android asset" />
-  <div class="caption">Delete</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_directions.png" title="ic_menu_directions" alt="Android asset" />
-  <div class="caption">Directions</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_edit.png" title="ic_menu_edit" alt="Android asset" />
-  <div class="caption">Edit</div></td>
-
-
-<td class="image-caption-i image-list">	
-  <img src="{@docRoot}images/icon_design/ic_menu_gallery.png" title="ic_menu_gallery" alt="Android asset" />
-  <div class="caption">Gallery</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_help.png" title="ic_menu_help" alt="Android asset" />
-  <div class="caption">Help</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_info_details.png" title="ic_menu_info_details" alt="Android asset" />
-  <div class="caption">Info / details</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_mapmode.png" title="ic_menu_mapmode" alt="Android asset" />
-  <div class="caption">Map mode</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_mylocation.png" title="ic_menu_mylocation" alt="Android asset" />
-  <div class="caption">My Location</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_more.png" title="ic_menu_more" alt="Android asset" />
-  <div class="caption">More</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_preferences.png" title="ic_menu_preferences" alt="Android asset" />
-  <div class="caption">Preferences</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_rotate.png" title="ic_menu_rotate" alt="Android asset" />
-  <div class="caption">Rotate</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_save.png" title="ic_menu_save" alt="Android asset" />
-  <div class="caption">Save</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_send.png" title="ic_menu_send" alt="Android asset" />
-  <div class="caption">Send</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_search.png" title="ic_menu_search" alt="Android asset" />
-  <div class="caption">Search</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_share.png" title="ic_menu_share" alt="Android asset" />
-  <div class="caption">Share</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_upload.png" title="ic_menu_upload" alt="Android asset" />
-  <div class="caption">Upload</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_view.png" title="ic_menu_view" alt="Android asset" />
-  <div class="caption">View</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_menu_zoom.png" title="ic_menu_zoom" alt="Android asset" />
-  <div class="caption">Zoom</div></td>
-
-</tr>
-</table>
-
-
-<h3 id="statusbarapx">Standard status bar icons</h3>
-
-<p>Shown below are standard status bar icons included in the Android platform
-(as of Android 1.5). You can reference any of these icon resources from your
-application as needed, but make sure that the meaning of the icon is consistent
-with the standard meaning listed. Note that this is not a complete list of icons
-and that the actual appearance of standard icons may change across platform
-versions.</p>
-
-<p>To reference one of the icons from your code, use
-<code>android.R.drawable.&lt;icon_resource_identifier&gt;</code>. For example,
-you can construct a simple notification that references one of the icons like
-this: </p>
-
-<p style="margin-left:2em"><code>new Notification(R.drawable.stat_notify_calendar, 
-"sample text", System.currentTimeMillis());</code></p>
-
-<p>To determine the resource ID for an icon listed below, hover over the icon 
-or simply look at the image filename, which use the format 
-"&lt;icon_resource_identifier&gt;.png".</p>
-
-
-<table class="image-caption">
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_data_bluetooth.png" title="stat_sys_data_bluetooth" alt="Android asset" />
-  <div class="caption">Bluetooth</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_email_generic.png" title="stat_notify_email_generic" alt="Android asset" />
-  <div class="caption">Email</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_chat.png" title="stat_notify_chat" alt="Android asset" />
-  <div class="caption">IM</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_voicemail.png" title="stat_notify_voicemail" alt="Android asset" />
-  <div class="caption">Voicemail</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_warning.png" title="stat_sys_warning" alt="Android asset" />
-  <div class="caption">Warning</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_phone_call.png" title="stat_sys_phone_call" alt="Android asset" />
-  <div class="caption">Call</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_phone_call_forward.png" title="stat_sys_phone_call_forward" alt="Android asset" />
-  <div class="caption">Call forward</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_sys_phone_call_on_hold.png" title="stat_sys_phone_call_on_hold" alt="Android asset" />
-  <div class="caption">Call on hold</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/stat_notify_missed_call.png" title="stat_notify_missed_call" alt="Android asset" />
-  <div class="caption">Missed call</div></td>
-
-</tr>
-</table>
-
-
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_dialog.jd b/docs/html/guide/practices/ui_guidelines/icon_design_dialog.jd
new file mode 100644
index 0000000..f78bd86
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_dialog.jd
@@ -0,0 +1,164 @@
+page.title=Dialog Icons
+parent.title=Icon Design Guidelines
+parent.link=icon_design.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#icon1">All Android Versions</a>
+  <ol>
+    <li><a href="#structure1">Structure</a></li>
+    <li><a href="#style1">Light, effects, and shadows</a></li>
+  </ol>
+</li>
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>Dialog icons are shown in pop-up dialog boxes that prompt the user for
+interaction. They use a light gradient and inner
+shadow in order to stand out against a dark background.</p>
+
+<p>As described in <a href="icon_design.html#icon-sets">Providing
+Density-Specific Icon Sets</a>, you should create separate icon sets for low-,
+medium-, and high-density screens. This ensures that your icons will display
+properly across the range of devices on which your application can be installed.
+See Table 1 for a listing of the recommended finished icon sizes for each
+density. Also, see <a href="icon_design.html#design-tips">Tips for Designers</a>
+for suggestions on how to work with multiple sets of icons.</p>
+
+
+<p class="table-caption"><strong>Table 1.</strong> Summary of finished dialog
+icon dimensions for each of the three generalized screen densities.</p>
+
+  <table>
+    <tbody>
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>Low density screen <em>(ldpi)</em></nobr>
+      </th>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>Medium density screen <em>(mdpi)</em></nobr>
+      </th>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>High density screen <em>(hdpi)</em><nobr>
+      </th>
+    </tr>
+
+    <tr>
+      <td>
+        24 x 24 px
+      </td>
+      <td>
+        32 x 32 px
+      </td>
+      <td>
+        48 x 48 px
+      </td>
+    </tr>
+
+    </tbody>
+  </table>
+
+
+
+<p><strong>Final art must be exported as a transparent PNG file. Do not include
+a background color</strong>.</p>
+
+<p>Templates for creating icons in Adobe Photoshop are available in the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon
+Templates Pack</a>.</p>
+
+<h2 id="icon1">All Android Versions</h2>
+
+<p>The following guidelines describe how to design dialog icons for all versions
+of the Android platform.</p>
+
+<h3 id="structure1">Structure</h3>
+
+<ul>
+<li>Dialog icons have a 1 pixel safeframe. The base shape must fit within the
+safeframe, but the anti-alias of a round shape can overlap the safeframe.</li>
+
+<li>All dimensions specified on this page are based on a 32x32 pixel artboard size
+in Adobe Photoshop. Keep 1 pixel of padding around the bounding box inside the
+Photoshop template.</li>
+
+
+</ul>
+
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/dialog_icon.png" alt="A view of dialog
+icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 1. </strong>Safeframe and fill gradient for dialog icons.
+Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<h3 id="style1">Light, effects, and shadows</h3>
+
+<p>Dialog icons are flat and pictured face-on. In order to stand out against a
+dark background, they are built up using a light gradient and inner shadow.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/dialog_light.png" alt="A view of light,
+effects, and shadows for dialog icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 2. </strong>Light, effects, and shadows for dialog
+icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90&deg;<br>bottom: r 223 | g 223 | b 223<br>top: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 25% opacity | <br>angle -90&deg; | distance 1px | size 0px</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<table>
+<tr>
+<td style="border:0;">
+
+<h4 id="steps1">Step by step</h4>
+
+<ol>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
+of 32x32 px on a transparent background. </li>
+<li>Add the effects seen in Figure 2 for the proper filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_launcher.jd b/docs/html/guide/practices/ui_guidelines/icon_design_launcher.jd
new file mode 100644
index 0000000..cb04b55
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_launcher.jd
@@ -0,0 +1,520 @@
+page.title=Launcher Icons
+parent.title=Icon Design Guidelines
+parent.link=icon_design.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#market">Application Icons in Android Market</a></li>
+<li><a href="#icon5">Android 2.0 and Later</a>
+  <ol>
+    <li><a href="#style5">Style</a></li>
+    <li><a href="#size5">Size</a></li>
+    <li><a href="#materialscolors5">Materials and colors</a></li>
+    <li><a href="#effects5">Effects</a></li>
+    <li><a href="#dodonts5">Do's and don'ts</a></li>
+    <li><a href="#examples5">Example icons</a></li>
+  </ol>
+</li>
+<li><a href="#icon1">Android 1.6 and Earlier</a></li>
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
+</div>
+</div>
+
+
+<p>A Launcher icon is a graphic that represents your application on the device's
+Home screen and in the Launcher window.</p>
+
+<p>The user opens the Launcher by touching the icon at the bottom of the Home
+screen. The Launcher opens and exposes the icons for all of the installed
+applications. The user selects an application and opens it by touching the
+Launcher icon or by means of any hardware navigation controls available, such as
+a trackball or d-pad.</p>
+
+<p>As described in <a href="icon_design.html#icon-sets">Providing
+Density-Specific Icon Sets</a>, you should create separate icons for low-,
+medium-, and high-density screens. This ensures that your icons will display
+properly across the range of devices on which your application can be installed.
+See <a href="icon_design.html#design-tips">Tips for Designers</a> for
+suggestions on how to work with multiple sets of icons.</p>
+
+
+
+<h2 id="market">Application Icons in Android Market</h2>
+
+<p>If you are <a href="{@docRoot}guide/publishing/publishing.html">publishing
+your application on Android Market</a>, you will also need to provide a 512x512
+pixel, high-resolution application icon in the <a
+href="http://market.android.com/publish">developer console</a> at upload-time.
+This icon will be used in various locations in Android Market and does
+not replace your launcher icon.</p>
+
+<p>For tips and recommendations on creating high-resolution launcher icons that
+can easily be scaled up to 512x512, see
+<a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#design-tips">
+Tips for Designers</a>.</p>
+
+<p>For information and specifications about high-resolution application
+icons in Android Market, see the following article:</p>
+
+<p style="margin-left:2em"><a
+href="http://market.android.com/support/bin/answer.py?answer=1078870">
+  Graphic Assets for your Application (Android Market Help) &raquo;</a>
+
+
+
+
+<h2 id="icon5">Android 2.0 and Later</h2>
+
+<p>Starting with Android 2.0, launcher icons should be front-facing, instead of
+at a three-quarter perspective. The following guidelines describe how to design
+launcher icons for Android 2.0 (API Level 5) and later.</p>
+
+<h3 id="style5">Style</h3>
+
+<p>The launcher icons that you create should follow the general style principles
+below. The guidelines aren't meant to restrict what you can do with your icons,
+but rather they are meant to emphasize the common approaches that your icons can
+share with others on the device. Figure 1, at right, provides examples.  </p>
+
+<div class="figure">
+  <img src="{@docRoot}images/icon_design/IconGraphic_Icons_i.png" 
+    width="340">
+  <p class="img-caption">
+    <strong>Figure 1.</strong> Example launcher icons for Android 2.0 and
+    greater.
+  </p>
+</div>
+
+<p>Clean and contemporary:</p>
+
+<ul>
+  <li>Launcher icons should be modern and sometimes quirky; they should not
+appear aged or ragged. You should avoid overused symbolic metaphors whenever
+possible.</li>
+</ul>
+
+<p>Simple and iconic:</p>
+<ul>
+  <li>Android Launcher icons are caricatural in nature; your icons should be
+highly simplified and exaggerated, so that they are appropriate for use at small
+sizes. Your icons should not be overly complicated. </li>
+  <li>Try featuring a single part of an application as a symbolic
+representation of the whole (for example, the Music icon features a speaker).
+</li>
+  <li>Consider using natural outlines and shapes, both geometric and organic,
+with a realistic (but never photorealistic) rendering. </li>
+  <li>Your icons <em>should not</em> present a cropped view of a larger
+image.</li>
+</ul>
+
+<p>Tactile and textured:</p>
+<ul>
+  <li>Icons should feature non-glossy, textured material. See
+  <a href="#materialscolors5">Materials and colors</a>, below, for more
+  information.</li>
+</ul>
+
+<p>Forward-facing and top-lit:</p>
+<ul>
+  <li><em>New for Android 2.0 and later platforms</em>: Android Launcher
+icons should be forward-facing, with very little perspective, and they
+should be top-lit.</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Android applies separate text labels
+using the application name when displaying launcher icons, so you should avoid
+embedding text in your icon and instead focus on designing a distinct and
+memorable icon.</p>
+
+
+
+<h3 id="size5">Size and positioning</h3>
+
+<p>Launcher icons should use a variety of shapes and forms that are scaled and
+positioned inside the asset to create consistent visual weight with other
+icons.</p>
+
+<p>Figure 2 illustrates various ways of positioning the icon inside the
+asset. You should size the icons <em>smaller than the actual bounds of the
+asset</em> to create a consistent visual weight and to allow for shadows. If
+your icon is square or nearly square, it should be scaled even smaller.</p>
+
+<p>In order to indicate the recommended size for the icon, each example in
+Figure 2 includes three different guide rectangles:</p>
+
+<ul>
+<li>The red box is the bounding box for the full asset.</li>
+<li>The blue box is the recommended bounding box for the actual icon.
+The icon box is sized smaller than the full asset box so that there is space to
+include shadows and allow for special icon treatments.</li>
+<li>The orange box is the recommended bounding box for the actual icon when
+the content is square. The box for square icons is smaller than that for other
+icons to establish a consistent visual weight across the two types.</li>
+</ul>
+
+<table>
+<tr>
+
+<td style="border:0;">
+<ol class="nolist">
+  <li>Launcher icon dimensions for high-density (<code>hdpi</code>) screens:</li>
+  <ol class="nolist">
+    <li>Full Asset: 72 x 72 px</li>
+    <li>Icon: 60 x 60 px</li>
+    <li>Square Icon: 56 x 56 px</li>
+  </ol>
+  </li>
+</ol>
+</td>
+<td style="border:0;">
+  <img src="{@docRoot}images/icon_design/launcher_size_hdpi.png" width="450">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Launcher icon dimensions for medium-density (<code>mdpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 48 x 48 px</li>
+      <li>Icon: 40 x 40 px</li>
+      <li>Square Icon: 38 x 38 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/launcher_size_mdpi.png" width="450">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Launcher icon dimensions for low-density (<code>ldpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 36 x 36 px</li>
+      <li>Icon: 30 x 30 px</li>
+      <li>Square Icon: 28 x 28 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/launcher_size_ldpi.png" width="450">
+</td>
+</tr>
+
+<tr>
+<td style="border:0;"></td>
+<td style="border:0;">
+ <p class="table-caption"><strong>Figure 2.</strong>
+ Launcher icon sizing and positioning inside the bounds of the
+ icon asset.</p>
+</td>
+</tr>
+
+</table>
+
+
+
+
+<h3 id="materialscolors5">Materials and colors</h3>
+
+<p>Launcher icons should make use of tactile, top-lit, textured materials. Even
+if your icon is just a simple shape, you should try to render in a way that
+makes it appear to be sculpted from some real-world material.</p>
+
+<p>Android launcher icons usually consist of a smaller shape within a
+larger base shape and combine one neutral and one primary color. Icons may
+use a combination of neutral colors but should maintain a fairly high level of
+contrast. Icons should not use more than one primary color per icon, if
+possible.</p>
+
+<p>Launcher icons should use a limited color palette that includes a range
+of neutral and primary colors. The icons should not be over-saturated.</p>
+
+<p>The recommended color palette to use for Launcher icons is shown in Figure 3.
+You can use elements of the palette for both the base color and the highlight
+color. You can use the colors of the palette in conjunction with a
+white-to-black vertical linear gradient overlay. This creates the impression
+that the icon is lit from above and keeps the color less saturated.</p>
+
+<img src="{@docRoot}images/icon_design/IconGraphic_Colors.png" width="530">
+<p class="img-caption">
+<strong>Figure 3.</strong> Recommended color palette for icons.</p>
+
+<p>When you combine the materials in Figure 4 with a color highlight from the
+recommended palette above, you can create materials combinations such as those
+shown in Figure 5. To get you started, the
+<a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon Templates Pack</a>
+includes a Photoshop file (<code>ic_launcher_template/example_materials.psd</code>)
+that provides all of the default materials, colors, and gradients. </p>
+
+<table>
+  <tbody>
+    <tr>
+      <td style="border:0;">
+<img src="{@docRoot}images/icon_design/IconGraphic_Materials.png" width="450">
+<p class="img-caption">
+<strong>Figure 4.</strong> Example materials that you can use to create
+your icons.</p>
+      </td>
+      <td style="border:0;border-left:1px solid #ccc;margin-left:1em;padding-left:1em">
+<img src="{@docRoot}images/icon_design/IconGraphic_AccentColor.png" width="450">
+<p class="img-caption">
+<strong>Figure 5.</strong> Examples of materials combined with base
+and highlight colors from the recommended palette.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+
+
+
+<h3 id="effects5">Effects</h3>
+
+<p>Launcher icons are flat and the perspective is straight-on, rather than at an
+angle. A drop shadow is used to create a sense of depth. Launcher icons can use
+varying textures and lighting effects, but must be lit directly from above
+(straight down).</p>
+
+<p>In order to maintain consistency, all launcher icons should use the same
+drop shadow effect, as shown in Figure 6.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/launcher_style.png"/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 6. </strong>Style, light and effects for launcher icons.</p>
+    <div class="image-caption-nested">
+    <p><em>Note: all pixel dimensions are for medium density and should be scaled appropriately for other densities.</em></p>
+    <table>
+    <tr><td><em>1.</em></td><td nowrap>Lighting:</td><td>Top-lit, using appropriate lighting details<br><br></td></tr>
+    <tr><td><em>2.</em></td><td nowrap>Drop shadow:</td><td><code>#000000</code>, 75% opacity<br>angle 90&deg;<br>distance 1px<br>size 3px<br><br></td></tr>
+    <tr><td><em>3.</em></td><td nowrap>Textures:</td><td>Tactile, appear to use real-world materials (monochromatic noise in example image)<br><br></td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+
+<h3 id="dodonts5">Do's and don'ts</h3>
+
+<p>Below are some "do and don't" examples to consider when creating icons for
+your application.  </p>
+
+
+<table>
+<tr>
+<td style="border:0;width:50%">
+
+<h4>Android Launcher icons are...</h4>
+
+<ul>
+<li>Modern, minimal, matte, tactile, and textured</li>
+<li>Forward-facing and top-lit, whole, limited in color
+palette</li>
+</ul>
+</td>
+<td style="border:0;width:50%">
+
+<h4>Android Launcher icons are not...</h4>
+
+<ul>
+<li>Antique, over-complicated, glossy, flat vector</li>
+<li>Rotated, Cropped, Over-Saturated</li>
+</ul>
+</td>
+</tr>
+<tr>
+</table>
+
+<img src="{@docRoot}images/icon_design/IconGraphic_DosDonts.png"/>
+<p class="img-caption">
+<strong>Figure 7.</strong> Side-by-side examples of "do's and don'ts" for
+Android launcher icons. </p>
+
+
+
+
+
+<h3 id="examples5">Example icons</h3>
+
+<p>Shown below are examples of high-density launcher icons used by
+Android applications. The icons are provided for your reference only &mdash;
+please do not reuse these icons in your applications.</code>.</p>
+
+<img src="{@docRoot}images/icon_design/IconGraphic_Icons.png" />
+
+
+
+<h2 id="icon1">Android 1.6 and earlier</h2>
+
+<p>The following guidelines describe how to design launcher icons for Android
+1.6 (API Level 4) and earlier. Launcher icons for Android 1.6 and below are
+simplified 3D icons with a fixed perspective. The required perspective is shown
+in Figure 8.</p>
+
+<h3 id="structure1">Structure</h3>
+
+<ul>
+<li>The base of a launcher icon can face either the top view or the front
+view.</li>
+
+<li>The majority of a launcher icon’s surface should be created using the
+launcher icon <a href="#palette1">color palette</a>. To add emphasis, use
+one or more bright accent colors to highlight specific characteristics.</li>
+
+<li>All launcher icons must be created with rounded corners to make them look
+friendly and simple—as shown in Figure 8.</li>
+
+<li>All dimensions specified are based on a 250x250 pixel artboard size
+in a vector graphics editor like Adobe Illustrator, where the icon fits within
+the artboard boundaries.</li>
+
+<li><strong>Final art must be scaled down and exported as a transparent PNG file
+using a raster image editor such as Adobe Photoshop. Do not include a background
+color.</strong></li>
+
+<li>Templates for creating icons in Adobe Photoshop are available in the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon
+Templates Pack</a>.</li>
+
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/launcher_structure.png" alt="A view of
+launcher icon corners and perspective angles" />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 8.</strong> Rounded corners and perspective angles for
+      launcher icons (90° is vertical).</p>
+    <div class="image-caption-nested">
+      <table>
+      <tr><td><em>1.</em></td><td>92°</td></tr>
+      <tr><td><em>2.</em></td><td>92°</td></tr>
+      <tr><td><em>3.</em></td><td>173°</td></tr>
+      <tr><td><em>4.</em></td><td>171°</td></tr>
+      <tr><td><em>5.</em></td><td>49°</td></tr>
+      <tr><td><em>6.</em></td><td>171°</td></tr>
+      <tr><td><em>7.</em></td><td>64°</td></tr>
+      <tr><td><em>8.</em></td><td>97°</td></tr>
+      <tr><td><em>9.</em></td><td>75°</td></tr>
+      <tr><td><em>10.</em></td><td>93°</td></tr>
+      <tr><td><em>11.</em></td><td>169°</td></tr>
+      </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<h3 id="style1">Light, effects, and shadows</h3>
+
+<p>Launcher icons are simplified 3D icons using light and shadows for
+definition. A light source is placed slightly to the left in front of the icon,
+and therefore the shadow expands to the right and back.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/launcher_light.png" alt="A view of
+light, effects, and shadows for launcher icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 9. </strong>Light, effects, and shadows for launcher icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Edge highlight:</td><td>white</td></tr>
+    <tr><td><em>2.</em></td><td>Icon shadow:</td><td>black | 20px blur<br>50% opacity | angle 67°</td></tr>
+    <tr><td><em>3.</em></td><td>Front part:</td><td>Use light gradient from color palette</td></tr>
+    <tr><td><em>4.</em></td><td>Detail shadow:</td><td>black | 10px blur<br>75% opacity</td></tr>
+    <tr><td><em>5.</em></td><td> Side part:</td><td>Use medium gradient from color palette</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table>
+<tr>
+<td style="border:0">
+
+<h4 id="palette1">Launcher icon color palette</h4>
+
+<table>
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_white.png"/></td>
+<td class="image-caption-c">White<br>r 255 | g 255 | b 255<br>Used for highlights on edges.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_light.png"/></td>
+<td class="image-caption-c">Light gradient<br><em>1:&nbsp;&nbsp;</em>r 0  | g 0  | b 0<br><em>2:&nbsp;&nbsp;</em>r 217 | g 217 | b 217<br>Used on the front (lit) part of the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_medium.png"/></td>
+<td class="image-caption-c">Medium gradient<br><em>1:&nbsp;&nbsp;</em>r 190 | g 190 | b 190<br><em>2:&nbsp;&nbsp;</em>r 115 | g 115 | b 115<br>Used on the side (shaded) part of the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_dark.png"/></td>
+<td class="image-caption-c">Dark gradient<br><em>1:&nbsp;&nbsp;</em>r 100 | g 100 | b 100<br><em>2:&nbsp;&nbsp;</em>r 25  | g 25  | b 25<br>Used on details and parts in the shade of the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_black.png"/></td>
+<td class="image-caption-c">Black<br>r 0 | g 0 | b 0<br>Used as base color in shadows.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0">
+
+<h4 id="steps1">Step by step</h4>
+
+<ol>
+  <li>Create the basic shapes with a tool like Adobe Illustrator, using the
+angles described in <a href="#structure1">Launcher icon: structure</a>.
+The shapes and effects must fit within a 250x250 pixel artboard.</li>
+  <li>Add depth to shapes by extruding them and create the rounded corners as
+described for the launcher icon structure.</li>
+  <li>Add details and colors. Gradients should be treated as if there is a light
+source placed slightly to the left in front of the icon.</li>
+  <li>Create the shadows with the correct angle and blur effect.</li>
+  <li>Import the icon into a tool like Adobe Photoshop and scale to fit an image
+size of 48x48 px on a transparent background.</li>
+  <li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_list.jd b/docs/html/guide/practices/ui_guidelines/icon_design_list.jd
new file mode 100644
index 0000000..7bf34cc
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_list.jd
@@ -0,0 +1,163 @@
+page.title=List View Icons
+parent.title=Icon Design Guidelines
+parent.link=icon_design.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#icon1">All Android Versions</a>
+  <ol>
+    <li><a href="#structure1">Structure</a></li>
+    <li><a href="#style1">Light, effects, and shadows</a></li>
+  </ol>
+</li>
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>List view icons look a lot like dialog icons, but they use an inner shadow
+effect where the light source is above the object. They are also designed to be
+used only in a {@link android.widget.ListView}. Examples include the Settings
+application.</p>
+
+<p>As described in <a href="icon_design.html#icon-sets">Providing
+Density-Specific Icon Sets</a>, you should create separate icon sets for low-,
+medium-, and high-density screens. This ensures that your icons will display
+properly across the range of devices on which your application can be installed.
+See Table 1 for a listing of the recommended finished icon sizes for each
+density. Also, see <a href="icon_design.html#design-tips">Tips for Designers</a>
+for suggestions on how to work with multiple sets of icons.</p>
+
+
+<p class="table-caption"><strong>Table 1.</strong> Summary of finished list view
+icon dimensions for each of the three generalized screen densities.</p>
+
+  <table>
+    <tbody>
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>Low density screen <em>(ldpi)</em></nobr>
+      </th>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>Medium density screen <em>(mdpi)</em></nobr>
+      </th>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>High density screen <em>(hdpi)</em><nobr>
+      </th>
+    </tr>
+
+    <tr>
+      <td>
+        24 x 24 px
+      </td>
+      <td>
+        32 x 32 px
+      </td>
+      <td>
+        48 x 48 px
+      </td>
+    </tr>
+
+    </tbody>
+  </table>
+
+
+
+<p><strong>Final art must be exported as a transparent PNG file. Do not include
+a background color</strong>.</p>
+
+<p>Templates for creating icons in Adobe Photoshop are available in the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon
+Templates Pack</a>.</p>
+
+<h2 id="icon1">All Android Versions</h2>
+
+<p>The following guidelines describe how to design dialog icons for all versions
+of the Android platform.</p>
+
+<h3 id="structure1">Structure</h3>
+
+<ul>
+<li>A list view icon normally has a 1 px safeframe, but it is OK to use the
+safeframe area for the edge of the anti-alias of a round shape.</li>
+
+<li>All dimensions specified are based on a 32x32 pixel artboard size in
+Photoshop. Keep 1 pixel of padding around the bounding box inside the template.
+</li>
+
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/listview_icon.png" alt="A view of list
+view icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 1. </strong>Safeframe and fill gradient for list view
+icons. Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+<h3 id="style1">Light, effects, and shadows</h3>
+
+<p>List view icons are flat and pictured face-on with an inner shadow. Built up
+by a light gradient and inner shadow, they stand out well on a dark
+background.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/listview_icon_details.png" alt="A view
+of light, effects, and shadows for list view icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 2. </strong>Light, effects, and shadows for list view
+icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Inner shadow:</td><td>black | 57 % opacity | angle 120&deg; | blend mode normal | distance 1px | size 1px <td></tr>
+    <tr><td><em>2.</em></td><td>Background:</td><td>black | standard system color <br>These icons are displayed in list views only.</td></tr>
+    <tr><td colspan="2">Note: The list view icon sits on 32x32 px artboard in Photoshop, without a safeframe.</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table>
+<tr>
+<td style="border:0">
+
+<h4 id="steps1">Step by step</h4>
+
+<ol>
+<li>Add the effects seen in Figure 2 for the proper filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
+of 32x32 px on a transparent background. </li>
+</ol>
+
+</td>
+</tr>
+</table>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_menu.jd b/docs/html/guide/practices/ui_guidelines/icon_design_menu.jd
new file mode 100644
index 0000000..2029def
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_menu.jd
@@ -0,0 +1,349 @@
+page.title=Menu Icons
+parent.title=Icon Design Guidelines
+parent.link=icon_design.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#icon9">Android 2.3 and Later</a>
+  <ol>
+    <li><a href="#size9">Size</a></li>
+    <li><a href="#style9">Style, colors, and effects</a></li>
+    <li><a href="#dodonts9">Do's and don'ts</a></li>
+    <li><a href="#examples9">Example icons</a></li>
+  </ol>
+</li>
+<li><a href="#icon1">Android 2.2 and Earlier</a></li>
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>Menu icons are graphical elements placed in the options menu shown to users
+when they press the Menu button. They are drawn in a flat-front perspective and
+in greyscale. Elements in a menu icon must not be visualized in 3D or
+perspective.</p>
+
+<p>As described in <a href="icon_design.html#icon-sets">Providing
+Density-Specific Icon Sets</a>, you should create separate icon sets for low-,
+medium-, and high-density screens. This ensures that your icons will display
+properly across the range of devices on which your application can be installed.
+See <a href="icon_design.html#design-tips">Tips for Designers</a>
+for suggestions on how to work with multiple sets of icons.</p>
+
+<p><strong>Final art must be exported as a transparent PNG file. Do not include
+a background color</strong>.</p>
+
+<p>Templates for creating icons in Adobe Photoshop are available in the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon
+Templates Pack</a>.</p>
+
+
+<p class="caution"><strong>Caution:</strong> The style and content sizing of
+menu icons have changed in Android 2.3 compared to
+<a href="#icon1">previous versions</a>:
+<br>
+1. Icons have a larger safe frame; icon content is smaller within the full
+asset. Final asset sizes have not changed.
+<br>
+2. The color palette is slightly lighter.
+<br>
+3. No outer glow effects are applied.
+<br>
+4. Menu icons can now be rendered on either dark or light backgrounds.
+
+</p>
+
+
+
+<h2 id="icon9">Android 2.3 and Later</h2>
+
+<p>The following guidelines describe how to design menu icons for Android
+2.3 (API Level 9) and later.</p>
+
+<h3 id="size9">Size and positioning</h3>
+
+<p>Menu icons can use a variety of shapes and forms and must be scaled and
+positioned inside the asset to create consistent visual weight with other
+icons.</p>
+
+<p>Figure 1 illustrates various ways of positioning the icon inside the
+asset. You should size the icons <em>smaller than the actual bounds of the
+asset</em>, to create a consistent visual weight. If your icon is square or
+nearly square, it should be scaled even smaller.</p>
+
+<p>In order to indicate the recommended size for the icon, each example in
+Figure 1 includes three different guide rectangles:</p>
+
+<ul>
+<li>The red box is the bounding box for the full asset.</li>
+<li>The blue box is the recommended bounding box for the actual icon.
+The icon box is sized smaller than the full asset box to allow for
+varying icon shapes while maintaining a consistent visual weight.</li>
+<li>The orange box is the recommended bounding box for the actual icon when
+the content is square. The box for square icons is smaller than that for other
+icons to establish a consistent visual weight across the two types.</li>
+</ul>
+
+<table>
+<tr>
+
+<td style="border:0;">
+<ol class="nolist">
+  <li>Menu icon dimensions for high-density (<code>hdpi</code>) screens:</li>
+  <ol class="nolist">
+    <li>Full Asset: 72 x 72 px</li>
+    <li>Icon: 48 x 48 px</li>
+    <li>Square Icon: 44 x 44 px</li>
+  </ol>
+  </li>
+</ol>
+</td>
+<td style="border:0;">
+  <img src="{@docRoot}images/icon_design/menu_size_hdpi.png" width="450">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Menu icon dimensions for medium-density (<code>mdpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 48 x 48 px</li>
+      <li>Icon: 32 x 32 px</li>
+      <li>Square Icon: 30 x 30 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/menu_size_mdpi.png" width="450">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Menu icon dimensions for low-density (<code>ldpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 36 x 36 px</li>
+      <li>Icon: 24 x 24 px</li>
+      <li>Square Icon: 22 x 22 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/menu_size_ldpi.png" width="450">
+</td>
+</tr>
+
+<tr>
+<td style="border:0;"></td>
+<td style="border:0;">
+ <p class="table-caption"><strong>Figure 1.</strong>
+ Menu icon sizing and positioning inside the bounds of the
+ icon asset.</p>
+</td>
+</tr>
+
+</table>
+
+
+
+
+<h3 id="style9">Style, colors, and effects</h3>
+
+<p>Menu icons are flat, pictured face on, and greyscale. A slight deboss and
+some other effects, which are shown below, are used to create depth. Menu icons
+should include rounded corners, but only when logically appropriate.</p>
+
+<p>In order to maintain consistency, all menu icons must use the same
+color palette and effects, as shown in Figure 2.</p>
+
+
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/menu_style.png" alt="A view of light, effects, and shadows for menu icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 2. </strong>Style, light and effects for menu icons.</p>
+    <div class="image-caption-nested">
+    <p><em>Note: all pixel dimensions are for medium density and should be scaled appropriately for other densities.</em></p>
+    <table>
+    <tr><td><em>1.</em></td><td nowrap>Corner rounding:</td><td>2 pixel corner radius, when appropriate<br><br></td></tr>
+    <tr><td><em>2.</em></td><td nowrap>Fill gradient:</td><td>90&deg;, from <code>#8C8C8C</code> to <code>#B2B2B2</code><br><br></td></tr>
+    <tr><td><em>3.</em></td><td nowrap>Inner shadow:</td><td><code>#000000</code>, 20% opacity<br>angle 90&deg;<br>distance 2px<br>size 2px<br><br></td></tr>
+    <tr><td><em>4.</em></td><td nowrap>Inner bevel:</td><td>depth 1%<br>direction down<br>size 0px<br>angle 90&deg;<br>altitude 10&deg;<br>highlight <code>#ffffff</code>, 70% opacity<br>shadow <code>#000000</code>, 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+
+
+<h3 id="dodonts9">Do's and don'ts</h3>
+
+<p>Below are some "do and don't" examples to consider when creating menu icons for
+your application. </p>
+
+
+<img src="{@docRoot}images/icon_design/do_dont_menuicons.png">
+
+
+
+
+<h3 id="examples9">Example icons</h3>
+
+<p>Shown below are standard high-density menu icons that are used in the Android
+platform.</p>
+
+<p class="warning"><strong>Warning:</strong> Because these resources can change
+between platform versions, you should not reference these icons using the
+Android platform resource IDs (i.e. menu icons under
+<code>android.R.drawable</code>). If you want to use any icons or other internal
+drawable resources, you should store a local copy of those icons or drawables in
+your application resources, then reference the local copy from your application
+code. In that way, you can maintain control over the appearance of your icons,
+even if the system's copy changes. Note that the grid below is not intended to
+be complete.</p>
+
+<img src="{@docRoot}images/icon_design/menu_standard.png" />
+
+
+
+
+<h2 id="icon1">Android 2.2 and Earlier</h2>
+
+<p>The following guidelines describe how to design menu icons for Android 2.2
+(API Level 4) and earlier. Menu icons in Android 2.2 and below are drawn in a
+flat-front perspective. Elements in a menu icon must not be visualized in 3D or
+perspective.</p>
+
+<h3 id="structure1">Structure</h3>
+
+<ul>
+<li>In order to maintain consistency, all menu icons must use the same
+primary palette and the same effects. For more information, see the
+menu icon <a href="#palette1">color palette</a>. </li>
+
+<li>Menu icons should include rounded corners, but only when logically
+appropriate. For example, in Figure 3 the logical place for rounded corners is
+the roof and not the rest of the building.</span></li>
+
+<li>All dimensions specified on this page are based on a 48x48 pixel artboard 
+size with a 6 pixel safeframe.</li>
+
+<li>The menu icon effect (the outer glow) described in <a
+href="#style1">Light, effects, and shadows</a> can overlap the 6px safeframe,
+but only when necessary. The base shape must always stay inside the
+safeframe.</li>
+
+<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
+
+<li>Templates for creating menu icons in Adobe Photoshop are available in the 
+Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/menu_structure.png" alt="A view of menu
+icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 3. </strong>Safeframe and corner-rounding for menu
+icons. Icon size is 48x48.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<h3 id="style1">Light, effects, and shadows</h3>
+
+<p>Menu icons are flat and pictured face on. A slight deboss and some other
+effects, which are shown below, are used to create depth.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/menu_light.png" alt="A view of light, effects, and shadows for launcher icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 4. </strong>Light, effects, and shadows for launcher icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20 % opacity<br>angle 90° | distance 2px<br>size 2px</td></tr>
+    <tr><td><em>3.</em></td><td>Outer glow:</td><td>white | 55% opacity <br>spread 10% | size 3px</td></tr>
+    <tr><td><em>5.</em></td><td>Inner bevel:</td><td>depth 1% | direction down size 0px<br>angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table>
+<tr>
+<td style="border:0">
+
+<h4 id="palette1">Color palette</h4>
+
+<table>
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_white.png"/></td>
+<td class="image-caption-c">White<br>r 255 | g 255 | b 255<br>Used for outer glow and bevel highlight.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png"/></td>
+<td class="image-caption-c">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_black.png"/></td>
+<td class="image-caption-c">Black<br>r 0 | g 0 | b 0<br>Used for inner shadow and bevel shadow.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0">
+
+<h4 id="steps1">Step by step</h4>
+
+<ol>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
+of 48x48 px on a transparent background. Mind the safeframe.</li>
+<li>Add the effects seen as described in Figure 4.</li>
+<li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_status_bar.jd b/docs/html/guide/practices/ui_guidelines/icon_design_status_bar.jd
new file mode 100644
index 0000000..1fc3528
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_status_bar.jd
@@ -0,0 +1,330 @@
+page.title=Status Bar Icons
+parent.title=Icon Design Guidelines
+parent.link=icon_design.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#icon9">Android 2.3 and Later</a>
+  <ol>
+    <li><a href="#size9">Size</a></li>
+    <li><a href="#style9">Style, color, and effects</a></li>
+    <li><a href="#dodonts9">Do's and don'ts</a></li>
+    <li><a href="#examples9">Example icons</a></li>
+  </ol>
+</li>
+<li><a href="#icon1">Android 2.2 and Earlier</a></li>
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>Status bar icons are used to represent notifications from your application in
+the status bar.</p>
+
+<p>As described in <a href="icon_design.html#icon-sets">Providing
+Density-Specific Icon Sets</a>, you should create separate icon sets for low-,
+medium-, and high-density screens. This ensures that your icons will display
+properly across the range of devices on which your application can be installed.
+See <a href="icon_design.html#design-tips">Tips for Designers</a> for
+suggestions on how to work with multiple sets of icons.</p>
+
+<p><strong>Final art must be exported as a transparent PNG file. Do not include
+a background color</strong>.</p>
+
+<p>Templates for creating icons in Adobe Photoshop are available in the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon
+Templates Pack</a>.</p>
+
+
+<p class="warning"><strong>Warning:</strong>
+
+The style and dimensions of status bar icons have changed drastically in
+Android 2.3 compared to <a href="#icon1">previous versions</a>. <strong>To
+provide support for all Android versions</strong>, developers should:
+<br>
+1. Place status bar icons for Android 2.3 and higher in the
+<code>drawable-hdpi-v9</code>, <code>drawable-mdpi-v9</code>, and <code>drawable-ldpi-v9</code> directories.
+<br>
+2. Place status bar icons for previous versions in
+<code>drawable-hdpi</code>, <code>drawable-mdpi</code>, and <code>drawable-ldpi</code> directories.
+
+</p>
+
+
+
+<h2 id="icon9">Android 2.3 and Later</h2>
+
+<p>The following guidelines describe how to design status bar icons for Android
+2.3 (API Level 9) and later.</p>
+
+<h3 id="size9">Size and positioning</h3>
+
+<p>Status bar icons should use simple shapes and forms and those must be
+scaled and positioned inside the final asset.</p>
+
+<p>Figure 1 illustrates various ways of positioning the icon inside the
+asset. You should size the icons <em>smaller than the actual bounds of the
+asset</em>. <strong>Status bar icons may vary in width, but only
+minimally.</strong></p>
+
+<p>In order to indicate the recommended size for the icon, each example in
+Figure 1 includes two different guide rectangles:</p>
+
+<ul>
+<li>The red box is the bounding box for the full asset.</li>
+<li>The blue box is the recommended bounding box for the actual icon.
+The icon box is sized smaller vertically than the full asset box to allow for
+varying icon shapes while maintaining a consistent visual weight.</li>
+</ul>
+
+<table>
+<tr>
+
+<td style="border:0;">
+<ol class="nolist">
+  <li>Status bar icon dimensions for high-density (<code>hdpi</code>) screens:</li>
+  <ol class="nolist">
+    <li>Full Asset: 24w x 38h px (preferred, width may vary)</li>
+    <li>Icon: 24w x 24h px (preferred, width may vary)</li>
+  </ol>
+  </li>
+</ol>
+</td>
+<td style="border:0;">
+  <img src="{@docRoot}images/icon_design/statusbar_size_hdpi.png" width="318">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Status bar icon dimensions for medium-density (<code>mdpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 16w x 25 px (preferred, width may vary)</li>
+      <li>Icon: 16w x 16w px (preferred, width may vary)</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/statusbar_size_mdpi.png" width="318">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Status bar icon dimensions for low-density (<code>ldpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 12w x 19h px (preferred, width may vary)</li>
+      <li>Icon: 12w x 12h px (preferred, width may vary)</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/statusbar_size_ldpi.png" width="318">
+</td>
+</tr>
+
+<tr>
+<td style="border:0;"></td>
+<td style="border:0;">
+ <p class="table-caption"><strong>Figure 1.</strong>
+ Status bar icon sizing and positioning inside the bounds of the
+ icon asset.</p>
+</td>
+</tr>
+
+</table>
+
+
+
+
+<h3 id="style9">Style, colors, and effects</h3>
+
+<p>Status bar icons are flat, matte, and pictured face-on.</p>
+
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/statusbar_style.png" alt="A view of effects for status bar icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 2. </strong>Style and effects for status icons.</p>
+    <div class="image-caption-nested">
+    <p><em>Note: all pixel dimensions are for medium density and should be scaled appropriately for other densities.</em></p>
+    <table>
+    <tr><td><em>1.</em></td><td nowrap>Fill gradient:</td><td>90&deg;, from <code>#828282</code> to <code>#919191</code><br><br></td></tr>
+    <tr><td><em>2.</em></td><td nowrap>Inner shadow:</td><td><code>#FFFFFF</code>, 10% opacity<br>angle 90&deg;<br>distance 1px<br>size 0px<br><br></td></tr>
+    <tr><td><em>3.</em></td><td nowrap>Inner content:</td><td>Inner content should subtract from the outer shape and consist purely of transparent pixels.</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+
+
+<h3 id="dosdonts9">Do's and don'ts</h3>
+
+<p>Below are some "do and don't" examples to consider when creating status bar icons for
+your application. </p>
+
+
+<img src="{@docRoot}images/icon_design/do_dont_statusicons.png">
+
+
+
+
+<h3 id="examples9">Example icons</h3>
+
+<p>Shown below are standard high-density status bar icons that are used in
+the Android platform.</p>
+
+<p class="warning"><strong>Warning:</strong> Because these resources can change
+between platform versions, you should not reference these icons using the
+Android platform resource IDs (i.e. status bar icons under
+<code>android.R.drawable</code>). If you want to use any icons or other internal
+drawable resources, you should store a local copy of those icons or drawables in
+your application resources, then reference the local copy from your application
+code. In that way, you can maintain control over the appearance of your icons,
+even if the system's copy changes. Note that the grid below is not intended to
+be complete.</p>
+
+<img src="{@docRoot}images/icon_design/statusbar_standard.png" />
+
+
+
+<h2 id="icon1">Android 2.2 and Earlier</h2>
+
+<p>The following guidelines describe how to design status bar icons for Android
+2.2 (API Level 8) and earlier.</p>
+
+<h3 id="structure1">Structure</h3>
+
+<ul>
+<li>Rounded corners must always be applied to the base shape and to the details
+of a status bar icon shown Figure 3.</li>
+
+<li>All dimensions specified are based on a 25x25 pixel artboard size with a 2
+pixel safeframe.</li>
+
+<li>Status bar icons can overlap the safeframe to the left and right when
+necessary, but must not overlap the safeframe at the top and bottom.</li>
+
+<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
+
+<li>Templates for creating status bar icons using Adobe Photoshop are available
+in the Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/statusbar_structure.png" alt="A view of
+status bar icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 3. </strong>Safeframe and corner-rounding for status bar
+icons. Icon size is 25x25.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<h3 id="style1">Light, effects, and shadows</h3>
+
+<p>Status bar icons are slightly debossed, high in contrast, and pictured
+face-on to enhance clarity at small sizes.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/statusbar_light.png"/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 4. </strong>Light, effects, and shadows for status bar icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
+    <tr><td><em>2.</em></td><td>Inner bevel:</td><td>depth 100% | direction down<br>size 0px | angle 90° |<br>altitude 30°<br>highlight white 75% opacity<br>shadow black 75% opacity</td></tr>
+    <tr><td><em>3.</em></td><td>Detail:</td><td>white</td></tr>
+    <tr><td><em>4.</em></td><td>Disabled detail:</td><td>grey gradient from palette<br>+ inner bevel: smooth | depth 1% | direction down | size 0px | angle 117° | <br>altitude 42° | highlight white 70% | no shadow</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table>
+<tr>
+<td style="border:0">
+
+<h4 id="palette1">Color palette</h4>
+
+<p>Only status bar icons related to the phone function use full color; all other status bar icons should remain monochromatic.</p>
+
+<table>
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_white.png"/></td>
+<td class="image-caption-c">White<br>r 255 | g 255 | b 255<br>Used for details within the icons and bevel highlight.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png"/></td>
+<td class="image-caption-c">Grey gradient<br><em>1:&nbsp;&nbsp;</em>r 169 | g 169 | b 169<br><em>2:&nbsp;&nbsp;</em>r 126 | g 126 | b 126<br>Used for disabled details within the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png"/></td>
+<td class="image-caption-c">Fill gradient<br><em>1:&nbsp;&nbsp;</em>1 r 105 | g 105 | b 105<br><em>2:&nbsp;&nbsp;</em>r 10   | g 10   | b 10<br>Used as color fill.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_black.png"/></td>
+<td class="image-caption-c">Black<br>r 0 | g 0 | b 0<br>Used for bevel shadow.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0">
+
+<h4 id="steps1">Step by step</h4>
+
+<ol>
+<li>In a tool like Adobe Photoshop, create the base shape within a 25x25 px
+image on a transparent background. Mind the safeframe, and keep the upper and
+lower 2 pixels free.</li>
+<li>Add rounded corners as specified in Figure 3.</li>
+<li>Add light, effects, and shadows as specified in Figure 4.</li>
+<li>Export the icon at 25x25 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_tab.jd b/docs/html/guide/practices/ui_guidelines/icon_design_tab.jd
new file mode 100644
index 0000000..1f96c3e
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_tab.jd
@@ -0,0 +1,454 @@
+page.title=Tab Icons
+parent.title=Icon Design Guidelines
+parent.link=icon_design.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#tabstates">Providing Icons for Two Tab States</a>
+<li><a href="#icon5">Android 2.0 and Later</a>
+  <ol>
+    <li><a href="#size5">Size</a></li>
+    <li><a href="#style5">Style, colors, and effects</a></li>
+    <li><a href="#dodonts5">Do's and don'ts</a></li>
+    <li><a href="#examples5">Example icons</a></li>
+  </ol>
+</li>
+<li><a href="#icon1">Android 1.6 and Earlier</a></li>
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>Tab icons are graphical elements used to represent individual tabs in a
+multi-tab interface. Each tab icon has two states: unselected and selected.</p>
+
+<p>As described in <a href="icon_design.html#icon-sets">Providing
+Density-Specific Icon Sets</a>, you should create separate icon sets for low-,
+medium-, and high-density screens. This ensures that your icons will display
+properly across the range of devices on which your application can be installed.
+See <a href="icon_design.html#design-tips">Tips for Designers</a>
+for suggestions on how to work with multiple sets of icons.</p>
+
+<p><strong>Final art must be exported as a transparent PNG file. Do not include
+a background color</strong>.</p>
+
+<p>Templates for creating icons in Adobe Photoshop are available in the <a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design.html#templatespack">Icon
+Templates Pack</a>.</p>
+
+
+
+<p class="warning"><strong>Warning:</strong>
+
+The style of tab icons has changed drastically in
+Android 2.0 compared to <a href="#icon1">previous versions</a>. <strong>To
+provide support for all Android versions</strong>, developers should:
+<br>
+1. Place tab icons for Android 2.0 and higher in the
+<code>drawable-hdpi-v5</code>, <code>drawable-mdpi-v5</code>, and <code>drawable-ldpi-v5</code> directories.
+<br>
+2. Place tab icons for previous versions in
+<code>drawable-hdpi</code>, <code>drawable-mdpi</code>, and <code>drawable-ldpi</code> directories.
+<br>
+3. Set <code>android:targetSdkVersion</code> to 5 or higher in the
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a>
+in the <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">application manifest</a>.
+This will inform the system that it should render tabs using the new tab style.
+
+</p>
+
+
+<h2 id="tabstates">Providing Icons for Two Tab States</h2>
+
+<p>Tab icons should have two states: unselected and selected. To provide icons
+with multiple states, developers must create a
+<a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state
+list drawable</a> for each an icon, which is an XML file that lists which image
+to use for the different UI states.</p>
+
+<p>For example, for a tab widget with tabs named 'Friends' and 'Coworkers',
+you can use a directory structure similar to the one below:</p>
+
+<pre>res/...
+    drawable/...
+        <strong>ic_tab_friends.xml</strong>
+        <strong>ic_tab_coworkers.xml</strong>
+    drawable-ldpi/...
+        ic_tab_friends_selected.png
+        ic_tab_friends_unselected.png
+        ic_tab_coworkers_selected.png
+        ic_tab_coworkers_unselected.png
+    drawable-mdpi/...
+        ic_tab_friends_selected.png
+        ic_tab_friends_unselected.png
+        ic_tab_coworkers_selected.png
+        ic_tab_coworkers_unselected.png
+    drawable-hdpi/...
+        ...
+    drawable-ldpi-v5/...
+        ...
+    drawable-mdpi-v5/...
+        ...
+    drawable-hdpi-v5/...
+        ...</pre>
+
+<p>The contents of the XML files listed above should reference the corresponding
+selected and unselected icon drawables. For example, below is the code
+for <code>ic_tab_friends.xml</code>:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+    &lt;!-- selected state --&gt;
+    &lt;item android:drawable="@drawable/ic_tab_friends_selected"
+          android:state_selected="true"
+          android:state_pressed="false" /&gt;
+    &lt;!-- unselected state (default) --&gt;
+    &lt;item android:drawable="@drawable/ic_tab_friends_unselected" /&gt;
+&lt;/selector&gt;
+</pre>
+
+
+
+
+<h2 id="icon5">Android 2.0 and Later</h2>
+
+<p>The following guidelines describe how to design tab icons for Android
+2.0 (API Level 5) and later.</p>
+
+<h3 id="size5">Size and positioning</h3>
+
+<p>Tab icons should use simple shapes and forms and those must be
+scaled and positioned inside the final asset.</p>
+
+<p>Figure 1 illustrates various ways of positioning the icon inside the
+asset. You should size the icons <em>smaller than the actual bounds of the
+asset</em>.</p>
+
+<p>In order to indicate the recommended size for the icon, each example in
+Figure 1 includes three different guide rectangles:</p>
+
+<ul>
+<li>The red box is the bounding box for the full asset.</li>
+<li>The blue box is the recommended bounding box for the actual icon.
+The icon box is sized smaller than the full asset box to allow for
+special icon treatments.</li>
+<li>The orange box is the recommended bounding box for the actual icon when
+the content is square. The box for square icons is smaller than that for other
+icons to establish a consistent visual weight across the two types.</li>
+</ul>
+
+
+<table>
+<tr>
+
+<td style="border:0;">
+<ol class="nolist">
+  <li>Tab icon dimensions for high-density (<code>hdpi</code>) screens:</li>
+  <ol class="nolist">
+    <li>Full Asset: 48 x 48 px</li>
+    <li>Icon: 42 x 42 px</li>
+  </ol>
+  </li>
+</ol>
+</td>
+<td style="border:0;">
+  <img src="{@docRoot}images/icon_design/tab_size_hdpi.png" width="385">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Tab icon dimensions for medium-density (<code>mdpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 32 x 32 px</li>
+      <li>Icon: 28 x 28 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/tab_size_mdpi.png" width="385">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Tab icon dimensions for low-density (<code>ldpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 24 x 24 px</li>
+      <li>Icon: 22 x 22 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;">
+ <img src="{@docRoot}images/icon_design/tab_size_ldpi.png" width="385">
+</td>
+</tr>
+
+<tr>
+<td style="border:0;"></td>
+<td style="border:0;">
+ <p class="table-caption"><strong>Figure 1.</strong>
+ Tab icon sizing and positioning inside the bounds of the
+ icon asset.</p>
+</td>
+</tr>
+
+</table>
+
+
+
+
+<h3 id="style5">Style, colors, and effects</h3>
+
+<p>Tab icons are flat, matte, and pictured face-on.</p>
+
+<p>Tab icons should have two states: selected and unselected.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_style_unselected.png" alt="A view of effects for unselected tab icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 2. </strong>Style and effects for unselected tab icons.</p>
+    <div class="image-caption-nested">
+    <p><em>Note: all pixel dimensions are for medium density and should be scaled appropriately for other densities.</em></p>
+    <table>
+    <tr><td><em>1.</em></td><td nowrap>Fill color:</td><td><code>#808080</code><br><br></td></tr>
+    <tr><td><em>2.</em></td><td nowrap>Inner content:</td><td>Inner content should subtract from the outer shape and consist purely of transparent pixels.</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_style_selected.png" alt="A view of effects for selected tab icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 3. </strong>Style and effects for selected tab icons.</p>
+    <div class="image-caption-nested">
+    <p><em>Note: all pixel dimensions are for medium density and should be scaled appropriately for other densities.</em></p>
+    <table>
+      <tr><td><em>1.</em></td><td nowrap>Fill color:</td><td><code>#FFFFFF</code><br><br></td></tr>
+      <tr><td><em>2.</em></td><td nowrap>Inner content:</td><td>Inner content should subtract from the outer shape and consist purely of transparent pixels.<br><br></td></tr>
+      <tr><td><em>3.</em></td><td nowrap>Outer glow:</td><td><code>#000000</code>, 25% opacity<br>size 3px</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+
+<h3 id="dosdonts5">Do's and don'ts</h3>
+
+<p>Below are some "do and don't" examples to consider when creating tab icons for
+your application. </p>
+
+
+<img src="{@docRoot}images/icon_design/do_dont_tabicons.png">
+
+
+
+
+<h3 id="examples5">Example icons</h3>
+
+<p>Shown below are standard high-density tab icons that are used in
+the Android platform.</p>
+
+<p class="warning"><strong>Warning:</strong>
+Because these resources can change between platform versions, you 
+should not reference the system's copy of the resources. If you want to
+use any icons or other internal drawable resources, you should store a
+local copy of those icons or drawables in your application resources, 
+then reference the local copy from your application code. In that way, you can
+maintain control over the appearance of your icons, even if the system's
+copy changes. Note that the grid below is not intended to be complete.</p>
+
+<img src="{@docRoot}images/icon_design/tab_standard.png" />
+
+
+
+<h2 id="icon1">Android 1.6 and Earlier</h2>
+
+<p>The following guidelines describe how to design tab icons for Android
+1.6 (API Level 4) and earlier.</p>
+
+<h4 id="structure1">Structure</h4>
+
+<ul>
+<li>Unselected tab icons have the same fill gradient and effects as
+<a href="icon_design_menu.html#icon1">menu icons</a>,
+but with no outer glow.</li>
+
+<li>Selected tab icons look just like unselected tab icons, but with a fainter
+inner shadow, and have the same front part gradient as
+<a href="icon_design_dialog.html#icon1">dialog icons</a>.</li>
+
+<li>Tab icons have a 1 px safeframe which should only be overlapped for the edge
+of the anti-alias of a round shape.</li>
+
+<li>All dimensions specified on this page are based on a 32x32 px artboard size.
+Keep 1 px of padding around the bounding box inside the Photoshop template.</li>
+
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_icon_unselected.png" alt="A view of
+unselected tab icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 3. </strong>Safeframe and fill gradient for unselected tab
+icons. Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_icon_selected.png" alt="A view of
+selected tab icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 4. </strong>Safeframe and fill gradient for tab icons in
+selected state. Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+<h3 id="unselectedtabdetails1">Unselected tab icon</h3>
+
+<h4 id="unselectedtablight1">Light, effects, and shadows</h4>
+
+<p>Unselected tab icons look just like the selected tab icons, but with a
+fainter inner shadow, and the same front part gradient as the dialog icons.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_unselected_light.png" alt="A view
+of light, effects, and shadows for unselected tab icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 5. </strong>Light, effects, and shadows for unselected
+tab icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom color: r 223 | g 223 | b 223<br>top color: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 10 % opacity | angle 90° distance 2px | size 2px</td></tr>
+    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<table>
+<tr>
+<td style="border:0">
+
+<h4 id="unselectedtabsteps1">Step by step</h4>
+
+<ol>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape to a tool like Adobe Photoshop and scale to fit an image of
+32x32 px on a transparent background.</li>
+<li>Add the effects seen in Figure 5 for the unselected state filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+<h3 id="selectedtabdetails1">Selected tab icon</h3>
+
+<p>The selected tab icons have the same fill gradient and effects as the menu
+icon, but with no outer glow.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_selected_light.png" alt="A view of
+light, effects, and shadows for selected tab icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 6. </strong>Light, effects, and shadows for selected tab
+icons.</p>
+    <div class="image-caption-nested">
+    <table>
+    <tr><td><em>1.</em></td><td>Front part:</td><td>Use fill gradient from color palette.</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20% opacity | <br>angle 90° | distance 2px | <br>size 2px</td></tr>
+    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | <br>altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table>
+<tr>
+<td style="border:0">
+
+<h4 id="selectedtabpalette1">Color palette</h4>
+
+<table>
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png"/></td>
+<td class="image-caption-c">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill on unselected tab icons.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0">
+
+<h4 id="selectedtabsteps1">Step by step</h4>
+
+<ol>
+<li>Create the basic shape using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit a 32x32
+px artboard with a transparent background. </li>
+<li>Add the effects seen in Figure 6 for the selected state filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
diff --git a/docs/html/guide/practices/ui_guidelines/index.jd b/docs/html/guide/practices/ui_guidelines/index.jd
index ea3551d..cb34d2e 100644
--- a/docs/html/guide/practices/ui_guidelines/index.jd
+++ b/docs/html/guide/practices/ui_guidelines/index.jd
@@ -12,7 +12,7 @@
  <dl>
   <dt><a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon
 Design Guidelines</a> and <a
-href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon Templates Pack
+href="{@docRoot}shareables/icon_templates-v2.3.zip">Android Icon Templates Pack
 &raquo; </a></dt>
   <dd>Your applications need a wide variety of icons, from a launcher icon to
 icons in menus, dialogs, tabs, the status bar, and lists. The Icon Guidelines
diff --git a/docs/html/images/icon_design/IconGraphic_Colors.png b/docs/html/images/icon_design/IconGraphic_Colors.png
index f70eefc..7723add 100644
--- a/docs/html/images/icon_design/IconGraphic_Colors.png
+++ b/docs/html/images/icon_design/IconGraphic_Colors.png
Binary files differ
diff --git a/docs/html/images/icon_design/do_dont_statusicons.png b/docs/html/images/icon_design/do_dont_statusicons.png
index 20c6737..731a202 100644
--- a/docs/html/images/icon_design/do_dont_statusicons.png
+++ b/docs/html/images/icon_design/do_dont_statusicons.png
Binary files differ
diff --git a/docs/html/images/icon_design/do_dont_tabicons.png b/docs/html/images/icon_design/do_dont_tabicons.png
new file mode 100644
index 0000000..06171b3
--- /dev/null
+++ b/docs/html/images/icon_design/do_dont_tabicons.png
Binary files differ
diff --git a/docs/html/images/icon_design/launcher_size_hdpi.png b/docs/html/images/icon_design/launcher_size_hdpi.png
new file mode 100644
index 0000000..e3f747f
--- /dev/null
+++ b/docs/html/images/icon_design/launcher_size_hdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/launcher_size_ldpi.png b/docs/html/images/icon_design/launcher_size_ldpi.png
new file mode 100644
index 0000000..91e87da
--- /dev/null
+++ b/docs/html/images/icon_design/launcher_size_ldpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/launcher_size_mdpi.png b/docs/html/images/icon_design/launcher_size_mdpi.png
new file mode 100644
index 0000000..e8da941
--- /dev/null
+++ b/docs/html/images/icon_design/launcher_size_mdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/launcher_structure.png b/docs/html/images/icon_design/launcher_structure.png
index 53e4d9a..b48173a 100644
--- a/docs/html/images/icon_design/launcher_structure.png
+++ b/docs/html/images/icon_design/launcher_structure.png
Binary files differ
diff --git a/docs/html/images/icon_design/launcher_style.png b/docs/html/images/icon_design/launcher_style.png
new file mode 100644
index 0000000..c4d2c6b
--- /dev/null
+++ b/docs/html/images/icon_design/launcher_style.png
Binary files differ
diff --git a/docs/html/images/icon_design/menu_size_hdpi.png b/docs/html/images/icon_design/menu_size_hdpi.png
new file mode 100644
index 0000000..597bbff
--- /dev/null
+++ b/docs/html/images/icon_design/menu_size_hdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/menu_size_ldpi.png b/docs/html/images/icon_design/menu_size_ldpi.png
new file mode 100644
index 0000000..6b521e1
--- /dev/null
+++ b/docs/html/images/icon_design/menu_size_ldpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/menu_size_mdpi.png b/docs/html/images/icon_design/menu_size_mdpi.png
new file mode 100644
index 0000000..9552991
--- /dev/null
+++ b/docs/html/images/icon_design/menu_size_mdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/menu_standard.png b/docs/html/images/icon_design/menu_standard.png
new file mode 100644
index 0000000..e50b74a
--- /dev/null
+++ b/docs/html/images/icon_design/menu_standard.png
Binary files differ
diff --git a/docs/html/images/icon_design/menu_style.png b/docs/html/images/icon_design/menu_style.png
new file mode 100644
index 0000000..030495a
--- /dev/null
+++ b/docs/html/images/icon_design/menu_style.png
Binary files differ
diff --git a/docs/html/images/icon_design/statusbar_size_hdpi.png b/docs/html/images/icon_design/statusbar_size_hdpi.png
new file mode 100644
index 0000000..caa4047
--- /dev/null
+++ b/docs/html/images/icon_design/statusbar_size_hdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/statusbar_size_ldpi.png b/docs/html/images/icon_design/statusbar_size_ldpi.png
new file mode 100644
index 0000000..1fe5c25
--- /dev/null
+++ b/docs/html/images/icon_design/statusbar_size_ldpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/statusbar_size_mdpi.png b/docs/html/images/icon_design/statusbar_size_mdpi.png
new file mode 100644
index 0000000..626ff60
--- /dev/null
+++ b/docs/html/images/icon_design/statusbar_size_mdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/statusbar_standard.png b/docs/html/images/icon_design/statusbar_standard.png
new file mode 100644
index 0000000..260e8e9
--- /dev/null
+++ b/docs/html/images/icon_design/statusbar_standard.png
Binary files differ
diff --git a/docs/html/images/icon_design/statusbar_style.png b/docs/html/images/icon_design/statusbar_style.png
new file mode 100644
index 0000000..3beb6ad
--- /dev/null
+++ b/docs/html/images/icon_design/statusbar_style.png
Binary files differ
diff --git a/docs/html/images/icon_design/tab_size_hdpi.png b/docs/html/images/icon_design/tab_size_hdpi.png
new file mode 100644
index 0000000..0e3a5c1
--- /dev/null
+++ b/docs/html/images/icon_design/tab_size_hdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/tab_size_ldpi.png b/docs/html/images/icon_design/tab_size_ldpi.png
new file mode 100644
index 0000000..cb361ca
--- /dev/null
+++ b/docs/html/images/icon_design/tab_size_ldpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/tab_size_mdpi.png b/docs/html/images/icon_design/tab_size_mdpi.png
new file mode 100644
index 0000000..557b491
--- /dev/null
+++ b/docs/html/images/icon_design/tab_size_mdpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/tab_standard.png b/docs/html/images/icon_design/tab_standard.png
new file mode 100644
index 0000000..7f07297
--- /dev/null
+++ b/docs/html/images/icon_design/tab_standard.png
Binary files differ
diff --git a/docs/html/images/icon_design/tab_style_selected.png b/docs/html/images/icon_design/tab_style_selected.png
new file mode 100644
index 0000000..e6f383e
--- /dev/null
+++ b/docs/html/images/icon_design/tab_style_selected.png
Binary files differ
diff --git a/docs/html/images/icon_design/tab_style_unselected.png b/docs/html/images/icon_design/tab_style_unselected.png
new file mode 100644
index 0000000..426e7c9
--- /dev/null
+++ b/docs/html/images/icon_design/tab_style_unselected.png
Binary files differ
diff --git a/docs/html/sdk/preview/features.jd b/docs/html/sdk/preview/features.jd
index 55d0f8d..cd0dea1 100644
--- a/docs/html/sdk/preview/features.jd
+++ b/docs/html/sdk/preview/features.jd
@@ -160,11 +160,12 @@
 and APIs introduced for Android 2.3. To learn more, read the <a
 href="{@docRoot}sdk/android-2.3.html">Android 2.3 release notes</a>.</p>
 
+<!--
 <div class="special">
 <p>To set up your preview SDK and start developing apps for Honeycomb, see the <a
 href="{@docRoot}sdk/preview/installing.html">Getting Started</a> guide.</p>
 </div>
-
+-->
 
 
 
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index fe71914..3366c5c 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -43,8 +43,10 @@
     <ul>
       <li><a href="<?cs var:toroot ?>sdk/preview/features.html">Introduction
 to Honeycomb</a></li>
+<!--
       <li><a href="<?cs var:toroot ?>sdk/preview/installing.html">Getting
 Started</a></li>
+-->
     </ul>
   </li><?cs
   /if ?>
diff --git a/docs/html/shareables/icon_templates-v2.3.zip b/docs/html/shareables/icon_templates-v2.3.zip
new file mode 100644
index 0000000..58d90ae
--- /dev/null
+++ b/docs/html/shareables/icon_templates-v2.3.zip
Binary files differ
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index b937721..30475bd 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -378,12 +378,12 @@
         mBitmapOptions.inScaled = false;
     }
 
-    static public Allocation createTyped(RenderScript rs, Type type, int usage) {
+    static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mc, int usage) {
         rs.validate();
         if (type.getID() == 0) {
             throw new RSInvalidStateException("Bad Type");
         }
-        int id = rs.nAllocationCreateTyped(type.getID(), usage);
+        int id = rs.nAllocationCreateTyped(type.getID(), mc.mID, usage);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -391,7 +391,7 @@
     }
 
     static public Allocation createTyped(RenderScript rs, Type type) {
-        return createTyped(rs, type, USAGE_ALL);
+        return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
     }
 
     static public Allocation createSized(RenderScript rs, Element e,
@@ -401,7 +401,7 @@
         b.setX(count);
         Type t = b.create();
 
-        int id = rs.nAllocationCreateTyped(t.getID(), usage);
+        int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
@@ -409,7 +409,7 @@
     }
 
     static public Allocation createSized(RenderScript rs, Element e, int count) {
-        return createSized(rs, e, count, USAGE_ALL);
+        return createSized(rs, e, count, USAGE_SCRIPT);
     }
 
     static private Element elementFromBitmap(RenderScript rs, Bitmap b) {
@@ -458,7 +458,7 @@
         if (genMips) {
             mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
         }
-        return createFromBitmap(rs, b, mc, USAGE_ALL);
+        return createFromBitmap(rs, b, mc, USAGE_GRAPHICS_TEXTURE);
     }
 
     static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
@@ -507,7 +507,7 @@
         if (genMips) {
             mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
         }
-        return createCubemapFromBitmap(rs, b, mc, layout, USAGE_ALL);
+        return createCubemapFromBitmap(rs, b, mc, layout, USAGE_GRAPHICS_TEXTURE);
     }
 
     static public Allocation createFromBitmapResource(RenderScript rs,
@@ -532,7 +532,7 @@
         if (genMips) {
             mc = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
         }
-        return createFromBitmapResource(rs, res, id, mc, USAGE_ALL);
+        return createFromBitmapResource(rs, res, id, mc, USAGE_GRAPHICS_TEXTURE);
     }
 
     static public Allocation createFromString(RenderScript rs,
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index 44faa32..b103af4 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -77,18 +77,14 @@
 
         for(int i = 0; i < vtxCount; i ++) {
             if(vtxIDs[i] != 0) {
-                mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null,
-                                                   Allocation.USAGE_GRAPHICS_VERTEX |
-                                                   Allocation.USAGE_SCRIPT);
+                mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
                 mVertexBuffers[i].updateFromNative();
             }
         }
 
         for(int i = 0; i < idxCount; i ++) {
             if(idxIDs[i] != 0) {
-                mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null,
-                                                  Allocation.USAGE_GRAPHICS_VERTEX |
-                                                  Allocation.USAGE_SCRIPT);
+                mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
                 mIndexBuffers[i].updateFromNative();
             }
             mPrimitives[i] = Primitive.values()[primitives[i]];
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 0211a4a..507f41f 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -119,7 +119,7 @@
     }
 
     public RenderScriptGL createRenderScriptGL(RenderScriptGL.SurfaceConfig sc) {
-        RenderScriptGL rs = new RenderScriptGL(sc);
+      RenderScriptGL rs = new RenderScriptGL(this.getContext(), sc);
         setRenderScriptGL(rs);
         return rs;
     }
@@ -137,4 +137,3 @@
         return mRS;
     }
 }
-
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 3fa9965..5f93f5b 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -18,6 +18,7 @@
 
 import java.lang.reflect.Field;
 
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.util.Config;
@@ -42,9 +43,9 @@
     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
     static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
 
+    private Context mApplicationContext;
 
-
-     /*
+    /*
      * We use a class initializer to allow the native code to cache some
      * field offsets.
      */
@@ -191,9 +192,9 @@
         rsnTypeGetNativeData(mContext, id, typeData);
     }
 
-    native int  rsnAllocationCreateTyped(int con, int type, int usage);
-    synchronized int nAllocationCreateTyped(int type, int usage) {
-        return rsnAllocationCreateTyped(mContext, type, usage);
+    native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage);
+    synchronized int nAllocationCreateTyped(int type, int mip, int usage) {
+        return rsnAllocationCreateTyped(mContext, type, mip, usage);
     }
     native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
     synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
@@ -416,9 +417,9 @@
     synchronized void nScriptCSetScript(byte[] script, int offset, int length) {
         rsnScriptCSetScript(mContext, script, offset, length);
     }
-    native int  rsnScriptCCreate(int con, String val);
-    synchronized int nScriptCCreate(String val) {
-        return rsnScriptCCreate(mContext, val);
+    native int  rsnScriptCCreate(int con, String val, String cacheDir);
+    synchronized int nScriptCCreate(String resName, String cacheDir) {
+      return rsnScriptCCreate(mContext, resName, cacheDir);
     }
 
     native void rsnSamplerBegin(int con);
@@ -776,17 +777,27 @@
         }
     }
 
-    RenderScript() {
+    RenderScript(Context ctx) {
+        mApplicationContext = ctx.getApplicationContext();
+    }
+
+    /**
+     * Gets the application context associated with the RenderScript context.
+     *
+     * @return The application context.
+     */
+    public final Context getApplicationContext() {
+        return mApplicationContext;
     }
 
     /**
      * Create a basic RenderScript context.
      *
-     *
+     * @param ctx The context.
      * @return RenderScript
      */
-    public static RenderScript create() {
-        RenderScript rs = new RenderScript();
+    public static RenderScript create(Context ctx) {
+        RenderScript rs = new RenderScript(ctx);
 
         rs.mDev = rs.nDeviceCreate();
         rs.mContext = rs.nContextCreate(rs.mDev, 0);
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 0886db4..5adb682 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -18,6 +18,7 @@
 
 import java.lang.reflect.Field;
 
+import android.content.Context;
 import android.graphics.PixelFormat;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -168,10 +169,11 @@
     /**
      * Construct a new RenderScriptGL context.
      *
-     *
+     * @param ctx The context.
      * @param sc The desired format of the primart rendering surface.
      */
-    public RenderScriptGL(SurfaceConfig sc) {
+    public RenderScriptGL(Context ctx, SurfaceConfig sc) {
+        super(ctx);
         mSurfaceConfig = new SurfaceConfig(sc);
 
         mSurface = null;
@@ -304,5 +306,3 @@
     }
 
 }
-
-
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 64ed75b..b10247c 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -16,9 +16,11 @@
 
 package android.renderscript;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.util.Log;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map.Entry;
@@ -76,6 +78,7 @@
         rs.nScriptCBegin();
         rs.nScriptCSetScript(pgm, 0, pgmLength);
         Log.v(TAG, "Create script for resource = " + resources.getResourceName(resourceID));
-        return rs.nScriptCCreate(resources.getResourceName(resourceID));
+        String cacheDir = rs.getApplicationContext().getCacheDir().toString();
+        return rs.nScriptCCreate(resources.getResourceName(resourceID), cacheDir);
     }
 }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 8344842..a8343b3 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -377,8 +377,8 @@
 static jint
 nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage)
 {
-    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i)", con, (RsElement)type, mip, usage);
-    return (jint) rsaAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapGenerationControl)mips, (uint32_t)usage);
+    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i)", con, (RsElement)type, mips, usage);
+    return (jint) rsaAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage);
 }
 
 static void
@@ -411,7 +411,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsaAllocationCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapGenerationControl)mip, ptr, usage);
+    jint id = (jint)rsaAllocationCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapControl)mip, ptr, usage);
     bitmap.unlockPixels();
     return id;
 }
@@ -425,7 +425,7 @@
 
     bitmap.lockPixels();
     const void* ptr = bitmap.getPixels();
-    jint id = (jint)rsaAllocationCubeCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapGenerationControl)mip, ptr, usage);
+    jint id = (jint)rsaAllocationCubeCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapControl)mip, ptr, usage);
     bitmap.unlockPixels();
     return id;
 }
@@ -902,11 +902,15 @@
 }
 
 static jint
-nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con, jstring resName)
+nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con, jstring resName, jstring cacheDir)
 {
     LOG_API("nScriptCCreate, con(%p)", con);
     const char* resNameUTF = _env->GetStringUTFChars(resName, NULL);
-    return (jint)rsScriptCCreate(con, resNameUTF);
+    const char* cacheDirUTF = _env->GetStringUTFChars(cacheDir, NULL);
+    jint i = (jint)rsScriptCCreate(con, resNameUTF, cacheDirUTF);
+    _env->ReleaseStringUTFChars(resName, resNameUTF);
+    _env->ReleaseStringUTFChars(cacheDir, cacheDirUTF);
+    return i;
 }
 
 // ---------------------------------------------------------------------------
@@ -1245,7 +1249,7 @@
 {"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
 {"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
 
-{"rsnAllocationCreateTyped",         "(III)I",                                (void*)nAllocationCreateTyped },
+{"rsnAllocationCreateTyped",         "(IIII)I",                               (void*)nAllocationCreateTyped },
 {"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
 {"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
 
@@ -1297,7 +1301,7 @@
 
 {"rsnScriptCBegin",                  "(I)V",                                  (void*)nScriptCBegin },
 {"rsnScriptCSetScript",              "(I[BII)V",                              (void*)nScriptCSetScript },
-{"rsnScriptCCreate",                 "(ILjava/lang/String;)I",                (void*)nScriptCCreate },
+{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;)I",  (void*)nScriptCCreate },
 
 {"rsnProgramStoreBegin",             "(III)V",                                (void*)nProgramStoreBegin },
 {"rsnProgramStoreDepthFunc",         "(II)V",                                 (void*)nProgramStoreDepthFunc },
@@ -1372,4 +1376,3 @@
 bail:
     return result;
 }
-
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index b54718f..3378d97 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -33,6 +33,7 @@
 {
 public:
     static  IPCThreadState*     self();
+    static  IPCThreadState*     selfOrNull();  // self(), but won't instantiate
     
             sp<ProcessState>    process();
             
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index dafc621..a31395e 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -78,31 +78,18 @@
         void clearSeekTo();
         bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
 
-        // Option allows encoder to skip some frames until the specified
-        // time stamp.
-        // To prevent from being abused, when the skipFrame timestamp is
-        // found to be more than 1 second later than the current timestamp,
-        // an error will be returned from read().
-        void clearSkipFrame();
-        bool getSkipFrame(int64_t *timeUs) const;
-        void setSkipFrame(int64_t timeUs);
-
         void setLateBy(int64_t lateness_us);
         int64_t getLateBy() const;
 
     private:
         enum Options {
-            // Bit map
             kSeekTo_Option      = 1,
-            kSkipFrame_Option   = 2,
         };
 
         uint32_t mOptions;
         int64_t mSeekTimeUs;
         SeekMode mSeekMode;
         int64_t mLatenessUs;
-
-        int64_t mSkipFrameUntilTimeUs;
     };
 
     // Causes this source to suspend pulling data from its upstream source
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index d37c22d..bba5b53 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -167,7 +167,6 @@
     int64_t mSeekTimeUs;
     ReadOptions::SeekMode mSeekMode;
     int64_t mTargetTimeUs;
-    int64_t mSkipTimeUs;
 
     MediaBuffer *mLeftOverBuffer;
 
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 13c58f0..95cfddf 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -318,6 +318,16 @@
     goto restart;
 }
 
+IPCThreadState* IPCThreadState::selfOrNull()
+{
+    if (gHaveTLS) {
+        const pthread_key_t k = gTLS;
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+        return st;
+    }
+    return NULL;
+}
+
 void IPCThreadState::shutdown()
 {
     gShutdown = true;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 17b9e83..72c8950 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -723,13 +723,6 @@
 #endif
 }
 
-void OpenGLRenderer::setupDraw() {
-    clearLayerRegions();
-    if (mDirtyClip) {
-        setScissorFromClip();
-    }
-}
-
 void OpenGLRenderer::clearLayerRegions() {
     if (mLayers.size() == 0 || mSnapshot->isIgnored()) return;
 
@@ -832,6 +825,162 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Drawing commands
+///////////////////////////////////////////////////////////////////////////////
+
+void OpenGLRenderer::setupDraw() {
+    clearLayerRegions();
+    if (mDirtyClip) {
+        setScissorFromClip();
+    }
+    mDescription.reset();
+    mSetShaderColor = false;
+    mColorSet = false;
+    mColorA = mColorR = mColorG = mColorB = 0.0f;
+    mTextureUnit = 0;
+    mTrackDirtyRegions = true;
+}
+
+void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
+    mDescription.hasTexture = true;
+    mDescription.hasAlpha8Texture = isAlpha8;
+}
+
+void OpenGLRenderer::setupDrawColor(int color) {
+    mColorA = ((color >> 24) & 0xFF) / 255.0f;
+    const float a = mColorA / 255.0f;
+    mColorR = a * ((color >> 16) & 0xFF);
+    mColorG = a * ((color >>  8) & 0xFF);
+    mColorB = a * ((color      ) & 0xFF);
+    mColorSet = true;
+    mSetShaderColor = mDescription.setColor(mColorR, mColorG, mColorB, mColorA);
+}
+
+void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) {
+    mColorA = a;
+    mColorR = r;
+    mColorG = g;
+    mColorB = b;
+    mColorSet = true;
+    mSetShaderColor = mDescription.setColor(r, g, b, a);
+}
+
+void OpenGLRenderer::setupDrawShader() {
+    if (mShader) {
+        mShader->describe(mDescription, mCaches.extensions);
+    }
+}
+
+void OpenGLRenderer::setupDrawColorFilter() {
+    if (mColorFilter) {
+        mColorFilter->describe(mDescription, mCaches.extensions);
+    }
+}
+
+void OpenGLRenderer::setupDrawBlending(SkXfermode::Mode mode, bool swapSrcDst) {
+    chooseBlending((mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode,
+            mDescription, swapSrcDst);
+}
+
+void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool swapSrcDst) {
+    chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode,
+            mDescription, swapSrcDst);
+}
+
+void OpenGLRenderer::setupDrawProgram() {
+    useProgram(mCaches.programCache.get(mDescription));
+}
+
+void OpenGLRenderer::setupDrawDirtyRegionsDisabled() {
+    mTrackDirtyRegions = false;
+}
+
+void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float right, float bottom,
+        bool ignoreTransform) {
+    mModelView.loadTranslate(left, top, 0.0f);
+    if (!ignoreTransform) {
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+        if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
+    } else {
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mIdentity);
+        if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
+    }
+}
+
+void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom,
+        bool ignoreTransform, bool ignoreModelView) {
+    if (!ignoreModelView) {
+        mModelView.loadTranslate(left, top, 0.0f);
+        mModelView.scale(right - left, bottom - top, 1.0f);
+        if (!ignoreTransform) {
+            mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+            if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
+        } else {
+            mCaches.currentProgram->set(mOrthoMatrix, mModelView, mIdentity);
+            if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
+        }
+    } else {
+        mModelView.loadIdentity();
+    }
+}
+
+void OpenGLRenderer::setupDrawColorUniforms() {
+    if (mColorSet || (mShader && mSetShaderColor)) {
+        mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
+    }
+}
+
+void OpenGLRenderer::setupDrawColorAlphaUniforms() {
+    if (mSetShaderColor) {
+        mCaches.currentProgram->setColor(mColorA, mColorA, mColorA, mColorA);
+    }
+}
+
+void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) {
+    if (mShader) {
+        if (ignoreTransform) {
+            mModelView.loadInverse(*mSnapshot->transform);
+        }
+        mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &mTextureUnit);
+    }
+}
+
+void OpenGLRenderer::setupDrawColorFilterUniforms() {
+    if (mColorFilter) {
+        mColorFilter->setupProgram(mCaches.currentProgram);
+    }
+}
+
+void OpenGLRenderer::setupDrawSimpleMesh() {
+    mCaches.bindMeshBuffer();
+    glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
+            gMeshStride, 0);
+}
+
+void OpenGLRenderer::setupDrawTexture(GLuint texture) {
+    bindTexture(texture);
+    glUniform1i(mCaches.currentProgram->getUniform("sampler"), mTextureUnit++);
+
+    mTexCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
+    glEnableVertexAttribArray(mTexCoordsSlot);
+}
+
+void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
+    if (!vertices) {
+        mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
+    } else {
+        mCaches.unbindMeshBuffer();
+    }
+    glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
+            gMeshStride, vertices);
+    glVertexAttribPointer(mTexCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords);
+}
+
+void OpenGLRenderer::finishDrawTexture() {
+    glDisableVertexAttribArray(mTexCoordsSlot);
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Drawing
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -1043,18 +1192,16 @@
     glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
             gMeshStride, vertex);
 
-    mModelView.loadIdentity();
-
     // Build and use the appropriate shader
     useProgram(mCaches.programCache.get(description));
-    mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+    mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform);
 
     if (!mShader || (mShader && setColor)) {
         mCaches.currentProgram->setColor(r, g, b, a);
     }
 
     if (mShader) {
-        mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit);
+        mShader->setupProgram(mCaches.currentProgram, mIdentity, *mSnapshot, &textureUnit);
     }
     if (mColorFilter) {
         mColorFilter->setupProgram(mCaches.currentProgram);
@@ -1116,6 +1263,7 @@
 
     Rect& clip(*mSnapshot->clipRect);
     clip.snapToPixelBoundaries();
+
     drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
 }
 
@@ -1512,84 +1660,26 @@
 
 void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
         int color, SkXfermode::Mode mode, bool ignoreTransform) {
-    setupDraw();
-
     // If a shader is set, preserve only the alpha
     if (mShader) {
         color |= 0x00ffffff;
     }
 
-    // Render using pre-multiplied alpha
-    const int alpha = (color >> 24) & 0xFF;
-    const GLfloat a = alpha / 255.0f;
-    const GLfloat r = a * ((color >> 16) & 0xFF) / 255.0f;
-    const GLfloat g = a * ((color >>  8) & 0xFF) / 255.0f;
-    const GLfloat b = a * ((color      ) & 0xFF) / 255.0f;
+    setupDraw();
+    setupDrawColor(color);
+    setupDrawShader();
+    setupDrawColorFilter();
+    setupDrawBlending(mode);
+    setupDrawProgram();
+    setupDrawModelView(left, top, right, bottom, ignoreTransform);
+    setupDrawColorUniforms();
+    setupDrawShaderUniforms(ignoreTransform);
+    setupDrawColorFilterUniforms();
+    setupDrawSimpleMesh();
 
-    setupColorRect(left, top, right, bottom, r, g, b, a, mode, ignoreTransform);
-
-    // Draw the mesh
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
 }
 
-void OpenGLRenderer::setupColorRect(float left, float top, float right, float bottom,
-        float r, float g, float b, float a, SkXfermode::Mode mode,
-        bool ignoreTransform, bool ignoreMatrix) {
-    GLuint textureUnit = 0;
-
-    // Describe the required shaders
-    ProgramDescription description;
-    const bool setColor = description.setColor(r, g, b, a);
-
-    if (mShader) {
-        mShader->describe(description, mCaches.extensions);
-    }
-    if (mColorFilter) {
-        mColorFilter->describe(description, mCaches.extensions);
-    }
-
-    // Setup the blending mode
-    chooseBlending(a < 1.0f || (mShader && mShader->blend()), mode, description);
-
-    // Build and use the appropriate shader
-    useProgram(mCaches.programCache.get(description));
-
-    // Setup attributes
-    mCaches.bindMeshBuffer();
-    glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
-            gMeshStride, 0);
-
-    if (!ignoreMatrix) {
-        // Setup uniforms
-        mModelView.loadTranslate(left, top, 0.0f);
-        mModelView.scale(right - left, bottom - top, 1.0f);
-        if (!ignoreTransform) {
-            mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
-            dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
-        } else {
-            mat4 identity;
-            mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
-            dirtyLayer(left, top, right, bottom);
-        }
-    }
-    if (!mShader || (mShader && setColor)) {
-        mCaches.currentProgram->setColor(r, g, b, a);
-    }
-
-    // Setup attributes and uniforms required by the shaders
-    if (mShader) {
-        if (ignoreMatrix) {
-            mModelView.loadIdentity();
-        } else if (ignoreTransform) {
-            mModelView.loadInverse(*mSnapshot->transform);
-        }
-        mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit);
-    }
-    if (mColorFilter) {
-        mColorFilter->setupProgram(mCaches.currentProgram);
-    }
-}
-
 void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
         Texture* texture, SkPaint* paint) {
     int alpha;
@@ -1622,61 +1712,29 @@
         GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
         bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
+
     setupDraw();
-
-    ProgramDescription description;
-    description.hasTexture = true;
-    const bool setColor = description.setColor(alpha, alpha, alpha, alpha);
-    if (mColorFilter) {
-        mColorFilter->describe(description, mCaches.extensions);
+    setupDrawWithTexture();
+    setupDrawColor(alpha, alpha, alpha, alpha);
+    setupDrawColorFilter();
+    setupDrawBlending(blend, mode, swapSrcDst);
+    setupDrawProgram();
+    if (!dirty) {
+        setupDrawDirtyRegionsDisabled();
     }
-
-    mModelView.loadTranslate(left, top, 0.0f);
     if (!ignoreScale) {
-        mModelView.scale(right - left, bottom - top, 1.0f);
-    }
-
-    chooseBlending(blend || alpha < 1.0f, mode, description, swapSrcDst);
-
-    useProgram(mCaches.programCache.get(description));
-    if (!ignoreTransform) {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
-        if (dirty) dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
+        setupDrawModelView(left, top, right, bottom, ignoreTransform);
     } else {
-        mat4 identity;
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
-        if (dirty) dirtyLayer(left, top, right, bottom);
+        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
     }
-
-    // Texture
-    bindTexture(texture);
-    glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);
-
-    // Always premultiplied
-    if (setColor) {
-        mCaches.currentProgram->setColor(alpha, alpha, alpha, alpha);
-    }
-
-    // Mesh
-    int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
-    glEnableVertexAttribArray(texCoordsSlot);
-
-    if (!vertices) {
-        mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
-    } else {
-        mCaches.unbindMeshBuffer();
-    }
-    glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
-            gMeshStride, vertices);
-    glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords);
-
-    // Color filter
-    if (mColorFilter) {
-        mColorFilter->setupProgram(mCaches.currentProgram);
-    }
+    setupDrawColorAlphaUniforms();
+    setupDrawColorFilterUniforms();
+    setupDrawTexture(texture);
+    setupDrawMesh(vertices, texCoords, vbo);
 
     glDrawArrays(drawMode, 0, elementsCount);
-    glDisableVertexAttribArray(texCoordsSlot);
+
+    finishDrawTexture();
 }
 
 void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e866d1b4..5d8653d 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -221,13 +221,6 @@
             int color, SkXfermode::Mode mode, bool ignoreTransform = false);
 
     /**
-     * Setups shaders to draw a colored rect.
-     */
-    void setupColorRect(float left, float top, float right, float bottom,
-            float r, float g, float b, float a, SkXfermode::Mode mode,
-            bool ignoreTransform, bool ignoreMatrix = false);
-
-    /**
      * Draws a textured rectangle with the specified texture. The specified coordinates
      * are transformed by the current snapshot's transform matrix.
      *
@@ -431,6 +424,32 @@
      * Invoked before any drawing operation. This sets required state.
      */
     void setupDraw();
+    /**
+     * Various methods to setup OpenGL rendering.
+     */
+    void setupDrawWithTexture(bool isAlpha8 = false);
+    void setupDrawColor(int color);
+    void setupDrawColor(float r, float g, float b, float a);
+    void setupDrawShader();
+    void setupDrawColorFilter();
+    void setupDrawBlending(SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
+            bool swapSrcDst = false);
+    void setupDrawBlending(bool blend = true, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
+            bool swapSrcDst = false);
+    void setupDrawProgram();
+    void setupDrawDirtyRegionsDisabled();
+    void setupDrawModelView(float left, float top, float right, float bottom,
+            bool ignoreTransform = false, bool ignoreModelView = false);
+    void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
+            bool ignoreTransform = false);
+    void setupDrawColorUniforms();
+    void setupDrawColorAlphaUniforms();
+    void setupDrawShaderUniforms(bool ignoreTransform = false);
+    void setupDrawColorFilterUniforms();
+    void setupDrawSimpleMesh();
+    void setupDrawTexture(GLuint texture);
+    void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0);
+    void finishDrawTexture();
 
     /**
      * Should be invoked every time the glScissor is modified.
@@ -495,6 +514,21 @@
     // Indicates whether the clip must be restored
     bool mDirtyClip;
 
+    // The following fields are used to setup drawing
+    // Used to describe the shaders to generate
+    ProgramDescription mDescription;
+    // Color description
+    bool mColorSet;
+    float mColorA, mColorR, mColorG, mColorB;
+    // Indicates that the shader should get a color
+    bool mSetShaderColor;
+    // Current texture unit
+    GLuint mTextureUnit;
+    // Track dirty regions, true by default
+    bool mTrackDirtyRegions;
+    // Texture coordinates slot
+    int mTexCoordsSlot;
+
     friend class DisplayListRenderer;
 
 }; // class OpenGLRenderer
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index fc3e248..3acd18a 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -102,14 +102,8 @@
         kGradientSweep
     };
 
-    ProgramDescription():
-        hasTexture(false), hasAlpha8Texture(false), modulate(false),
-        hasBitmap(false), isBitmapNpot(false), hasGradient(false),
-        gradientType(kGradientLinear),
-        shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
-        bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
-        colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode),
-        framebufferMode(SkXfermode::kClear_Mode), swapSrcDst(false) {
+    ProgramDescription() {
+        reset();
     }
 
     // Texturing
@@ -142,6 +136,35 @@
     bool swapSrcDst;
 
     /**
+     * Resets this description. All fields are reset back to the default
+     * values they hold after building a new instance.
+     */
+    void reset() {
+        hasTexture = false;
+        hasAlpha8Texture = false;
+
+        modulate = false;
+
+        hasBitmap = false;
+        isBitmapNpot = false;
+
+        hasGradient = false;
+        gradientType = kGradientLinear;
+
+        shadersMode = SkXfermode::kClear_Mode;
+
+        isBitmapFirst = false;
+        bitmapWrapS = GL_CLAMP_TO_EDGE;
+        bitmapWrapT = GL_CLAMP_TO_EDGE;
+
+        colorOp = kColorNone;
+        colorMode = SkXfermode::kClear_Mode;
+
+        framebufferMode = SkXfermode::kClear_Mode;
+        swapSrcDst = false;
+    }
+
+    /**
      * Indicates, for a given color, whether color modulation is required in
      * the fragment shader. When this method returns true, the program should
      * be provided with a modulation color.
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 9e30799..43d4291 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -105,10 +105,10 @@
     RS_ALLOCATION_USAGE_ALL = 0x000F
 };
 
-enum RsAllocationMipmapGenerationControl {
-    RS_MIPMAP_NONE = 0,
-    RS_MIPMAP_FULL = 1,
-    RS_MIPMAP_TEXTURE_ONLY = 2
+enum RsAllocationMipmapControl {
+    RS_ALLOCATION_MIPMAP_NONE = 0,
+    RS_ALLOCATION_MIPMAP_FULL = 1,
+    RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE = 2
 };
 
 enum RsDataType {
@@ -345,13 +345,13 @@
 RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimX, uint32_t dimY,
                      uint32_t dimZ, bool mips, bool faces);
 RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype,
-                                      RsAllocationMipmapGenerationControl mips,
+                                      RsAllocationMipmapControl mips,
                                       uint32_t usages);
 RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
-                                           RsAllocationMipmapGenerationControl mips,
+                                           RsAllocationMipmapControl mips,
                                            const void *data, uint32_t usages);
 RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
-                                               RsAllocationMipmapGenerationControl mips,
+                                               RsAllocationMipmapControl mips,
                                                const void *data, uint32_t usages);
 
 #ifndef NO_RS_FUNCS
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
index 4338f33..0a06394 100644
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
@@ -34,11 +34,12 @@
     private ProgramFragment mPFPoints;
     private ProgramVertex mPV;
     private ScriptField_Point mPoints;
-    private ScriptField_Point mArcs;
     private ScriptField_VpConsts mVpConsts;
 
     void updateProjectionMatrices() {
-        mVpConsts = new ScriptField_VpConsts(mRS, 1);
+        mVpConsts = new ScriptField_VpConsts(mRS, 1,
+                                             Allocation.USAGE_SCRIPT |
+                                             Allocation.USAGE_GRAPHICS_CONSTANTS);
         ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
         Matrix4f mvp = new Matrix4f();
         mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1);
@@ -67,9 +68,10 @@
     }
 
     private Allocation loadTexture(int id) {
-        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes,
-                id, Element.RGB_565(mRS), false);
-        allocation.uploadToTexture(0);
+        final Allocation allocation =
+            Allocation.createFromBitmapResource(mRS, mRes,
+                id, Allocation.MipmapControl.MIPMAP_NONE,
+                Allocation.USAGE_GRAPHICS_TEXTURE);
         return allocation;
     }
 
@@ -88,31 +90,24 @@
         pfb.setVaryingColor(true);
         mPFLines = pfb.create();
 
+        android.util.Log.e("rs", "Load texture");
         mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
 
-        mPoints = new ScriptField_Point(mRS, PART_COUNT);
-        mArcs = new ScriptField_Point(mRS, PART_COUNT * 2);
+        mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
 
         Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
         smb.addVertexAllocation(mPoints.getAllocation());
         smb.addIndexType(Primitive.POINT);
         Mesh smP = smb.create();
 
-        smb = new Mesh.AllocationBuilder(mRS);
-        smb.addVertexAllocation(mArcs.getAllocation());
-        smb.addIndexType(Primitive.LINE);
-        Mesh smA = smb.create();
-
         mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
 
         mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
         mScript.set_partMesh(smP);
-        mScript.set_arcMesh(smA);
         mScript.set_physics_script(mPhysicsScript);
         mScript.bind_point(mPoints);
-        mScript.bind_arc(mArcs);
-        mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT));
-        mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT));
+        mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
+        mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
 
         mScript.set_gPFLines(mPFLines);
         mScript.set_gPFPoints(mPFPoints);
diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs
index c41ed0f..fed9963 100644
--- a/libs/rs/java/Balls/src/com/android/balls/balls.rs
+++ b/libs/rs/java/Balls/src/com/android/balls/balls.rs
@@ -10,18 +10,14 @@
 rs_program_fragment gPFPoints;
 rs_program_fragment gPFLines;
 rs_mesh partMesh;
-rs_mesh arcMesh;
 
 typedef struct __attribute__((packed, aligned(4))) Point {
     float2 position;
-    //uchar4 color;
     float size;
 } Point_t;
 Point_t *point;
-Point_t *arc;
 
 typedef struct VpConsts {
-    //rs_matrix4x4 Proj;
     rs_matrix4x4 MVP;
 } VpConsts_t;
 VpConsts_t *vpConstants;
@@ -42,8 +38,6 @@
         balls1[ct].position.y = rsRand(0.f, (float)h);
         balls1[ct].delta.x = 0.f;
         balls1[ct].delta.y = 0.f;
-        //balls1[ct].arcID = -1;
-        //balls1[ct].color = 0.f;
         balls1[ct].size = 1.f;
 
         float r = rsRand(100.f);
@@ -76,28 +70,12 @@
 
     rsForEach(physics_script, bc.ain, bc.aout, &bc);
 
-    uint32_t arcIdx = 0;
     for (uint32_t ct=0; ct < bc.dimX; ct++) {
         point[ct].position = bout[ct].position;
-        ///point[ct].color = 0xff;//rsPackColorTo8888(bout[ct].color);
         point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size;
-/*
-        if (bout[ct].arcID >= 0) {
-            arc[arcIdx].position = bout[ct].position;
-            arc[arcIdx].color.r = min(bout[ct].arcStr, 1.f) * 0xff;
-            arc[arcIdx].color.g = 0;
-            arc[arcIdx].color.b = 0;
-            arc[arcIdx].color.a = 0xff;
-            arc[arcIdx+1].position = bout[bout[ct].arcID].position;
-            arc[arcIdx+1].color = arc[arcIdx].color;
-            arcIdx += 2;
-        }
-        */
     }
 
     frame++;
-    //rsgBindProgramFragment(gPFLines);
-    //rsgDrawMesh(arcMesh, 0, 0, arcIdx);
     rsgBindProgramFragment(gPFPoints);
     rsgDrawMesh(partMesh);
     rsClearObject(&bc.ain);
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 09654ab..5de09f7 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -362,7 +362,7 @@
     }
 
     private void createScript() {
-        mRS = RenderScript.create();
+        mRS = RenderScript.create(this);
         mRS.setMessageHandler(new FilterCallback());
 
         mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
diff --git a/libs/rs/java/Samples/AndroidManifest.xml b/libs/rs/java/Samples/AndroidManifest.xml
index be191f2..6f35e2a 100644
--- a/libs/rs/java/Samples/AndroidManifest.xml
+++ b/libs/rs/java/Samples/AndroidManifest.xml
@@ -20,5 +20,14 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <activity android:name="RsBench"
+                  android:label="RsBenchmark"                  
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/libs/rs/java/Samples/res/raw/multitexf.glsl b/libs/rs/java/Samples/res/raw/multitexf.glsl
index 351ff9b..e492a47 100644
--- a/libs/rs/java/Samples/res/raw/multitexf.glsl
+++ b/libs/rs/java/Samples/res/raw/multitexf.glsl
@@ -7,6 +7,7 @@
    lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba;
    col0.xyz = col0.xyz*col1.xyz*1.5;
    col0.xyz = mix(col0.xyz, col2.xyz, col2.w);
+   col0.w = 0.5;
    gl_FragColor = col0;
 }
 
diff --git a/libs/rs/java/Samples/res/raw/shader2f.glsl b/libs/rs/java/Samples/res/raw/shader2f.glsl
new file mode 100644
index 0000000..5fc05f1
--- /dev/null
+++ b/libs/rs/java/Samples/res/raw/shader2f.glsl
@@ -0,0 +1,29 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+   vec3 V = normalize(-varWorldPos.xyz);
+   vec3 worldNorm = normalize(varWorldNormal);
+
+   vec3 light0Vec = normalize(UNI_light0_Posision.xyz - varWorldPos);
+   vec3 light0R = -reflect(light0Vec, worldNorm);
+   float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
+   float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
+   float light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
+
+   vec3 light1Vec = normalize(UNI_light1_Posision.xyz - varWorldPos);
+   vec3 light1R = reflect(light1Vec, worldNorm);
+   float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
+   float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
+   float light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
+
+   vec2 t0 = varTex0.xy;
+   lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+   col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
+   col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
+   col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
+   gl_FragColor = col;
+}
+
diff --git a/libs/rs/java/Samples/res/raw/shader2movev.glsl b/libs/rs/java/Samples/res/raw/shader2movev.glsl
new file mode 100644
index 0000000..68712e6
--- /dev/null
+++ b/libs/rs/java/Samples/res/raw/shader2movev.glsl
@@ -0,0 +1,22 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+   vec4 objPos = ATTRIB_position;
+   vec3 oldPos = objPos.xyz;
+   objPos.xyz += 0.1*sin(objPos.xyz*2.0 + UNI_time);
+   objPos.xyz += 0.05*sin(objPos.xyz*4.0 + UNI_time*0.5);
+   objPos.xyz += 0.02*sin(objPos.xyz*7.0 + UNI_time*0.75);
+   vec4 worldPos = UNI_model * objPos;
+   gl_Position = UNI_proj * worldPos;
+
+   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+   vec3 worldNorm = model3 * (ATTRIB_normal + oldPos - objPos.xyz);
+   //vec3 worldNorm = model3 * ATTRIB_normal;
+
+   varWorldPos = worldPos.xyz;
+   varWorldNormal = worldNorm;
+   varTex0 = ATTRIB_texture0;
+}
diff --git a/libs/rs/java/Samples/res/raw/shader2v.glsl b/libs/rs/java/Samples/res/raw/shader2v.glsl
new file mode 100644
index 0000000..e6885a3
--- /dev/null
+++ b/libs/rs/java/Samples/res/raw/shader2v.glsl
@@ -0,0 +1,17 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+   vec4 objPos = ATTRIB_position;
+   vec4 worldPos = UNI_model * objPos;
+   gl_Position = UNI_proj * worldPos;
+
+   mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+   vec3 worldNorm = model3 * ATTRIB_normal;
+
+   varWorldPos = worldPos.xyz;
+   varWorldNormal = worldNorm;
+   varTex0 = ATTRIB_texture0;
+}
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBench.java b/libs/rs/java/Samples/src/com/android/samples/RsBench.java
new file mode 100644
index 0000000..5b9af6f
--- /dev/null
+++ b/libs/rs/java/Samples/src/com/android/samples/RsBench.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.samples;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class RsBench extends Activity {
+
+    private RsBenchView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new RsBenchView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.pause();
+    }
+
+}
+
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
new file mode 100644
index 0000000..212e7a8
--- /dev/null
+++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.samples;
+
+import java.io.Writer;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.*;
+import android.renderscript.Allocation.CubemapLayout;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.renderscript.Sampler.Value;
+import android.util.Log;
+
+
+public class RsBenchRS {
+
+    int mWidth;
+    int mHeight;
+
+    public RsBenchRS() {
+    }
+
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
+        mWidth = width;
+        mHeight = height;
+        mOptionsARGB.inScaled = false;
+        mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        mMode = 0;
+        mMaxModes = 0;
+        initRS();
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+
+    private Sampler mLinearClamp;
+    private Sampler mLinearWrap;
+    private Sampler mMipLinearWrap;
+    private Sampler mNearestClamp;
+    private Sampler mMipLinearAniso8;
+    private Sampler mMipLinearAniso15;
+
+    private ProgramStore mProgStoreBlendNoneDepth;
+    private ProgramStore mProgStoreBlendNone;
+    private ProgramStore mProgStoreBlendAlpha;
+    private ProgramStore mProgStoreBlendAdd;
+
+    private ProgramFragment mProgFragmentTexture;
+    private ProgramFragment mProgFragmentColor;
+
+    private ProgramVertex mProgVertex;
+    private ProgramVertex.MatrixAllocation mPVA;
+
+    // Custom shaders
+    private ProgramVertex mProgVertexCustom;
+    private ProgramFragment mProgFragmentCustom;
+    private ProgramFragment mProgFragmentMultitex;
+    private ProgramVertex mProgVertexPixelLight;
+    private ProgramVertex mProgVertexPixelLightMove;
+    private ProgramFragment mProgFragmentPixelLight;
+    private ScriptField_VertexShaderConstants_s mVSConst;
+    private ScriptField_FragentShaderConstants_s mFSConst;
+    private ScriptField_VertexShaderConstants3_s mVSConstPixel;
+    private ScriptField_FragentShaderConstants3_s mFSConstPixel;
+
+    private ProgramVertex mProgVertexCube;
+    private ProgramFragment mProgFragmentCube;
+
+    private ProgramRaster mCullBack;
+    private ProgramRaster mCullFront;
+    private ProgramRaster mCullNone;
+
+    private Allocation mTexTorus;
+    private Allocation mTexOpaque;
+    private Allocation mTexTransparent;
+    private Allocation mTexChecker;
+    private Allocation mTexCube;
+
+    private Mesh m10by10Mesh;
+    private Mesh m100by100Mesh;
+    private Mesh mWbyHMesh;
+    private Mesh mTorus;
+
+    Font mFontSans;
+    Font mFontSerif;
+    Font mFontSerifBold;
+    Font mFontSerifItalic;
+    Font mFontSerifBoldItalic;
+    Font mFontMono;
+    private Allocation mTextAlloc;
+
+    private ScriptC_rsbench mScript;
+
+    private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+
+    int mMode;
+    int mMaxModes;
+
+    public void onActionDown(int x, int y) {
+        mMode ++;
+        mMode = mMode % mMaxModes;
+        mScript.set_gDisplayMode(mMode);
+    }
+
+    private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
+
+        Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
+                                           2, Mesh.TriangleMeshBuilder.TEXTURE_0);
+
+        for (int y = 0; y <= hResolution; y++) {
+            final float normalizedY = (float)y / hResolution;
+            final float yOffset = (normalizedY - 0.5f) * height;
+            for (int x = 0; x <= wResolution; x++) {
+                float normalizedX = (float)x / wResolution;
+                float xOffset = (normalizedX - 0.5f) * width;
+                tmb.setTexture((float)x % 2, (float)y % 2);
+                tmb.addVertex(xOffset, yOffset);
+             }
+        }
+
+        for (int y = 0; y < hResolution; y++) {
+            final int curY = y * (wResolution + 1);
+            final int belowY = (y + 1) * (wResolution + 1);
+            for (int x = 0; x < wResolution; x++) {
+                int curV = curY + x;
+                int belowV = belowY + x;
+                tmb.addTriangle(curV, belowV, curV + 1);
+                tmb.addTriangle(belowV, belowV + 1, curV + 1);
+            }
+        }
+
+        return tmb.create(true);
+    }
+
+    private void initProgramStore() {
+        // Use stock the stock program store object
+        mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
+        mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NO_DEPTH(mRS);
+
+        // Create a custom program store
+        ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
+        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+        builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
+                             ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        builder.setDitherEnable(false);
+        builder.setDepthMask(false);
+        mProgStoreBlendAlpha = builder.create();
+
+        mProgStoreBlendAdd = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS);
+
+        mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
+        mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
+        mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
+        mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
+    }
+
+    private void initProgramFragment() {
+
+        ProgramFragment.Builder texBuilder = new ProgramFragment.Builder(mRS);
+        texBuilder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+                              ProgramFragment.Builder.Format.RGBA, 0);
+        mProgFragmentTexture = texBuilder.create();
+        mProgFragmentTexture.bindSampler(mLinearClamp, 0);
+
+        ProgramFragment.Builder colBuilder = new ProgramFragment.Builder(mRS);
+        colBuilder.setVaryingColor(false);
+        mProgFragmentColor = colBuilder.create();
+
+        mScript.set_gProgFragmentColor(mProgFragmentColor);
+        mScript.set_gProgFragmentTexture(mProgFragmentTexture);
+    }
+
+    private void initProgramVertex() {
+        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        mProgVertex = pvb.create();
+
+        mPVA = new ProgramVertex.MatrixAllocation(mRS);
+        mProgVertex.bindAllocation(mPVA);
+        mPVA.setupOrthoWindow(mWidth, mHeight);
+
+        mScript.set_gProgVertex(mProgVertex);
+    }
+
+    private void initCustomShaders() {
+        mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
+        mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
+        mScript.bind_gVSConstants(mVSConst);
+        mScript.bind_gFSConstants(mFSConst);
+
+        mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1);
+        mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1);
+        mScript.bind_gVSConstPixel(mVSConstPixel);
+        mScript.bind_gFSConstPixel(mFSConstPixel);
+
+        // Initialize the shader builder
+        ProgramVertex.ShaderBuilder pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        // Specify the resource that contains the shader string
+        pvbCustom.setShader(mRes, R.raw.shaderv);
+        // Use a script field to spcify the input layout
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        // Define the constant input layout
+        pvbCustom.addConstant(mVSConst.getAllocation().getType());
+        mProgVertexCustom = pvbCustom.create();
+        // Bind the source of constant data
+        mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
+
+        ProgramFragment.ShaderBuilder pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        // Specify the resource that contains the shader string
+        pfbCustom.setShader(mRes, R.raw.shaderf);
+        //Tell the builder how many textures we have
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        // Define the constant input layout
+        pfbCustom.addConstant(mFSConst.getAllocation().getType());
+        mProgFragmentCustom = pfbCustom.create();
+        // Bind the source of constant data
+        mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
+
+        // Cubemap test shaders
+        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom.setShader(mRes, R.raw.shadercubev);
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        pvbCustom.addConstant(mVSConst.getAllocation().getType());
+        mProgVertexCube = pvbCustom.create();
+        mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
+
+        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom.setShader(mRes, R.raw.shadercubef);
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
+        mProgFragmentCube = pfbCustom.create();
+
+        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom.setShader(mRes, R.raw.shader2v);
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
+        mProgVertexPixelLight = pvbCustom.create();
+        mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0);
+
+        pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
+        pvbCustom.setShader(mRes, R.raw.shader2movev);
+        pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
+        pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
+        mProgVertexPixelLightMove = pvbCustom.create();
+        mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0);
+
+        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom.setShader(mRes, R.raw.shader2f);
+        pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+        pfbCustom.addConstant(mFSConstPixel.getAllocation().getType());
+        mProgFragmentPixelLight = pfbCustom.create();
+        mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0);
+
+        pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
+        pfbCustom.setShader(mRes, R.raw.multitexf);
+        pfbCustom.setTextureCount(3);
+        mProgFragmentMultitex = pfbCustom.create();
+
+        mScript.set_gProgVertexCustom(mProgVertexCustom);
+        mScript.set_gProgFragmentCustom(mProgFragmentCustom);
+        mScript.set_gProgVertexCube(mProgVertexCube);
+        mScript.set_gProgFragmentCube(mProgFragmentCube);
+        mScript.set_gProgVertexPixelLight(mProgVertexPixelLight);
+        mScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove);
+        mScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight);
+        mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
+    }
+
+    private Allocation loadTextureRGB(int id) {
+        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes,
+                id, Element.RGB_565(mRS), true);
+        allocation.uploadToTexture(0);
+        return allocation;
+    }
+
+    private Allocation loadTextureARGB(int id) {
+        Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
+        final Allocation allocation = Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true);
+        allocation.uploadToTexture(0);
+        return allocation;
+    }
+
+    private void loadImages() {
+        mTexTorus = loadTextureRGB(R.drawable.torusmap);
+        mTexOpaque = loadTextureRGB(R.drawable.data);
+        mTexTransparent = loadTextureARGB(R.drawable.leaf);
+        mTexChecker = loadTextureRGB(R.drawable.checker);
+        Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
+        mTexCube = Allocation.createCubemapFromBitmap(mRS, b, Element.RGB_565(mRS), false,
+                                                      Allocation.CubemapLayout.VERTICAL_FACE_LIST);
+        mTexCube.uploadToTexture(0);
+
+        mScript.set_gTexTorus(mTexTorus);
+        mScript.set_gTexOpaque(mTexOpaque);
+        mScript.set_gTexTransparent(mTexTransparent);
+        mScript.set_gTexChecker(mTexChecker);
+        mScript.set_gTexCube(mTexCube);
+    }
+
+    private void initFonts() {
+        // Sans font by family name
+        mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
+        // Create font by file name
+        mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8);
+        // Create fonts by family and style
+        mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8);
+        mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+        mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+        mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8);
+
+        mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
+
+        mScript.set_gFontSans(mFontSans);
+        mScript.set_gFontSerif(mFontSerif);
+        mScript.set_gFontSerifBold(mFontSerifBold);
+        mScript.set_gFontSerifItalic(mFontSerifItalic);
+        mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
+        mScript.set_gFontMono(mFontMono);
+        mScript.set_gTextAlloc(mTextAlloc);
+    }
+
+    private void initMesh() {
+        m10by10Mesh = getMbyNMesh(mWidth, mHeight, 10, 10);
+        mScript.set_g10by10Mesh(m10by10Mesh);
+        m100by100Mesh = getMbyNMesh(mWidth, mHeight, 100, 100);
+        mScript.set_g100by100Mesh(m100by100Mesh);
+        mWbyHMesh= getMbyNMesh(mWidth, mHeight, mWidth/4, mHeight/4);
+        mScript.set_gWbyHMesh(mWbyHMesh);
+
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+            Log.e("rs", "could not load model");
+        } else {
+            mTorus = (Mesh)entry.getObject();
+            mScript.set_gTorusMesh(mTorus);
+        }
+    }
+
+    private void initSamplers() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMin(Sampler.Value.LINEAR);
+        bs.setMag(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.WRAP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        mLinearWrap = bs.create();
+
+        mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
+        mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
+        mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
+
+        bs = new Sampler.Builder(mRS);
+        bs.setMin(Sampler.Value.LINEAR_MIP_LINEAR);
+        bs.setMag(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.WRAP);
+        bs.setWrapT(Sampler.Value.WRAP);
+        bs.setAnisotropy(8.0f);
+        mMipLinearAniso8 = bs.create();
+        bs.setAnisotropy(15.0f);
+        mMipLinearAniso15 = bs.create();
+
+        mScript.set_gLinearClamp(mLinearClamp);
+        mScript.set_gLinearWrap(mLinearWrap);
+        mScript.set_gMipLinearWrap(mMipLinearWrap);
+        mScript.set_gMipLinearAniso8(mMipLinearAniso8);
+        mScript.set_gMipLinearAniso15(mMipLinearAniso15);
+        mScript.set_gNearestClamp(mNearestClamp);
+    }
+
+    private void initProgramRaster() {
+        mCullBack = ProgramRaster.CULL_BACK(mRS);
+        mCullFront = ProgramRaster.CULL_FRONT(mRS);
+        mCullNone = ProgramRaster.CULL_NONE(mRS);
+
+        mScript.set_gCullBack(mCullBack);
+        mScript.set_gCullFront(mCullFront);
+        mScript.set_gCullNone(mCullNone);
+    }
+
+    private void initRS() {
+
+        mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench);
+
+        mMaxModes = mScript.get_gMaxModes();
+
+        initSamplers();
+        initProgramStore();
+        initProgramFragment();
+        initProgramVertex();
+        initFonts();
+        loadImages();
+        initMesh();
+        initProgramRaster();
+        initCustomShaders();
+
+        mRS.bindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java
new file mode 100644
index 0000000..4283a42
--- /dev/null
+++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.samples;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class RsBenchView extends RSSurfaceView {
+
+    public RsBenchView(Context context) {
+        super(context);
+        //setFocusable(true);
+    }
+
+    private RenderScriptGL mRS;
+    private RsBenchRS mRender;
+
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        if (mRS == null) {
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            sc.setDepth(16, 24);
+            mRS = createRenderScriptGL(sc);
+            mRS.setSurface(holder, w, h);
+            mRender = new RsBenchRS();
+            mRender.init(mRS, getResources(), w, h);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if (mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event)
+    {
+        // break point at here
+        // this method doesn't work when 'extends View' include 'extends ScrollView'.
+        return super.onKeyDown(keyCode, event);
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev)
+    {
+        boolean ret = false;
+        int act = ev.getAction();
+        if (act == ev.ACTION_DOWN) {
+            mRender.onActionDown((int)ev.getX(), (int)ev.getY());
+            ret = true;
+        }
+
+        return ret;
+    }
+}
+
+
diff --git a/libs/rs/java/Samples/src/com/android/samples/rsbench.rs b/libs/rs/java/Samples/src/com/android/samples/rsbench.rs
new file mode 100644
index 0000000..87f2f29
--- /dev/null
+++ b/libs/rs/java/Samples/src/com/android/samples/rsbench.rs
@@ -0,0 +1,845 @@
+// Copyright (C) 2009 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.samples)
+
+#include "rs_graphics.rsh"
+#include "shader_def.rsh"
+
+const int gMaxModes = 23;
+
+rs_program_vertex gProgVertex;
+rs_program_fragment gProgFragmentColor;
+rs_program_fragment gProgFragmentTexture;
+
+rs_program_store gProgStoreBlendNoneDepth;
+rs_program_store gProgStoreBlendNone;
+rs_program_store gProgStoreBlendAlpha;
+rs_program_store gProgStoreBlendAdd;
+
+rs_allocation gTexOpaque;
+rs_allocation gTexTorus;
+rs_allocation gTexTransparent;
+rs_allocation gTexChecker;
+rs_allocation gTexCube;
+
+rs_mesh g10by10Mesh;
+rs_mesh g100by100Mesh;
+rs_mesh gWbyHMesh;
+rs_mesh gTorusMesh;
+
+rs_font gFontSans;
+rs_font gFontSerif;
+rs_font gFontSerifBold;
+rs_font gFontSerifItalic;
+rs_font gFontSerifBoldItalic;
+rs_font gFontMono;
+rs_allocation gTextAlloc;
+
+int gDisplayMode;
+
+rs_sampler gLinearClamp;
+rs_sampler gLinearWrap;
+rs_sampler gMipLinearWrap;
+rs_sampler gMipLinearAniso8;
+rs_sampler gMipLinearAniso15;
+rs_sampler gNearestClamp;
+
+rs_program_raster gCullBack;
+rs_program_raster gCullFront;
+rs_program_raster gCullNone;
+
+// Custom vertex shader compunents
+VertexShaderConstants *gVSConstants;
+FragentShaderConstants *gFSConstants;
+VertexShaderConstants3 *gVSConstPixel;
+FragentShaderConstants3 *gFSConstPixel;
+// Export these out to easily set the inputs to shader
+VertexShaderInputs *gVSInputs;
+// Custom shaders we use for lighting
+rs_program_vertex gProgVertexCustom;
+rs_program_fragment gProgFragmentCustom;
+rs_program_vertex gProgVertexPixelLight;
+rs_program_vertex gProgVertexPixelLightMove;
+rs_program_fragment gProgFragmentPixelLight;
+rs_program_vertex gProgVertexCube;
+rs_program_fragment gProgFragmentCube;
+rs_program_fragment gProgFragmentMultitex;
+
+float gDt = 0;
+
+void init() {
+}
+
+static const char *sampleText = "This is a sample of small text for performace";
+// Offsets for multiple layer of text
+static int textOffsets[] = { 0,  0, -5, -5, 5,  5, -8, -8, 8,  8};
+static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f,
+                             0.5f, 0.7f, 0.5f, 1.0f,
+                             0.7f, 0.5f, 0.5f, 1.0f,
+                             0.5f, 0.5f, 0.7f, 1.0f,
+                             0.5f, 0.6f, 0.7f, 1.0f,
+};
+
+void displayFontSamples(int fillNum) {
+
+    uint width = rsgGetWidth();
+    uint height = rsgGetHeight();
+    int left = 0, right = 0, top = 0, bottom = 0;
+    rsgMeasureText(sampleText, &left, &right, &top, &bottom);
+
+    int textHeight = top - bottom;
+    int textWidth = right - left;
+    int numVerticalLines = height / textHeight;
+    int yPos = top;
+
+    int xOffset = 0, yOffset = 0;
+    rsgBindFont(gFontSans); //rsgBindFont(gFontSerif); rsgBindFont(gFontSerifBold); rsgBindFont(gFontSerifBoldItalic); rsgBindFont(gFontSans);
+
+    for(int fillI = 0; fillI < fillNum; fillI ++) {
+        xOffset = textOffsets[fillI * 2];
+        yOffset = textOffsets[fillI * 2 + 1];
+        float *colPtr = textColors + fillI * 4;
+        rsgFontColor(colPtr[0], colPtr[1], colPtr[2], colPtr[3]);
+        for (int h = 0; h < 4; h ++) {
+            yPos = top + yOffset;
+            for (int v = 0; v < numVerticalLines; v ++) {
+                rsgDrawText(sampleText, xOffset + textWidth * h, yPos);
+                yPos += textHeight;
+            }
+        }
+    }
+}
+
+void bindProgramVertexOrtho() {
+    // Default vertex sahder
+    rsgBindProgramVertex(gProgVertex);
+    // Setup the projectioni matrix
+    rs_matrix4x4 proj;
+    rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+}
+
+void displaySingletexFill(bool blend, int quadCount) {
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    if (!blend) {
+        rsgBindProgramStore(gProgStoreBlendNone);
+    } else {
+        rsgBindProgramStore(gProgStoreBlendAlpha);
+    }
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    for (int i = 0; i < quadCount; i ++) {
+        float startX = 10 * i, startY = 10 * i;
+        float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY;
+        rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                             startX, startY + height, 0, 0, 1,
+                             startX + width, startY + height, 0, 1, 1,
+                             startX + width, startY, 0, 1, 0);
+    }
+}
+
+void displayBlendingSamples() {
+    int i;
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    rsgBindProgramFragment(gProgFragmentColor);
+
+    rsgBindProgramStore(gProgStoreBlendNone);
+    for (i = 0; i < 3; i ++) {
+        float iPlusOne = (float)(i + 1);
+        rsgProgramFragmentConstantColor(gProgFragmentColor,
+                                        0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
+        float yPos = 150 * (float)i;
+        rsgDrawRect(0, yPos, 200, yPos + 200, 0);
+    }
+
+    rsgBindProgramStore(gProgStoreBlendAlpha);
+    for (i = 0; i < 3; i ++) {
+        float iPlusOne = (float)(i + 1);
+        rsgProgramFragmentConstantColor(gProgFragmentColor,
+                                        0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
+        float yPos = 150 * (float)i;
+        rsgDrawRect(150, yPos, 350, yPos + 200, 0);
+    }
+
+    rsgBindProgramStore(gProgStoreBlendAdd);
+    for (i = 0; i < 3; i ++) {
+        float iPlusOne = (float)(i + 1);
+        rsgProgramFragmentConstantColor(gProgFragmentColor,
+                                        0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
+        float yPos = 150 * (float)i;
+        rsgDrawRect(300, yPos, 500, yPos + 200, 0);
+    }
+
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("No Blending", 10, 50);
+    rsgDrawText("Alpha Blending", 160, 150);
+    rsgDrawText("Additive Blending", 320, 250);
+
+}
+
+void displayMeshSamples(int meshNum) {
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadTranslate(&matrix, rsgGetWidth()/2, rsgGetHeight()/2, 0);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    if (meshNum == 0) {
+        rsgDrawMesh(g10by10Mesh);
+    } else if (meshNum == 1) {
+        rsgDrawMesh(g100by100Mesh);
+    } else if (meshNum == 2) {
+        rsgDrawMesh(gWbyHMesh);
+    }
+}
+
+void displayTextureSamplers() {
+
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+    // Linear clamp
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    float startX = 0, startY = 0;
+    float width = 300, height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    // Linear Wrap
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
+    startX = 0; startY = 300;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    // Nearest
+    rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
+    startX = 300; startY = 0;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.1,
+                         startX + width, startY + height, 0, 1.1, 1.1,
+                         startX + width, startY, 0, 1.1, 0);
+
+    rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+    startX = 300; startY = 300;
+    width = 300; height = 300;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1.5,
+                         startX + width, startY + height, 0, 1.5, 1.5,
+                         startX + width, startY, 0, 1.5, 0);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    rsgDrawText("Filtering: linear clamp", 10, 290);
+    rsgDrawText("Filtering: linear wrap", 10, 590);
+    rsgDrawText("Filtering: nearest clamp", 310, 290);
+    rsgDrawText("Filtering: miplinear wrap", 310, 590);
+}
+
+float gTorusRotation = 0;
+static void drawToruses(int numMeshes) {
+    rs_matrix4x4 matrix;
+
+    if (numMeshes == 1) {
+        rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -7.5f);
+        rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsgProgramVertexLoadModelMatrix(&matrix);
+        rsgDrawMesh(gTorusMesh);
+        return;
+    }
+
+    if (numMeshes == 2) {
+        rsMatrixLoadTranslate(&matrix, -1.6f, 0.0f, -7.5f);
+        rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsgProgramVertexLoadModelMatrix(&matrix);
+        rsgDrawMesh(gTorusMesh);
+
+        rsMatrixLoadTranslate(&matrix, 1.6f, 0.0f, -7.5f);
+        rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsgProgramVertexLoadModelMatrix(&matrix);
+        rsgDrawMesh(gTorusMesh);
+        return;
+    }
+
+    float startX = -5.0f;
+    float startY = -1.5f;
+    float startZ = -15.0f;
+    float dist = 3.2f;
+
+    for (int h = 0; h < 4; h ++) {
+        for (int v = 0; v < 2; v ++) {
+            // Position our model on the screen
+            rsMatrixLoadTranslate(&matrix, startX + dist * h, startY + dist * v, startZ);
+            rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+            rsgProgramVertexLoadModelMatrix(&matrix);
+            rsgDrawMesh(gTorusMesh);
+        }
+    }
+}
+
+
+// Quick hack to get some geometry numbers
+void displaySimpleGeoSamples(bool useTexture, int numMeshes) {
+    rsgBindProgramVertex(gProgVertex);
+    rsgBindProgramRaster(gCullBack);
+    // Setup the projectioni matrix with 60 degree field of view
+    rs_matrix4x4 proj;
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    if (useTexture) {
+        rsgBindProgramFragment(gProgFragmentTexture);
+    } else {
+        rsgBindProgramFragment(gProgFragmentColor);
+        rsgProgramFragmentConstantColor(gProgFragmentColor, 0.1, 0.7, 0.1, 1);
+    }
+    rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
+
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    drawToruses(numMeshes);
+}
+
+float gLight0Rotation = 0;
+float gLight1Rotation = 0;
+
+void setupCustomShaderLights() {
+    float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
+    float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
+    float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
+    float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
+    float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
+    float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
+
+    gLight0Rotation += 50.0f * gDt;
+    if (gLight0Rotation > 360.0f) {
+        gLight0Rotation -= 360.0f;
+    }
+    gLight1Rotation -= 50.0f * gDt;
+    if (gLight1Rotation > 360.0f) {
+        gLight1Rotation -= 360.0f;
+    }
+
+    rs_matrix4x4 l0Mat;
+    rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
+    light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
+    rs_matrix4x4 l1Mat;
+    rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
+    light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
+
+    // Set light 0 properties
+    gVSConstants->light0_Posision = light0Pos;
+    gVSConstants->light0_Diffuse = 1.0f;
+    gVSConstants->light0_Specular = 0.5f;
+    gVSConstants->light0_CosinePower = 10.0f;
+    // Set light 1 properties
+    gVSConstants->light1_Posision = light1Pos;
+    gVSConstants->light1_Diffuse = 1.0f;
+    gVSConstants->light1_Specular = 0.7f;
+    gVSConstants->light1_CosinePower = 25.0f;
+    rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
+
+    // Update fragmetn shader constants
+    // Set light 0 colors
+    gFSConstants->light0_DiffuseColor = light0DiffCol;
+    gFSConstants->light0_SpecularColor = light0SpecCol;
+    // Set light 1 colors
+    gFSConstants->light1_DiffuseColor = light1DiffCol;
+    gFSConstants->light1_SpecularColor = light1SpecCol;
+    rsAllocationMarkDirty(rsGetAllocation(gFSConstants));
+
+    // Set light 0 properties for per pixel lighting
+    gFSConstPixel->light0_Posision = light0Pos;
+    gFSConstPixel->light0_Diffuse = 1.0f;
+    gFSConstPixel->light0_Specular = 0.5f;
+    gFSConstPixel->light0_CosinePower = 10.0f;
+    gFSConstPixel->light0_DiffuseColor = light0DiffCol;
+    gFSConstPixel->light0_SpecularColor = light0SpecCol;
+    // Set light 1 properties
+    gFSConstPixel->light1_Posision = light1Pos;
+    gFSConstPixel->light1_Diffuse = 1.0f;
+    gFSConstPixel->light1_Specular = 0.7f;
+    gFSConstPixel->light1_CosinePower = 25.0f;
+    gFSConstPixel->light1_DiffuseColor = light1DiffCol;
+    gFSConstPixel->light1_SpecularColor = light1SpecCol;
+    rsAllocationMarkDirty(rsGetAllocation(gFSConstPixel));
+}
+
+void displayCustomShaderSamples(int numMeshes) {
+
+    // Update vertex shader constants
+    // Load model matrix
+    // Aplly a rotation to our mesh
+    gTorusRotation += 50.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    // Setup the projectioni matrix
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
+    setupCustomShaderLights();
+
+    rsgBindProgramVertex(gProgVertexCustom);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentCustom);
+    rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
+
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+
+    rs_matrix4x4 matrix;
+
+    if (numMeshes == 1) {
+        rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -7.5f);
+        rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+        rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
+
+        rsgDrawMesh(gTorusMesh);
+        return;
+    }
+
+    if (numMeshes == 2) {
+        rsMatrixLoadTranslate(&gVSConstants->model, -1.6f, 0.0f, -7.5f);
+        rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+        rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
+        rsgDrawMesh(gTorusMesh);
+
+        rsMatrixLoadTranslate(&gVSConstants->model, 1.6f, 0.0f, -7.5f);
+        rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+        rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
+        rsgDrawMesh(gTorusMesh);
+        return;
+    }
+
+    float startX = -5.0f;
+    float startY = -1.5f;
+    float startZ = -15.0f;
+    float dist = 3.2f;
+
+    for (int h = 0; h < 4; h ++) {
+        for (int v = 0; v < 2; v ++) {
+            // Position our model on the screen
+            rsMatrixLoadTranslate(&gVSConstants->model, startX + dist * h, startY + dist * v, startZ);
+            rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+            rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+            rsAllocationMarkDirty(rsGetAllocation(gVSConstants));
+            rsgDrawMesh(gTorusMesh);
+        }
+    }
+}
+
+void displayPixelLightSamples(int numMeshes) {
+
+    // Update vertex shader constants
+    // Load model matrix
+    // Aplly a rotation to our mesh
+    gTorusRotation += 20.0f * gDt;
+    if (gTorusRotation > 360.0f) {
+        gTorusRotation -= 360.0f;
+    }
+
+    //gTorusRotation = 45.0f;
+
+    gVSConstPixel->time = rsUptimeMillis()*0.005;
+
+    // Setup the projectioni matrix
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f);
+    setupCustomShaderLights();
+
+    rsgBindProgramVertex(gProgVertexPixelLight);
+
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNoneDepth);
+    rsgBindProgramFragment(gProgFragmentPixelLight);
+    rsgBindSampler(gProgFragmentPixelLight, 0, gLinearClamp);
+    rsgBindTexture(gProgFragmentPixelLight, 0, gTexTorus);
+
+    // Use back face culling
+    rsgBindProgramRaster(gCullBack);
+
+    rs_matrix4x4 matrix;
+
+    if (numMeshes == 1) {
+        rsMatrixLoadTranslate(&gVSConstPixel->model, 0.0f, 0.0f, -7.5f);
+        rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+        rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel));
+
+        rsgDrawMesh(gTorusMesh);
+        return;
+    }
+
+    if (numMeshes == 2) {
+        rsMatrixLoadTranslate(&gVSConstPixel->model, -1.6f, 0.0f, -7.5f);
+        rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+        rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel));
+        rsgDrawMesh(gTorusMesh);
+
+        rsMatrixLoadTranslate(&gVSConstPixel->model, 1.6f, 0.0f, -7.5f);
+        rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+        rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+        rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel));
+        rsgDrawMesh(gTorusMesh);
+        return;
+    }
+
+    float startX = -5.0f;
+    float startY = -1.5f;
+    float startZ = -15.0f;
+    float dist = 3.2f;
+
+    for (int h = 0; h < 4; h ++) {
+        for (int v = 0; v < 2; v ++) {
+            // Position our model on the screen
+            rsMatrixLoadTranslate(&gVSConstPixel->model, startX + dist * h, startY + dist * v, startZ);
+            rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
+            rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
+            rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel));
+            rsgDrawMesh(gTorusMesh);
+        }
+    }
+}
+
+void displayMultitextureSample(bool blend, int quadCount) {
+    bindProgramVertexOrtho();
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    // Fragment shader with texture
+    if (!blend) {
+        rsgBindProgramStore(gProgStoreBlendNone);
+    } else {
+        rsgBindProgramStore(gProgStoreBlendAlpha);
+    }
+    rsgBindProgramFragment(gProgFragmentMultitex);
+    rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp);
+    rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap);
+    rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp);
+    rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker);
+    rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus);
+    rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent);
+
+    for (int i = 0; i < quadCount; i ++) {
+        float startX = 10 * i, startY = 10 * i;
+        float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY;
+        rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                             startX, startY + height, 0, 0, 1,
+                             startX + width, startY + height, 0, 1, 1,
+                             startX + width, startY, 0, 1, 0);
+    }
+}
+
+float gAnisoTime = 0.0f;
+uint anisoMode = 0;
+void displayAnisoSample() {
+
+    gAnisoTime += gDt;
+
+    rsgBindProgramVertex(gProgVertex);
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rs_matrix4x4 proj;
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    rs_matrix4x4 matrix;
+    // Fragment shader with texture
+    rsgBindProgramStore(gProgStoreBlendNone);
+    rsgBindProgramFragment(gProgFragmentTexture);
+    rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
+    rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    rsgBindProgramRaster(gCullNone);
+
+    rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
+
+    if (gAnisoTime >= 5.0f) {
+        gAnisoTime = 0.0f;
+        anisoMode ++;
+        anisoMode = anisoMode % 3;
+    }
+
+    if (anisoMode == 0) {
+        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
+    } else if (anisoMode == 1) {
+        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
+    } else {
+        rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+    }
+
+    float startX = -15;
+    float startY = -15;
+    float width = 30;
+    float height = 30;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 10,
+                         startX + width, startY + height, 0, 10, 10,
+                         startX + width, startY, 0, 10, 0);
+
+    rsgBindProgramRaster(gCullBack);
+
+    rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgBindFont(gFontMono);
+    if (anisoMode == 0) {
+        rsgDrawText("Anisotropic filtering 8", 10, 40);
+    } else if (anisoMode == 1) {
+        rsgDrawText("Anisotropic filtering 15", 10, 40);
+    } else {
+        rsgDrawText("Miplinear filtering", 10, 40);
+    }
+}
+
+static bool checkInit() {
+
+    static int countdown = 5;
+
+    if (countdown == 0) {
+        gDt = 0;
+        countdown --;
+    }
+    // Perform all the uploads so we only measure rendered time
+    if(countdown > 1) {
+        displayFontSamples(5);
+        displaySingletexFill(true, 3);
+        displayBlendingSamples();
+        displayMeshSamples(0);
+        displayMeshSamples(1);
+        displayMeshSamples(2);
+        displayTextureSamplers();
+        displayMultitextureSample(true, 5);
+        displayAnisoSample();
+        countdown --;
+        rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+
+        // Now use text metrics to center the text
+        uint width = rsgGetWidth();
+        uint height = rsgGetHeight();
+        int left = 0, right = 0, top = 0, bottom = 0;
+
+        rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
+        rsgBindFont(gFontSerifBoldItalic);
+
+        const char* text = "Initializing";
+        rsgMeasureText(text, &left, &right, &top, &bottom);
+        int centeredPosX = width / 2 - (right - left) / 2;
+        int centeredPosY = height / 2 - (top - bottom) / 2;
+        rsgDrawText(text, centeredPosX, centeredPosY);
+
+        return false;
+    }
+
+    return true;
+}
+
+static int frameCount = 0;
+static int totalFramesRendered = 0;
+static int benchMode = 0;
+
+#define testTime 10.0f
+static float curTestTime = testTime;
+
+static const char *testNames[] = {
+    "Finished text fill 1",
+    "Finished text fill 2",
+    "Finished text fill 3",
+    "Finished text fill 4",
+    "Finished text fill 5",
+    "Finished 25.6k geo flat color",
+    "Finished 51.2k geo flat color",
+    "Finished 204.8k geo raster load flat color",
+    "Finished 25.6k geo texture",
+    "Finished 51.2k geo texture",
+    "Finished 204.8k geo raster load texture",
+    "Finished full screen mesh 10 by 10",
+    "Finished full screen mesh 100 by 100",
+    "Finished full screen mesh W / 4 by H / 4",
+    "Finished 25.6k geo heavy vertex",
+    "Finished 51.2k geo heavy vertex",
+    "Finished 204.8k geo raster load heavy vertex",
+    "Finished singletexture 5x fill",
+    "Finished 3tex multitexture 5x fill",
+    "Finished blend singletexture 5x fill",
+    "Finished blend 3tex multitexture 5x fill",
+    "Finished 25.6k geo heavy fragment",
+    "Finished 51.2k geo heavy fragment",
+    "Finished 204.8k geo raster load heavy fragment",
+    "Finished simpleGeo",
+    "Finished simpleGeo",
+    "Finished simpleGeo",
+    "Finished simpleGeo",
+    "Finished simpleGeo",
+    "Finished simpleGeo",
+};
+
+int root(int launchID) {
+
+    gDt = rsGetDt();
+
+    rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+    rsgClearDepth(1.0f);
+
+    if(!checkInit()) {
+        return 1;
+    }
+
+    /*displayPixelLightSamples(1);
+    return 1;*/
+
+    curTestTime -= gDt;
+    if(curTestTime < 0.0f) {
+        float fps = (float)(frameCount) / (testTime - curTestTime);
+        rsDebug(testNames[benchMode], fps);
+        benchMode ++;
+        curTestTime = testTime;
+        totalFramesRendered += frameCount;
+        frameCount = 0;
+        gTorusRotation = 0;
+
+        if (benchMode > gMaxModes) {
+            benchMode = 0;
+        }
+    }
+
+    switch (benchMode) {
+    case 0:
+        displayFontSamples(1);
+        break;
+    case 1:
+        displayFontSamples(2);
+        break;
+    case 2:
+        displayFontSamples(3);
+        break;
+    case 3:
+        displayFontSamples(4);
+        break;
+    case 4:
+        displayFontSamples(5);
+        break;
+    case 5:
+        displaySimpleGeoSamples(false, 1);
+        break;
+    case 6:
+        displaySimpleGeoSamples(false, 2);
+        break;
+    case 7:
+        displaySimpleGeoSamples(false, 8);
+        break;
+    case 8:
+        displaySimpleGeoSamples(true, 1);
+        break;
+    case 9:
+        displaySimpleGeoSamples(true, 2);
+        break;
+    case 10:
+        displaySimpleGeoSamples(true, 8);
+        break;
+    case 11:
+        displayMeshSamples(0);
+        break;
+    case 12:
+        displayMeshSamples(1);
+        break;
+    case 13:
+        displayMeshSamples(2);
+        break;
+    case 14:
+        displayCustomShaderSamples(1);
+        break;
+    case 15:
+        displayCustomShaderSamples(2);
+        break;
+    case 16:
+        displayCustomShaderSamples(8);
+        break;
+    case 17:
+        displaySingletexFill(false, 5);
+        break;
+    case 18:
+        displayMultitextureSample(false, 5);
+        break;
+    case 19:
+        displaySingletexFill(true, 5);
+        break;
+    case 20:
+        displayMultitextureSample(true, 5);
+        break;
+    case 21:
+        displayPixelLightSamples(1);
+        break;
+    case 22:
+        displayPixelLightSamples(2);
+        break;
+    case 23:
+        displayPixelLightSamples(8);
+        break;
+    }
+
+    frameCount ++;
+
+    return 1;
+}
diff --git a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh
index 3f51785..1d804c6 100644
--- a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh
+++ b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh
@@ -39,6 +39,13 @@
     float light_CosinePower[2];
 } VertexShaderConstants2;
 
+typedef struct VertexShaderConstants3_s {
+    rs_matrix4x4 model;
+    rs_matrix4x4 proj;
+    float time;
+} VertexShaderConstants3;
+
+
 typedef struct FragentShaderConstants_s {
     float4 light0_DiffuseColor;
     float4 light0_SpecularColor;
@@ -52,6 +59,22 @@
     float4 light_SpecularColor[2];
 } FragentShaderConstants2;
 
+typedef struct FragentShaderConstants3_s {
+    float4 light0_DiffuseColor;
+    float4 light0_SpecularColor;
+    float4 light0_Posision;
+    float light0_Diffuse;
+    float light0_Specular;
+    float light0_CosinePower;
+
+    float4 light1_DiffuseColor;
+    float4 light1_SpecularColor;
+    float4 light1_Posision;
+    float light1_Diffuse;
+    float light1_Specular;
+    float light1_CosinePower;
+} FragentShaderConstants3;
+
 typedef struct VertexShaderInputs_s {
     float4 position;
     float3 normal;
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index c1f652f..265e1d6 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -16,6 +16,7 @@
 
 package com.android.rs.test;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.renderscript.*;
 import android.util.Log;
@@ -28,8 +29,10 @@
 public class RSTestCore {
     int mWidth;
     int mHeight;
+    Context mCtx;
 
-    public RSTestCore() {
+    public RSTestCore(Context ctx) {
+        mCtx = ctx;
     }
 
     private Resources mRes;
@@ -61,10 +64,10 @@
 
         unitTests = new ArrayList<UnitTest>();
 
-        unitTests.add(new UT_primitives(this, mRes));
-        unitTests.add(new UT_rsdebug(this, mRes));
-        unitTests.add(new UT_rstypes(this, mRes));
-        unitTests.add(new UT_fp_mad(this, mRes));
+        unitTests.add(new UT_primitives(this, mRes, mCtx));
+        unitTests.add(new UT_rsdebug(this, mRes, mCtx));
+        unitTests.add(new UT_rstypes(this, mRes, mCtx));
+        unitTests.add(new UT_fp_mad(this, mRes, mCtx));
         /*
         unitTests.add(new UnitTest(null, "<Pass>", 1));
         unitTests.add(new UnitTest());
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
index 2f7542d..368f286 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
@@ -41,8 +41,11 @@
 
 public class RSTestView extends RSSurfaceView {
 
+    private Context mCtx;
+
     public RSTestView(Context context) {
         super(context);
+        mCtx = context;
         //setFocusable(true);
     }
 
@@ -55,7 +58,7 @@
             RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
             mRS = createRenderScriptGL(sc);
             mRS.setSurface(holder, w, h);
-            mRender = new RSTestCore();
+            mRender = new RSTestCore(mCtx);
             mRender.init(mRS, getResources(), w, h);
         }
     }
@@ -92,5 +95,3 @@
         return ret;
     }
 }
-
-
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
index 409192b..f2c91af 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
@@ -16,19 +16,20 @@
 
 package com.android.rs.test;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.renderscript.*;
 
 public class UT_fp_mad extends UnitTest {
     private Resources mRes;
 
-    protected UT_fp_mad(RSTestCore rstc, Resources res) {
-        super(rstc, "Fp_Mad");
+    protected UT_fp_mad(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "Fp_Mad", ctx);
         mRes = res;
     }
 
     public void run() {
-        RenderScript pRS = RenderScript.create();
+        RenderScript pRS = RenderScript.create(mCtx);
         ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad);
         pRS.setMessageHandler(mRsMessage);
         s.invoke_fp_mad_test(0, 0);
@@ -37,4 +38,3 @@
         pRS.destroy();
     }
 }
-
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
index 6e0859a..b7a65a5 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
@@ -16,14 +16,15 @@
 
 package com.android.rs.test;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.renderscript.*;
 
 public class UT_primitives extends UnitTest {
     private Resources mRes;
 
-    protected UT_primitives(RSTestCore rstc, Resources res) {
-        super(rstc, "Primitives");
+    protected UT_primitives(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "Primitives", ctx);
         mRes = res;
     }
 
@@ -87,7 +88,7 @@
     }
 
     public void run() {
-        RenderScript pRS = RenderScript.create();
+        RenderScript pRS = RenderScript.create(mCtx);
         ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives);
         pRS.setMessageHandler(mRsMessage);
         if (!initializeGlobals(s)) {
@@ -101,4 +102,3 @@
         pRS.destroy();
     }
 }
-
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java b/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
index df31f98..0614b1a 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
@@ -16,19 +16,20 @@
 
 package com.android.rs.test;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.renderscript.*;
 
 public class UT_rsdebug extends UnitTest {
     private Resources mRes;
 
-    protected UT_rsdebug(RSTestCore rstc, Resources res) {
-        super(rstc, "rsDebug");
+    protected UT_rsdebug(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "rsDebug", ctx);
         mRes = res;
     }
 
     public void run() {
-        RenderScript pRS = RenderScript.create();
+        RenderScript pRS = RenderScript.create(mCtx);
         ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug);
         pRS.setMessageHandler(mRsMessage);
         s.invoke_test_rsdebug(0, 0);
@@ -37,4 +38,3 @@
         pRS.destroy();
     }
 }
-
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java b/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java
index d1232ce..74211c8 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java
@@ -16,19 +16,20 @@
 
 package com.android.rs.test;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.renderscript.*;
 
 public class UT_rstypes extends UnitTest {
     private Resources mRes;
 
-    protected UT_rstypes(RSTestCore rstc, Resources res) {
-        super(rstc, "rsTypes");
+    protected UT_rstypes(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "rsTypes", ctx);
         mRes = res;
     }
 
     public void run() {
-        RenderScript pRS = RenderScript.create();
+        RenderScript pRS = RenderScript.create(mCtx);
         ScriptC_rstypes s = new ScriptC_rstypes(pRS, mRes, R.raw.rstypes);
         pRS.setMessageHandler(mRsMessage);
         s.invoke_test_rstypes(0, 0);
@@ -37,4 +38,3 @@
         pRS.destroy();
     }
 }
-
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
index 8923a19..a7722c7 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
@@ -15,6 +15,7 @@
  */
 
 package com.android.rs.test;
+import android.content.Context;
 import android.renderscript.RenderScript.RSMessageHandler;
 import android.util.Log;
 
@@ -24,6 +25,7 @@
     private ScriptField_ListAllocs_s.Item mItem;
     private RSTestCore mRSTC;
     private boolean msgHandled;
+    protected Context mCtx;
 
     /* These constants must match those in shared.rsh */
     public static final int RS_MSG_TEST_PASSED = 100;
@@ -32,25 +34,26 @@
     private static int numTests = 0;
     public int testID;
 
-    protected UnitTest(RSTestCore rstc, String n, int initResult) {
+    protected UnitTest(RSTestCore rstc, String n, int initResult, Context ctx) {
         super();
         mRSTC = rstc;
         name = n;
         msgHandled = false;
+        mCtx = ctx;
         result = initResult;
         testID = numTests++;
     }
 
-    protected UnitTest(RSTestCore rstc, String n) {
-        this(rstc, n, 0);
+    protected UnitTest(RSTestCore rstc, String n, Context ctx) {
+        this(rstc, n, 0, ctx);
     }
 
-    protected UnitTest(RSTestCore rstc) {
-        this (rstc, "<Unknown>");
+    protected UnitTest(RSTestCore rstc, Context ctx) {
+        this (rstc, "<Unknown>", ctx);
     }
 
-    protected UnitTest() {
-        this (null);
+    protected UnitTest(Context ctx) {
+        this (null, ctx);
     }
 
     protected RSMessageHandler mRsMessage = new RSMessageHandler() {
@@ -101,4 +104,3 @@
         }
     }
 }
-
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 14094c4..5daba08 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -89,14 +89,6 @@
 	param size_t dataLen
 	}
 
-AllocationCreateBitmapRef {
-	param RsType type
-	param RsAsyncVoidPtr bmpPtr
-	param RsAsyncVoidPtr callbackData
-	param RsBitmapCallback_t callback
-	ret RsAllocation
-	}
-
 AllocationUploadToTexture {
 	param RsAllocation alloc
 	param bool genMipMaps
@@ -330,6 +322,7 @@
 
 ScriptCCreate {
         param const char * resName
+        param const char * cacheDir
 	ret RsScript
 	}
 
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 10a5caf..78b570a 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -36,7 +36,7 @@
 
     mUsageFlags = usages;
 
-    mPtr = malloc(mType->getSizeBytes());
+    allocScriptMemory();
     if (mType->getElement()->getHasReferences()) {
         memset(mPtr, 0, mType->getSizeBytes());
     }
@@ -45,17 +45,6 @@
     }
 }
 
-Allocation::Allocation(Context *rsc, const Type *type, void *bmp,
-                       void *callbackData, RsBitmapCallback_t callback)
-                       : ObjectBase(rsc) {
-    init(rsc, type);
-
-    mUsageFlags = RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
-
-    mPtr = bmp;
-    mUserBitmapCallback = callback;
-    mUserBitmapCallbackData = callbackData;
-}
 
 void Allocation::init(Context *rsc, const Type *type) {
     mPtr = NULL;
@@ -67,10 +56,10 @@
 
     mReadWriteRatio = 0;
     mUpdateSize = 0;
+    mUsageFlags = 0;
+    mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
 
-    mIsTexture = false;
     mTextureID = 0;
-    mIsVertexBuffer = false;
     mBufferID = 0;
     mUploadDefered = false;
 
@@ -86,10 +75,9 @@
 Allocation::~Allocation() {
     if (mUserBitmapCallback != NULL) {
         mUserBitmapCallback(mUserBitmapCallbackData);
-    } else {
-        free(mPtr);
+        mPtr = NULL;
     }
-    mPtr = NULL;
+    freeScriptMemory();
 
     if (mBufferID) {
         // Causes a SW crash....
@@ -119,35 +107,46 @@
     return false;
 }
 
-void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset) {
-    rsAssert(lodOffset < mType->getLODCount());
-    mIsTexture = true;
-    mTextureLOD = lodOffset;
+void Allocation::deferedUploadToTexture(const Context *rsc) {
+    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
     mUploadDefered = true;
-    mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
 }
 
 uint32_t Allocation::getGLTarget() const {
-    if (mIsTexture) {
+    if (getIsTexture()) {
         if (mType->getDimFaces()) {
             return GL_TEXTURE_CUBE_MAP;
         } else {
             return GL_TEXTURE_2D;
         }
     }
-    if (mIsVertexBuffer) {
+    if (getIsBufferObject()) {
         return GL_ARRAY_BUFFER;
     }
     return 0;
 }
 
+void Allocation::allocScriptMemory() {
+    rsAssert(!mPtr);
+    mPtr = malloc(mType->getSizeBytes());
+}
+
+void Allocation::freeScriptMemory() {
+    rsAssert(!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT));
+    if (mPtr) {
+        free(mPtr);
+        mPtr = NULL;
+    }
+}
+
+
 void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
     rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
 
-    if (mIsTexture) {
+    if (getIsTexture()) {
         uploadToTexture(rsc);
     }
-    if (mIsVertexBuffer) {
+    if (getIsBufferObject()) {
         uploadToBufferObject(rsc);
     }
 
@@ -156,7 +155,7 @@
 
 void Allocation::uploadToTexture(const Context *rsc) {
 
-    mIsTexture = true;
+    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
     GLenum type = mType->getElement()->getComponent().getGLType();
     GLenum format = mType->getElement()->getComponent().getGLFormat();
 
@@ -164,6 +163,10 @@
         return;
     }
 
+    if (!mPtr) {
+        return;
+    }
+
     bool isFirstUpload = false;
 
     if (!mTextureID) {
@@ -182,41 +185,46 @@
     }
 
     GLenum target = (GLenum)getGLTarget();
-    glBindTexture(target, mTextureID);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
     if (target == GL_TEXTURE_2D) {
-        upload2DTexture(isFirstUpload);
+        upload2DTexture(isFirstUpload, mPtr);
     } else if (target == GL_TEXTURE_CUBE_MAP) {
         uploadCubeTexture(isFirstUpload);
     }
 
-    if (mTextureGenMipmap) {
+    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
 #ifndef ANDROID_RS_BUILD_FOR_HOST
         glGenerateMipmap(target);
 #endif //ANDROID_RS_BUILD_FOR_HOST
     }
 
+
+    if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
+        freeScriptMemory();
+    }
+
     rsc->checkError("Allocation::uploadToTexture");
 }
 
-void Allocation::upload2DTexture(bool isFirstUpload) {
+void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
     GLenum type = mType->getElement()->getComponent().getGLType();
     GLenum format = mType->getElement()->getComponent().getGLFormat();
 
-    Adapter2D adapt(getContext(), this);
-    for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
-        adapt.setLOD(lod+mTextureLOD);
+    GLenum target = (GLenum)getGLTarget();
+    glBindTexture(target, mTextureID);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
-        uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
+    for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
+        const uint8_t *p = (const uint8_t *)ptr;
+        p += mType->getLODOffset(lod);
+
         if (isFirstUpload) {
             glTexImage2D(GL_TEXTURE_2D, lod, format,
-                         adapt.getDimX(), adapt.getDimY(),
-                         0, format, type, ptr);
+                         mType->getLODDimX(lod), mType->getLODDimY(lod),
+                         0, format, type, p);
         } else {
             glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
-                            adapt.getDimX(), adapt.getDimY(),
-                            format, type, ptr);
+                            mType->getLODDimX(lod), mType->getLODDimY(lod),
+                            format, type, p);
         }
     }
 }
@@ -225,6 +233,10 @@
     GLenum type = mType->getElement()->getComponent().getGLType();
     GLenum format = mType->getElement()->getComponent().getGLFormat();
 
+    GLenum target = (GLenum)getGLTarget();
+    glBindTexture(target, mTextureID);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
     GLenum faceOrder[] = {
         GL_TEXTURE_CUBE_MAP_POSITIVE_X,
         GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -238,8 +250,8 @@
     for (uint32_t face = 0; face < 6; face ++) {
         adapt.setFace(face);
 
-        for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
-            adapt.setLOD(lod+mTextureLOD);
+        for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
+            adapt.setLOD(lod);
 
             uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
 
@@ -257,7 +269,7 @@
 }
 
 void Allocation::deferedUploadToBufferObject(const Context *rsc) {
-    mIsVertexBuffer = true;
+    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
     mUploadDefered = true;
 }
 
@@ -265,7 +277,7 @@
     rsAssert(!mType->getDimY());
     rsAssert(!mType->getDimZ());
 
-    mIsVertexBuffer = true;
+    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
 
     if (!mBufferID) {
         glGenBuffers(1, &mBufferID);
@@ -470,8 +482,8 @@
     LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
           prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
 
-    LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i",
-          prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID);
+    LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
+          prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
 }
 
 void Allocation::serialize(OStream *stream) const {
@@ -517,7 +529,7 @@
         return NULL;
     }
 
-    Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_ALL);
+    Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
     alloc->setName(name.string(), name.size());
 
     // Read in all of our allocation data
@@ -596,7 +608,7 @@
 
 void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
     Allocation *alloc = static_cast<Allocation *>(va);
-    alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel);
+    alloc->deferedUploadToTexture(rsc);
 }
 
 void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
@@ -672,81 +684,6 @@
     }
 }
 
-typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
-
-static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) {
-    memcpy(dst, src, count * 2);
-}
-static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) {
-    memcpy(dst, src, count);
-}
-static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) {
-    memcpy(dst, src, count * 4);
-}
-
-static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) {
-    uint16_t *d = static_cast<uint16_t *>(dst);
-    const uint8_t *s = static_cast<const uint8_t *>(src);
-
-    while (count--) {
-        *d = rs888to565(s[0], s[1], s[2]);
-        d++;
-        s+= 3;
-    }
-}
-
-static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) {
-    uint16_t *d = static_cast<uint16_t *>(dst);
-    const uint8_t *s = static_cast<const uint8_t *>(src);
-
-    while (count--) {
-        *d = rs888to565(s[0], s[1], s[2]);
-        d++;
-        s+= 4;
-    }
-}
-
-static ElementConverter_t pickConverter(const Element *dst, const Element *src) {
-    GLenum srcGLType = src->getComponent().getGLType();
-    GLenum srcGLFmt = src->getComponent().getGLFormat();
-    GLenum dstGLType = dst->getComponent().getGLType();
-    GLenum dstGLFmt = dst->getComponent().getGLFormat();
-
-    if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
-        switch (dst->getSizeBytes()) {
-        case 4:
-            return elementConverter_cpy_32;
-        case 2:
-            return elementConverter_cpy_16;
-        case 1:
-            return elementConverter_cpy_8;
-        }
-    }
-
-    if (srcGLType == GL_UNSIGNED_BYTE &&
-        srcGLFmt == GL_RGB &&
-        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
-        dstGLFmt == GL_RGB) {
-
-        return elementConverter_888_to_565;
-    }
-
-    if (srcGLType == GL_UNSIGNED_BYTE &&
-        srcGLFmt == GL_RGBA &&
-        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
-        dstGLFmt == GL_RGB) {
-
-        return elementConverter_8888_to_565;
-    }
-
-    LOGE("pickConverter, unsuported combo, src %p,  dst %p", src, dst);
-    LOGE("pickConverter, srcGLType = %x,  srcGLFmt = %x", srcGLType, srcGLFmt);
-    LOGE("pickConverter, dstGLType = %x,  dstGLFmt = %x", dstGLType, dstGLFmt);
-    src->dumpLOGV("SRC ");
-    dst->dumpLOGV("DST ");
-    return 0;
-}
-
 #ifndef ANDROID_RS_BUILD_FOR_HOST
 
 void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
@@ -754,15 +691,6 @@
     a->syncAll(rsc, src);
 }
 
-RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
-                                           void *bmp, void *callbackData,
-                                           RsBitmapCallback_t callback) {
-    const Type * type = static_cast<const Type *>(vtype);
-    Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback);
-    alloc->incUserRef();
-    return alloc;
-}
-
 void rsi_AllocationCopyFromBitmap(Context *rsc, RsAllocation va, const void *data, size_t dataLen) {
     Allocation *texAlloc = static_cast<Allocation *>(va);
     const Type * t = texAlloc->getType();
@@ -776,16 +704,21 @@
         return;
     }
 
-    memcpy(texAlloc->getPtr(), data, s);
-    if (genMips) {
-        Adapter2D adapt(rsc, texAlloc);
-        Adapter2D adapt2(rsc, texAlloc);
-        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
-            adapt.setLOD(lod);
-            adapt2.setLOD(lod + 1);
-            mip(adapt2, adapt);
+    if (texAlloc->getIsScript()) {
+        memcpy(texAlloc->getPtr(), data, s);
+        if (genMips) {
+            Adapter2D adapt(rsc, texAlloc);
+            Adapter2D adapt2(rsc, texAlloc);
+            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+                adapt.setLOD(lod);
+                adapt2.setLOD(lod + 1);
+                mip(adapt2, adapt);
+            }
         }
+    } else {
+        texAlloc->upload2DTexture(false, data);
     }
+
 }
 
 void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
@@ -854,7 +787,7 @@
 }
 
 RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
-                                      RsAllocationMipmapGenerationControl mips,
+                                      RsAllocationMipmapControl mips,
                                       uint32_t usages) {
     Context *rsc = static_cast<Context *>(con);
     Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages);
@@ -864,7 +797,7 @@
 
 
 RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
-                                           RsAllocationMipmapGenerationControl mips,
+                                           RsAllocationMipmapControl mips,
                                            const void *data, uint32_t usages) {
     Context *rsc = static_cast<Context *>(con);
     Type *t = static_cast<Type *>(vtype);
@@ -877,7 +810,7 @@
     }
 
     memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
-    if (mips == RS_MIPMAP_FULL) {
+    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
         Adapter2D adapt(rsc, texAlloc);
         Adapter2D adapt2(rsc, texAlloc);
         for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
@@ -887,11 +820,12 @@
         }
     }
 
+    texAlloc->deferedUploadToTexture(rsc);
     return texAlloc;
 }
 
 RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
-                                               RsAllocationMipmapGenerationControl mips,
+                                               RsAllocationMipmapControl mips,
                                                const void *data, uint32_t usages) {
     Context *rsc = static_cast<Context *>(con);
     Type *t = static_cast<Type *>(vtype);
@@ -917,7 +851,7 @@
         // Move the data pointer to the next cube face
         sourcePtr += cpySize;
 
-        if (mips == RS_MIPMAP_FULL) {
+        if (mips == RS_ALLOCATION_MIPMAP_FULL) {
             Adapter2D adapt(rsc, texAlloc);
             Adapter2D adapt2(rsc, texAlloc);
             adapt.setFace(face);
@@ -930,5 +864,6 @@
         }
     }
 
+    texAlloc->deferedUploadToTexture(rsc);
     return texAlloc;
 }
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index e63c7ab..4a5f3da 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -30,7 +30,6 @@
 
 public:
     Allocation(Context *rsc, const Type *, uint32_t usages);
-    Allocation(Context *rsc, const Type *, void *bmp, void *callbackData, RsBitmapCallback_t callback);
 
     virtual ~Allocation();
 
@@ -46,7 +45,7 @@
 
     void syncAll(Context *rsc, RsAllocationUsageType src);
 
-    void deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset);
+    void deferedUploadToTexture(const Context *rsc);
     void uploadToTexture(const Context *rsc);
     uint32_t getTextureID() const {return mTextureID;}
 
@@ -88,14 +87,25 @@
 
     virtual void uploadCheck(Context *rsc);
 
-    bool getIsTexture() const {return mIsTexture;}
-    bool getIsBufferObject() const {return mIsVertexBuffer;}
+    bool getIsScript() const {
+        return (mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0;
+    }
+    bool getIsTexture() const {
+        return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
+    }
+    bool getIsBufferObject() const {
+        return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
+    }
 
     void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
     void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
 
     void sendDirty() const;
-    bool getHasGraphicsMipmaps() const {return mTextureGenMipmap;}
+    bool getHasGraphicsMipmaps() const {
+        return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE;
+    }
+
+    void upload2DTexture(bool isFirstUpload, const void *ptr);
 
 protected:
     ObjectBaseRef<const Type> mType;
@@ -115,6 +125,7 @@
     bool mGpuRead;
 
     uint32_t mUsageFlags;
+    RsAllocationMipmapControl mMipmapControl;
 
     // more usage hint data from the application
     // which can be used by a driver to pick the best memory type.
@@ -125,23 +136,22 @@
 
     // Is this a legal structure to be used as a texture source.
     // Initially this will require 1D or 2D and color data
-    bool mIsTexture;
-    bool mTextureGenMipmap;
-    uint32_t mTextureLOD;
     uint32_t mTextureID;
 
     // Is this a legal structure to be used as a vertex source.
     // Initially this will require 1D and x(yzw).  Additional per element data
     // is allowed.
-    bool mIsVertexBuffer;
     uint32_t mBufferID;
 
     bool mUploadDefered;
 
 private:
     void init(Context *rsc, const Type *);
-    void upload2DTexture(bool isFirstUpload);
     void uploadCubeTexture(bool isFirstUpload);
+
+    void allocScriptMemory();
+    void freeScriptMemory();
+
 };
 
 }
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 1dc9540..49ee676 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -207,6 +207,7 @@
     uint32_t getMaxFragmentTextures() const {return mGL.mMaxFragmentTextureImageUnits;}
     uint32_t getMaxFragmentUniformVectors() const {return mGL.mMaxFragmentUniformVectors;}
     uint32_t getMaxVertexUniformVectors() const {return mGL.mMaxVertexUniformVectors;}
+    uint32_t getMaxVertexAttributes() const {return mGL.mMaxVertexAttribs;}
 
     void launchThreads(WorkerCallback_t cbk, void *data);
     uint32_t getWorkerPoolSize() const {return (uint32_t)mWorkers.mCount;}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 3d17be2..3f9a9d6 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -463,7 +463,7 @@
 
     // This will dirty the texture and the shader so next time
     // we draw it will upload the data
-    mTextTexture->deferedUploadToTexture(mRSC, false, 0);
+    mTextTexture->deferedUploadToTexture(mRSC);
     mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get());
 
     // Some debug code
@@ -529,7 +529,7 @@
 
     Allocation *cacheAlloc = new Allocation(mRSC, texType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE);
     mTextTexture.set(cacheAlloc);
-    mTextTexture->deferedUploadToTexture(mRSC, false, 0);
+    mTextTexture->deferedUploadToTexture(mRSC);
 
     // Split up our cache texture into lines of certain widths
     int32_t nextLine = 0;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index b3dbf11..507430d 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -402,7 +402,7 @@
 extern const char rs_runtime_lib_bc[];
 extern unsigned rs_runtime_lib_bc_size;
 
-void ScriptCState::runCompiler(Context *rsc, ScriptC *s, const char *resName) {
+void ScriptCState::runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir) {
     {
         s->mBccScript = bccCreateScript();
         s->mEnviroment.mIsThreadable = true;
@@ -413,7 +413,8 @@
         if (bccReadBC(s->mBccScript,
                       s->mEnviroment.mScriptText,
                       s->mEnviroment.mScriptTextLength,
-                      resName) >= 0) {
+                      resName,
+                      cacheDir) >= 0) {
           //bccLinkBC(s->mBccScript, rs_runtime_lib_bc, rs_runtime_lib_bc_size);
           bccCompileBC(s->mBccScript);
         } else {
@@ -534,7 +535,7 @@
     ss->mScript->mEnviroment.mScriptTextLength = len;
 }
 
-RsScript rsi_ScriptCCreate(Context * rsc, const char *resName)
+RsScript rsi_ScriptCCreate(Context * rsc, const char *resName, const char *cacheDir)
 {
     ScriptCState *ss = &rsc->mScriptC;
 
@@ -542,7 +543,7 @@
     ss->mScript.clear();
     s->incUserRef();
 
-    ss->runCompiler(rsc, s.get(), resName);
+    ss->runCompiler(rsc, s.get(), resName, cacheDir);
     ss->clear(rsc);
     return s.get();
 }
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index ab2db5c8..a714132 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -83,7 +83,7 @@
     void init(Context *rsc);
 
     void clear(Context *rsc);
-    void runCompiler(Context *rsc, ScriptC *s, const char *resName);
+    void runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
 
     struct SymbolTable_t {
         const char * mName;
diff --git a/libs/rs/rsVertexArray.cpp b/libs/rs/rsVertexArray.cpp
index 8a9fafe..d9393fe 100644
--- a/libs/rs/rsVertexArray.cpp
+++ b/libs/rs/rsVertexArray.cpp
@@ -81,8 +81,12 @@
                            class VertexArrayState *state,
                            ShaderCache *sc) const {
     rsc->checkError("VertexArray::setupGL2 start");
-    for (uint32_t ct=1; ct <= state->mLastEnableCount; ct++) {
-        glDisableVertexAttribArray(ct);
+    uint32_t maxAttrs = state->mAttrsEnabledSize;
+    for (uint32_t ct=1; ct < maxAttrs; ct++) {
+        if(state->mAttrsEnabled[ct]) {
+            glDisableVertexAttribArray(ct);
+            state->mAttrsEnabled[ct] = false;
+        }
     }
 
     rsc->checkError("VertexArray::setupGL2 disabled");
@@ -91,10 +95,11 @@
         if (rsc->props.mLogShadersAttr) {
             logAttrib(ct, slot);
         }
-        if (slot < 0) {
+        if (slot < 0 || slot >= (int32_t)maxAttrs) {
             continue;
         }
         glEnableVertexAttribArray(slot);
+        state->mAttrsEnabled[slot] = true;
         glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
         glVertexAttribPointer(slot,
                               mAttribs[ct].size,
@@ -103,12 +108,25 @@
                               mAttribs[ct].stride,
                               mAttribs[ct].ptr + mAttribs[ct].offset);
     }
-    state->mLastEnableCount = mCount;
     rsc->checkError("VertexArray::setupGL2 done");
 }
 ////////////////////////////////////////////
+VertexArrayState::VertexArrayState() {
+    mAttrsEnabled = NULL;
+    mAttrsEnabledSize = 0;
+}
 
-void VertexArrayState::init(Context *) {
-    mLastEnableCount = 0;
+VertexArrayState::~VertexArrayState() {
+    if (mAttrsEnabled) {
+        delete[] mAttrsEnabled;
+        mAttrsEnabled = NULL;
+    }
+}
+void VertexArrayState::init(Context *rsc) {
+    mAttrsEnabledSize = rsc->getMaxVertexAttributes();
+    mAttrsEnabled = new bool[mAttrsEnabledSize];
+    for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) {
+        mAttrsEnabled[ct] = false;
+    }
 }
 
diff --git a/libs/rs/rsVertexArray.h b/libs/rs/rsVertexArray.h
index 7bcfa68..45d9e82 100644
--- a/libs/rs/rsVertexArray.h
+++ b/libs/rs/rsVertexArray.h
@@ -63,9 +63,12 @@
 
 class VertexArrayState {
 public:
+    VertexArrayState();
+    ~VertexArrayState();
     void init(Context *);
 
-    uint32_t mLastEnableCount;
+    bool *mAttrsEnabled;
+    uint32_t mAttrsEnabledSize;
 };
 
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2836005..6d47c44 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -752,6 +752,10 @@
                 mode = mMode;
             }
             if (mode != mMode) {
+
+                // automatically handle audio focus for mode changes
+                handleFocusForCalls(mMode, mode);
+
                 if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
                     mMode = mode;
 
@@ -807,6 +811,38 @@
         }
     }
 
+    /** pre-condition: oldMode != newMode */
+    private void handleFocusForCalls(int oldMode, int newMode) {
+        // if ringing
+        if (newMode == AudioSystem.MODE_RINGTONE) {
+            // if not ringing silently
+            int ringVolume = AudioService.this.getStreamVolume(AudioManager.STREAM_RING);
+            if (ringVolume > 0) {
+                // request audio focus for the communication focus entry
+                requestAudioFocus(AudioManager.STREAM_RING,
+                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
+                        null, null /* both allowed to be null only for this clientId */,
+                        IN_VOICE_COMM_FOCUS_ID /*clientId*/);
+
+            }
+        }
+        // if entering call
+        else if ((newMode == AudioSystem.MODE_IN_CALL)
+                || (newMode == AudioSystem.MODE_IN_COMMUNICATION)) {
+            // request audio focus for the communication focus entry
+            // (it's ok if focus was already requested during ringing)
+            requestAudioFocus(AudioManager.STREAM_RING,
+                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
+                    null, null /* both allowed to be null only for this clientId */,
+                    IN_VOICE_COMM_FOCUS_ID /*clientId*/);
+        }
+        // if exiting call
+        else if (newMode == AudioSystem.MODE_NORMAL) {
+            // abandon audio focus for communication focus entry
+            abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID);
+        }
+    }
+
     /** @see AudioManager#getMode() */
     public int getMode() {
         return mMode;
@@ -2093,28 +2129,11 @@
                 synchronized(mRingingLock) {
                     mIsRinging = true;
                 }
-                int ringVolume = AudioService.this.getStreamVolume(AudioManager.STREAM_RING);
-                if (ringVolume > 0) {
-                    requestAudioFocus(AudioManager.STREAM_RING,
-                                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
-                                null, null /* both allowed to be null only for this clientId */,
-                                IN_VOICE_COMM_FOCUS_ID /*clientId*/);
-                }
-            } else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
-                //Log.v(TAG, " CALL_STATE_OFFHOOK");
+            } else if ((state == TelephonyManager.CALL_STATE_OFFHOOK)
+                    || (state == TelephonyManager.CALL_STATE_IDLE)) {
                 synchronized(mRingingLock) {
                     mIsRinging = false;
                 }
-                requestAudioFocus(AudioManager.STREAM_RING,
-                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
-                        null, null /* both allowed to be null only for this clientId */,
-                        IN_VOICE_COMM_FOCUS_ID /*clientId*/);
-            } else if (state == TelephonyManager.CALL_STATE_IDLE) {
-                //Log.v(TAG, " CALL_STATE_IDLE");
-                synchronized(mRingingLock) {
-                    mIsRinging = false;
-                }
-                abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID);
             }
         }
     };
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index e17a640..63ec6b2 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1494,17 +1494,6 @@
         } else if (fileType == MediaFile.FILE_TYPE_WPL) {
             processWplPlayList(path, playListDirectory, membersUri);
         }
-
-        Cursor cursor = mMediaProvider.query(membersUri, PLAYLIST_MEMBERS_PROJECTION, null,
-                null, null);
-        try {
-            if (cursor == null || cursor.getCount() == 0) {
-                Log.d(TAG, "playlist is empty - deleting");
-                mMediaProvider.delete(uri, null, null);
-            }
-        } finally {
-            if (cursor != null) cursor.close();
-        }
     }
 
     private void processPlayLists() throws RemoteException {
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 4a9e483..db08b27 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -91,6 +91,7 @@
             Files.FileColumns.DATE_MODIFIED, // 5
     };
     private static final String ID_WHERE = Files.FileColumns._ID + "=?";
+    private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
     private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?";
     private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
                                             + Files.FileColumns.FORMAT + "=?";
@@ -154,6 +155,25 @@
 
     private int beginSendObject(String path, int format, int parent,
                          int storage, long size, long modified) {
+        // first make sure the object does not exist
+        if (path != null) {
+            Cursor c = null;
+            try {
+                c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, PATH_WHERE,
+                        new String[] { path }, null);
+                if (c != null && c.getCount() > 0) {
+                    Log.w(TAG, "file already exists in beginSendObject: " + path);
+                    return -1;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException in beginSendObject", e);
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
+            }
+        }
+
         mDatabaseModified = true;
         ContentValues values = new ContentValues();
         values.put(Files.FileColumns.DATA, path);
@@ -705,26 +725,38 @@
         }
     }
 
-    private int deleteRecursive(int handle) throws RemoteException {
-        int[] children = getObjectList(0 /* storageID */, 0 /* format */, handle);
-        Uri uri = Files.getMtpObjectsUri(mVolumeName, handle);
-        // delete parent first, to avoid potential infinite recursion
-        int count = mMediaProvider.delete(uri, null, null);
-        if (count == 1) {
-            if (children != null) {
-                for (int i = 0; i < children.length; i++) {
-                    count += deleteRecursive(children[i]);
-                }
-            }
-        }
-        return count;
-    }
-
     private int deleteFile(int handle) {
         Log.d(TAG, "deleteFile: " + handle);
         mDatabaseModified = true;
+        String path = null;
+        int format = 0;
+
+        Cursor c = null;
         try {
-            if (deleteRecursive(handle) > 0) {
+            c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
+                            ID_WHERE, new String[] {  Integer.toString(handle) }, null);
+            if (c != null && c.moveToNext()) {
+                // don't convert to media path here, since we will be matching
+                // against paths in the database matching /data/media
+                path = c.getString(1);
+                format = c.getInt(3);
+            } else {
+                return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
+            }
+
+            if (path == null || format == 0) {
+                return MtpConstants.RESPONSE_GENERAL_ERROR;
+            }
+
+            if (format == MtpConstants.FORMAT_ASSOCIATION) {
+                // recursive case - delete all children first
+                Uri uri = Files.getMtpObjectsUri(mVolumeName);
+                int count = mMediaProvider.delete(uri, "_data LIKE ?",
+                        new String[] { path + "/%"});
+            }
+
+            Uri uri = Files.getMtpObjectsUri(mVolumeName, handle);
+            if (mMediaProvider.delete(uri, null, null) > 0) {
                 return MtpConstants.RESPONSE_OK;
             } else {
                 return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
@@ -732,6 +764,10 @@
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in deleteFile", e);
             return MtpConstants.RESPONSE_GENERAL_ERROR;
+        } finally {
+            if (c != null) {
+                c.close();
+            }
         }
     }
 
diff --git a/media/jni/android_media_MtpServer.cpp b/media/jni/android_media_MtpServer.cpp
index 28a80cb..87ce12a 100644
--- a/media/jni/android_media_MtpServer.cpp
+++ b/media/jni/android_media_MtpServer.cpp
@@ -102,7 +102,7 @@
             return false;
         }
 
-        mServer = new MtpServer(mFd, mDatabase, AID_SDCARD_RW, 0664, 0775);
+        mServer = new MtpServer(mFd, mDatabase, AID_MEDIA_RW, 0664, 0775);
         mServer->addStorage(mStoragePath, mReserveSpace);
         sMutex.unlock();
 
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 29f16d8..235d752 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -140,38 +140,6 @@
     return meta;
 }
 
-/*
- * Returns -1 if frame skipping request is too long.
- * Returns  0 if there is no need to skip frames.
- * Returns  1 if we need to skip frames.
- */
-static int skipFrame(int64_t timestampUs,
-        const MediaSource::ReadOptions *options) {
-
-    int64_t skipFrameUs;
-    if (!options || !options->getSkipFrame(&skipFrameUs)) {
-        return 0;
-    }
-
-    if (skipFrameUs <= timestampUs) {
-        return 0;
-    }
-
-    // Safe guard against the abuse of the kSkipFrame_Option.
-    if (skipFrameUs - timestampUs >= 1E6) {
-        LOGE("Frame skipping requested is way too long: %lld us",
-            skipFrameUs - timestampUs);
-
-        return -1;
-    }
-
-    LOGV("skipFrame: %lld us > timestamp: %lld us",
-        skipFrameUs, timestampUs);
-
-    return 1;
-
-}
-
 void AudioSource::rampVolume(
         int32_t startFrame, int32_t rampDurationFrames,
         uint8_t *data,   size_t bytes) {
@@ -218,7 +186,7 @@
     CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
 
     int err = 0;
-    while (mStarted) {
+    if (mStarted) {
 
         uint32_t numFramesRecorded;
         mRecord->getPosition(&numFramesRecorded);
@@ -268,12 +236,6 @@
             if (mCollectStats) {
                 mTotalLostFrames += (numLostBytes >> 1);
             }
-            if ((err = skipFrame(timestampUs, options)) == -1) {
-                buffer->release();
-                return UNKNOWN_ERROR;
-            } else if (err != 0) {
-                continue;
-            }
             memset(buffer->data(), 0, numLostBytes);
             buffer->set_range(0, numLostBytes);
             if (numFramesRecorded == 0) {
@@ -294,12 +256,6 @@
 
         int64_t recordDurationUs = (1000000LL * n >> 1) / sampleRate;
         timestampUs += recordDurationUs;
-        if ((err = skipFrame(timestampUs, options)) == -1) {
-            buffer->release();
-            return UNKNOWN_ERROR;
-        } else if (err != 0) {
-            continue;
-        }
 
         if (mPrevSampleTimeUs - mStartTimeUs < kAutoRampStartUs) {
             // Mute the initial video recording signal
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index fac7b78..2f3353b 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -665,45 +665,22 @@
 
     {
         Mutex::Autolock autoLock(mLock);
-        while (mStarted) {
-            while(mFramesReceived.empty()) {
-                mFrameAvailableCondition.wait(mLock);
-            }
-
-            if (!mStarted) {
-                return OK;
-            }
-
-            frame = *mFramesReceived.begin();
-            mFramesReceived.erase(mFramesReceived.begin());
-
-            frameTime = *mFrameTimes.begin();
-            mFrameTimes.erase(mFrameTimes.begin());
-            int64_t skipTimeUs;
-            if (!options || !options->getSkipFrame(&skipTimeUs)) {
-                skipTimeUs = frameTime;
-            }
-            if (skipTimeUs > frameTime) {
-                LOGV("skipTimeUs: %lld us > frameTime: %lld us",
-                    skipTimeUs, frameTime);
-                releaseOneRecordingFrame(frame);
-                ++mNumFramesDropped;
-                // Safeguard against the abuse of the kSkipFrame_Option.
-                if (skipTimeUs - frameTime >= 1E6) {
-                    LOGE("Frame skipping requested is way too long: %lld us",
-                        skipTimeUs - frameTime);
-                    return UNKNOWN_ERROR;
-                }
-            } else {
-                mFramesBeingEncoded.push_back(frame);
-                *buffer = new MediaBuffer(frame->pointer(), frame->size());
-                (*buffer)->setObserver(this);
-                (*buffer)->add_ref();
-                (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
-
-                return OK;
-            }
+        while (mStarted && mFramesReceived.empty()) {
+            mFrameAvailableCondition.wait(mLock);
         }
+        if (!mStarted) {
+            return OK;
+        }
+        frame = *mFramesReceived.begin();
+        mFramesReceived.erase(mFramesReceived.begin());
+
+        frameTime = *mFrameTimes.begin();
+        mFrameTimes.erase(mFrameTimes.begin());
+        mFramesBeingEncoded.push_back(frame);
+        *buffer = new MediaBuffer(frame->pointer(), frame->size());
+        (*buffer)->setObserver(this);
+        (*buffer)->add_ref();
+        (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
     }
     return OK;
 }
@@ -729,7 +706,7 @@
 
     // May need to skip frame or modify timestamp. Currently implemented
     // by the subclass CameraSourceTimeLapse.
-    if(skipCurrentFrame(timestampUs)) {
+    if (skipCurrentFrame(timestampUs)) {
         releaseOneRecordingFrame(data);
         return;
     }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 602aa9f..06c4c98 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1734,6 +1734,8 @@
     } else {
         prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
     }
+    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
+
     sp<MetaData> meta_data;
 
     mNumSamples = 0;
diff --git a/media/libstagefright/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
index b4ef338..fd0e79c3 100644
--- a/media/libstagefright/MediaSource.cpp
+++ b/media/libstagefright/MediaSource.cpp
@@ -32,7 +32,6 @@
     mOptions = 0;
     mSeekTimeUs = 0;
     mLatenessUs = 0;
-    mSkipFrameUntilTimeUs = 0;
 }
 
 void MediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
@@ -54,21 +53,6 @@
     return (mOptions & kSeekTo_Option) != 0;
 }
 
-void MediaSource::ReadOptions::clearSkipFrame() {
-    mOptions &= ~kSkipFrame_Option;
-    mSkipFrameUntilTimeUs = 0;
-}
-
-void MediaSource::ReadOptions::setSkipFrame(int64_t timeUs) {
-    mOptions |= kSkipFrame_Option;
-    mSkipFrameUntilTimeUs = timeUs;
-}
-
-bool MediaSource::ReadOptions::getSkipFrame(int64_t *timeUs) const {
-    *timeUs = mSkipFrameUntilTimeUs;
-    return (mOptions & kSkipFrame_Option) != 0;
-}
-
 void MediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
     mLatenessUs = lateness_us;
 }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 4bf922f..69ab75a 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1426,7 +1426,6 @@
       mSeekTimeUs(-1),
       mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
       mTargetTimeUs(-1),
-      mSkipTimeUs(-1),
       mLeftOverBuffer(NULL),
       mPaused(false),
       mNativeWindow(nativeWindow) {
@@ -2030,6 +2029,9 @@
 
                 mFilledBuffers.push_back(i);
                 mBufferFilled.signal();
+                if (mIsEncoder) {
+                    sched_yield();
+                }
             }
 
             break;
@@ -2635,15 +2637,13 @@
 
     for (;;) {
         MediaBuffer *srcBuffer;
-        MediaSource::ReadOptions options;
-        if (mSkipTimeUs >= 0) {
-            options.setSkipFrame(mSkipTimeUs);
-        }
         if (mSeekTimeUs >= 0) {
             if (mLeftOverBuffer) {
                 mLeftOverBuffer->release();
                 mLeftOverBuffer = NULL;
             }
+
+            MediaSource::ReadOptions options;
             options.setSeekTo(mSeekTimeUs, mSeekMode);
 
             mSeekTimeUs = -1;
@@ -2668,13 +2668,14 @@
 
             err = OK;
         } else {
-            err = mSource->read(&srcBuffer, &options);
+            err = mSource->read(&srcBuffer);
         }
 
         if (err != OK) {
             signalEOS = true;
             mFinalStatus = err;
             mSignalledEOS = true;
+            mBufferFilled.signal();
             break;
         }
 
@@ -3304,12 +3305,6 @@
     if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
         seeking = true;
     }
-    int64_t skipTimeUs;
-    if (options && options->getSkipFrame(&skipTimeUs)) {
-        mSkipTimeUs = skipTimeUs;
-    } else {
-        mSkipTimeUs = -1;
-    }
 
     if (mInitialBufferSubmit) {
         mInitialBufferSubmit = false;
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 446021c..9332120 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -318,7 +318,7 @@
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
     if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
-        int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2;
+        int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3);
         if (pos > mSize) {
             pos = mSize;
         }
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index e9131a6..45e018d 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -149,7 +149,25 @@
     }
 
     if (header.version_major == 4) {
-        if (!removeUnsynchronizationV2_4()) {
+        void *copy = malloc(size);
+        memcpy(copy, mData, size);
+
+        bool success = removeUnsynchronizationV2_4(false /* iTunesHack */);
+        if (!success) {
+            memcpy(mData, copy, size);
+            mSize = size;
+
+            success = removeUnsynchronizationV2_4(true /* iTunesHack */);
+
+            if (success) {
+                LOGV("Had to apply the iTunes hack to parse this ID3 tag");
+            }
+        }
+
+        free(copy);
+        copy = NULL;
+
+        if (!success) {
             free(mData);
             mData = NULL;
 
@@ -261,7 +279,7 @@
     }
 }
 
-bool ID3::removeUnsynchronizationV2_4() {
+bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) {
     size_t oldSize = mSize;
 
     size_t offset = 0;
@@ -271,7 +289,9 @@
         }
 
         size_t dataSize;
-        if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) {
+        if (iTunesHack) {
+            dataSize = U32_AT(&mData[offset + 4]);
+        } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) {
             return false;
         }
 
@@ -308,7 +328,7 @@
             flags &= ~2;
         }
 
-        if (flags != prevFlags) {
+        if (flags != prevFlags || iTunesHack) {
             WriteSyncsafeInteger(&mData[offset + 4], dataSize);
             mData[offset + 8] = flags >> 8;
             mData[offset + 9] = flags & 0xff;
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 7ddbb41..98c82a4 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -80,7 +80,7 @@
     bool parseV1(const sp<DataSource> &source);
     bool parseV2(const sp<DataSource> &source);
     void removeUnsynchronization();
-    bool removeUnsynchronizationV2_4();
+    bool removeUnsynchronizationV2_4(bool iTunesHack);
 
     static bool ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x);
 
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index b371e41..236cd0a 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -683,10 +683,6 @@
         path += "/";
     path += (const char *)name;
 
-    // file should not already exist
-    if (access(path, R_OK) == 0)
-        return MTP_RESPONSE_GENERAL_ERROR;
-
     // check space first
     if (mSendObjectFileSize > storage->getFreeSpace())
         return MTP_RESPONSE_STORAGE_FULL;
diff --git a/native/android/asset_manager.cpp b/native/android/asset_manager.cpp
index 33f088d..f5db57c 100644
--- a/native/android/asset_manager.cpp
+++ b/native/android/asset_manager.cpp
@@ -178,6 +178,11 @@
     return asset->mAsset->seek(offset, whence);
 }
 
+off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence)
+{
+    return asset->mAsset->seek(offset, whence);
+}
+
 void AAsset_close(AAsset* asset)
 {
     asset->mAsset->close();
@@ -194,14 +199,35 @@
     return asset->mAsset->getLength();
 }
 
+off64_t AAsset_getLength64(AAsset* asset)
+{
+    return asset->mAsset->getLength();
+}
+
 off_t AAsset_getRemainingLength(AAsset* asset)
 {
     return asset->mAsset->getRemainingLength();
 }
 
+off64_t AAsset_getRemainingLength64(AAsset* asset)
+{
+    return asset->mAsset->getRemainingLength();
+}
+
 int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength)
 {
-    return asset->mAsset->openFileDescriptor((off64_t*)outStart, (off64_t*)outLength);
+    off64_t outStart64, outLength64;
+
+    int ret = asset->mAsset->openFileDescriptor(&outStart64, &outLength64);
+
+    *outStart = off_t(outStart64);
+    *outLength = off_t(outLength64);
+    return ret;
+}
+
+int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength)
+{
+    return asset->mAsset->openFileDescriptor(outStart, outLength);
 }
 
 int AAsset_isAllocated(AAsset* asset)
diff --git a/native/include/android/asset_manager.h b/native/include/android/asset_manager.h
index 4fa0ef3..f5df46b 100644
--- a/native/include/android/asset_manager.h
+++ b/native/include/android/asset_manager.h
@@ -94,6 +94,17 @@
 off_t AAsset_seek(AAsset* asset, off_t offset, int whence);
 
 /**
+ * Seek to the specified offset within the asset data.  'whence' uses the
+ * same constants as lseek()/fseek().
+ *
+ * Uses 64-bit data type for large files as opposed to the 32-bit type used
+ * by AAsset_seek.
+ *
+ * Returns the new position on success, or (off64_t) -1 on error.
+ */
+off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence);
+
+/**
  * Close the asset, freeing all associated resources.
  */
 void AAsset_close(AAsset* asset);
@@ -111,12 +122,27 @@
 off_t AAsset_getLength(AAsset* asset);
 
 /**
+ * Report the total size of the asset data. Reports the size using a 64-bit
+ * number insted of 32-bit as AAsset_getLength.
+ */
+off64_t AAsset_getLength64(AAsset* asset);
+
+/**
  * Report the total amount of asset data that can be read from the current position.
  */
 off_t AAsset_getRemainingLength(AAsset* asset);
 
 /**
- * Open a new file descriptor that can be used to read the asset data.
+ * Report the total amount of asset data that can be read from the current position.
+ *
+ * Uses a 64-bit number instead of a 32-bit number as AAsset_getRemainingLength does.
+ */
+off64_t AAsset_getRemainingLength64(AAsset* asset);
+
+/**
+ * Open a new file descriptor that can be used to read the asset data. If the
+ * start or length cannot be represented by a 32-bit number, it will be
+ * truncated. If the file is large, use AAsset_openFileDescriptor64 instead.
  *
  * Returns < 0 if direct fd access is not possible (for example, if the asset is
  * compressed).
@@ -124,6 +150,17 @@
 int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength);
 
 /**
+ * Open a new file descriptor that can be used to read the asset data.
+ *
+ * Uses a 64-bit number for the offset and length instead of 32-bit instead of
+ * as AAsset_openFileDescriptor does.
+ *
+ * Returns < 0 if direct fd access is not possible (for example, if the asset is
+ * compressed).
+ */
+int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength);
+
+/**
  * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not
  * mmapped).
  */
diff --git a/opengl/tests/hwc/hwc_stress.cpp b/opengl/tests/hwc/hwc_stress.cpp
index d119734..d41b074 100644
--- a/opengl/tests/hwc/hwc_stress.cpp
+++ b/opengl/tests/hwc/hwc_stress.cpp
@@ -120,14 +120,21 @@
                                  // larger than the default screen size
 const unsigned int passesPerGroup = 10; // A group of passes all use the same
                                         // graphic buffers
-const float rareRatio = 0.1; // Ratio at which rare conditions are produced.
+
+// Ratios at which rare and frequent conditions should be produced
+const float rareRatio = 0.1;
+const float freqRatio = 0.9;
 
 // Defaults for command-line options
 const bool defaultVerbose = false;
 const unsigned int defaultStartPass = 0;
 const unsigned int defaultEndPass = 99999;
 const unsigned int defaultPerPassNumSet = 10;
-const float defaultPerPassDelay = 0.1;
+const float defaultPerSetDelay = 0.0; // Default delay after each set
+                                      // operation.  Default delay of
+                                      // zero used so as to perform the
+                                      // the set operations as quickly
+                                      // as possible.
 const float defaultEndDelay = 2.0; // Default delay between completion of
                                    // final pass and restart of framework
 const float defaultDuration = FLT_MAX; // A fairly long time, so that
@@ -139,7 +146,7 @@
 static unsigned int startPass = defaultStartPass;
 static unsigned int endPass = defaultEndPass;
 static unsigned int numSet = defaultPerPassNumSet;
-static float perSetDelay = defaultPerPassDelay;
+static float perSetDelay = defaultPerSetDelay;
 static float endDelay = defaultEndDelay;
 static float duration = defaultDuration;
 
@@ -195,18 +202,19 @@
 };
 
 // File scope constants
-static const struct {
+static const struct graphicFormat {
     unsigned int format;
     const char *desc;
+    unsigned int wMod, hMod; // Width/height mod this value must equal zero
 } graphicFormat[] = {
-    {HAL_PIXEL_FORMAT_RGBA_8888, "RGBA8888"},
-    {HAL_PIXEL_FORMAT_RGBX_8888, "RGBX8888"},
-//    {HAL_PIXEL_FORMAT_RGB_888, "RGB888"},  // Known issue: 3198458
-    {HAL_PIXEL_FORMAT_RGB_565, "RGB565"},
-    {HAL_PIXEL_FORMAT_BGRA_8888, "BGRA8888"},
-    {HAL_PIXEL_FORMAT_RGBA_5551, "RGBA5551"},
-    {HAL_PIXEL_FORMAT_RGBA_4444, "RGBA4444"},
-//    {HAL_PIXEL_FORMAT_YV12, "YV12"}, // Currently not supported by HWC
+    {HAL_PIXEL_FORMAT_RGBA_8888, "RGBA8888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGBX_8888, "RGBX8888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGB_888, "RGB888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGB_565, "RGB565", 1, 1},
+    {HAL_PIXEL_FORMAT_BGRA_8888, "BGRA8888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGBA_5551, "RGBA5551", 1, 1},
+    {HAL_PIXEL_FORMAT_RGBA_4444, "RGBA4444", 1, 1},
+    {HAL_PIXEL_FORMAT_YV12, "YV12", 2, 2},
 };
 const unsigned int blendingOps[] = {
     HWC_BLENDING_NONE,
@@ -471,7 +479,7 @@
             exit(20);
         }
 
-	// Prandomly select a subset of frames to be used by this pass.
+        // Prandomly select a subset of frames to be used by this pass.
         vector <vector <sp<GraphicBuffer> > > selectedFrames;
         selectedFrames = vectorRandSelect(frames, list->numHwLayers);
 
@@ -505,6 +513,28 @@
                 + testRandMod(width - layer->displayFrame.left) + 1;
             layer->displayFrame.bottom = layer->displayFrame.top
                 + testRandMod(height - layer->displayFrame.top) + 1;
+
+            // Increase the frequency that a scale factor of 1.0 from
+            // the sourceCrop to displayFrame occurs.  This is the
+            // most common scale factor used by applications and would
+            // be rarely produced by this stress test without this
+            // logic.
+            if (testRandFract() <= freqRatio) {
+                // Only change to scale factor to 1.0 if both the
+                // width and height will fit.
+                int sourceWidth = layer->sourceCrop.right
+                                  - layer->sourceCrop.left;
+                int sourceHeight = layer->sourceCrop.bottom
+                                   - layer->sourceCrop.top;
+                if (((layer->displayFrame.left + sourceWidth) <= width)
+                    && ((layer->displayFrame.top + sourceHeight) <= height)) {
+                    layer->displayFrame.right = layer->displayFrame.left
+                                                + sourceWidth;
+                    layer->displayFrame.bottom = layer->displayFrame.top
+                                                 + sourceHeight;
+                }
+            }
+
             layer->visibleRegionScreen.numRects = 1;
             layer->visibleRegionScreen.rects = &layer->displayFrame;
         }
@@ -720,7 +750,6 @@
 {
     unsigned char* buf = NULL;
     status_t err;
-    unsigned int numPixels = gBuf->getWidth() * gBuf->getHeight();
     uint32_t pixel;
 
     // RGB 2 YUV conversion ratios
@@ -806,9 +835,16 @@
         exit(51);
     }
 
-    for (unsigned int n1 = 0; n1 < numPixels; n1++) {
-        memmove(buf, &pixel, attrib->bytes);
-        buf += attrib->bytes;
+    for (unsigned int row = 0; row < gBuf->getHeight(); row++) {
+        for (unsigned int col = 0; col < gBuf->getWidth(); col++) {
+          memmove(buf, &pixel, attrib->bytes);
+          buf += attrib->bytes;
+        }
+        for (unsigned int pad = 0;
+             pad < (gBuf->getStride() - gBuf->getWidth()) * attrib->bytes;
+             pad++) {
+            *buf++ = testRandMod(256);
+        }
     }
 
     err = gBuf->unlock();
@@ -827,14 +863,13 @@
 
     const struct yuvAttrib {
         int format;
-        size_t padWidth;
         bool   planar;
         unsigned int uSubSampX;
         unsigned int uSubSampY;
         unsigned int vSubSampX;
         unsigned int vSubSampY;
     } yuvAttributes[] = {
-        { HAL_PIXEL_FORMAT_YV12, 16, true, 2, 2, 2, 2},
+        { HAL_PIXEL_FORMAT_YV12, true, 2, 2, 2, 2},
     };
 
     const struct yuvAttrib *attrib;
@@ -850,12 +885,6 @@
 
     assert(attrib->planar == true); // So far, only know how to handle planar
 
-    // If needed round width up to pad size
-    if (width % attrib->padWidth) {
-        width += attrib->padWidth - (width % attrib->padWidth);
-    }
-    assert((width % attrib->padWidth) == 0);
-
     err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
     if (err != 0) {
         testPrintE("fillColor lock failed: %d", err);
@@ -863,23 +892,35 @@
     }
 
     // Fill in Y component
-    for (unsigned int x = 0; x < width; x++) {
-        for (unsigned int y = 0; y < height; y++) {
-            *buf++ = (x < gBuf->getWidth()) ? (255 * color.y()) : 0;
+    for (unsigned int row = 0; row < height; row++) {
+        for (unsigned int col = 0; col < width; col++) {
+            *buf++ = 255 * color.y();
+        }
+        for (unsigned int pad = 0; pad < gBuf->getStride() - gBuf->getWidth();
+             pad++) {
+             *buf++ = testRandMod(256);
         }
     }
 
     // Fill in U component
-    for (unsigned int x = 0; x < width; x += attrib->uSubSampX) {
-        for (unsigned int y = 0; y < height; y += attrib->uSubSampY) {
-            *buf++ = (x < gBuf->getWidth()) ? (255 * color.u()) : 0;
+    for (unsigned int row = 0; row < height; row += attrib->uSubSampY) {
+        for (unsigned int col = 0; col < width; col += attrib->uSubSampX) {
+            *buf++ = 255 * color.u();
+        }
+        for (unsigned int pad = 0; pad < gBuf->getStride() - gBuf->getWidth();
+             pad += attrib->uSubSampX) {
+            *buf++ = testRandMod(256);
         }
     }
 
     // Fill in V component
-    for (unsigned int x = 0; x < width; x += attrib->vSubSampX) {
-        for (unsigned int y = 0; y < height; y += attrib->vSubSampY) {
-            *buf++ = (x < gBuf->getWidth()) ? (255 * color.v()) : 0;
+    for (unsigned int row = 0; row < height; row += attrib->vSubSampY) {
+        for (unsigned int col = 0; col < width; col += attrib->vSubSampX) {
+            *buf++ = 255 * color.v();
+        }
+        for (unsigned int pad = 0; pad < gBuf->getStride() - gBuf->getWidth();
+             pad += attrib->vSubSampX) {
+            *buf++ = testRandMod(256);
         }
     }
 
@@ -960,7 +1001,7 @@
     eglQuerySurface(dpy, surface, EGL_HEIGHT, &height);
     checkEglError("eglQuerySurface");
 
-    fprintf(stderr, "Window dimensions: %d x %d", width, height);
+    testPrintI("Window dimensions: %d x %d", width, height);
 
     printGLString("Version", GL_VERSION);
     printGLString("Vendor", GL_VENDOR);
@@ -988,13 +1029,14 @@
  *
  * Creates an array of graphic buffers, within the global variable
  * named frames.  The graphic buffers are contained within a vector of
- * verctors.  All the graphic buffers in a particular row are of the same
+ * vectors.  All the graphic buffers in a particular row are of the same
  * format and dimension.  Each graphic buffer is uniformly filled with a
  * prandomly selected color.  It is likely that each buffer, even
  * in the same row, will be filled with a unique color.
  */
 void initFrames(unsigned int seed)
 {
+    int rv;
     const size_t maxRows = 5;
     const size_t minCols = 2;  // Need at least double buffering
     const size_t maxCols = 4;  // One more than triple buffering
@@ -1009,7 +1051,12 @@
     for (unsigned int row = 0; row < rows; row++) {
         // All frames within a row have to have the same format and
         // dimensions.  Width and height need to be >= 1.
-        int format = graphicFormat[testRandMod(NUMA(graphicFormat))].format;
+        unsigned int formatIdx = testRandMod(NUMA(graphicFormat));
+        const struct graphicFormat *formatPtr = &graphicFormat[formatIdx];
+        int format = formatPtr->format;
+
+        // Pick width and height, which must be >= 1 and the size
+        // mod the wMod/hMod value must be equal to 0.
         size_t w = (width * maxSizeRatio) * testRandFract();
         size_t h = (height * maxSizeRatio) * testRandFract();
         w = max(1u, w);
@@ -1018,6 +1065,12 @@
             testPrintI("  frame %u width: %u height: %u format: %u %s",
                        row, w, h, format, graphicFormat2str(format));
         }
+        if ((w % formatPtr->wMod) != 0) {
+            w += formatPtr->wMod - (w % formatPtr->wMod);
+        }
+        if ((h % formatPtr->hMod) != 0) {
+            h += formatPtr->hMod - (h % formatPtr->hMod);
+        }
 
         size_t cols = testRandMod((maxCols + 1) - minCols) + minCols;
         frames[row].resize(cols);
@@ -1026,6 +1079,13 @@
             float transp = testRandFract();
 
             frames[row][col] = new GraphicBuffer(w, h, format, texUsage);
+            if ((rv = frames[row][col]->initCheck()) != NO_ERROR) {
+                testPrintE("GraphicBuffer initCheck failed, rv: %i", rv);
+                testPrintE("  frame %u width: %u height: %u format: %u %s",
+                           row, w, h, format, graphicFormat2str(format));
+                exit(80);
+            }
+
             fillColor(frames[row][col].get(), color, transp);
             if (verbose) {
                 testPrintI("    buf: %p handle: %p color: <%f, %f, %f> "
@@ -1097,6 +1157,15 @@
                    list->hwLayers[layer].displayFrame.top,
                    list->hwLayers[layer].displayFrame.right,
                    list->hwLayers[layer].displayFrame.bottom);
+        testPrintI("      scaleFactor: [%f %f]",
+                   (float) (list->hwLayers[layer].displayFrame.right
+                            - list->hwLayers[layer].displayFrame.left)
+                       / (float) (list->hwLayers[layer].sourceCrop.right
+                            - list->hwLayers[layer].sourceCrop.left),
+                   (float) (list->hwLayers[layer].displayFrame.bottom
+                            - list->hwLayers[layer].displayFrame.top)
+                       / (float) (list->hwLayers[layer].sourceCrop.bottom
+                            - list->hwLayers[layer].sourceCrop.top));
     }
 }
 
diff --git a/packages/SettingsProvider/res/xml/bookmarks.xml b/packages/SettingsProvider/res/xml/bookmarks.xml
index dfaeeaf..83229f4 100644
--- a/packages/SettingsProvider/res/xml/bookmarks.xml
+++ b/packages/SettingsProvider/res/xml/bookmarks.xml
@@ -4,9 +4,9 @@
      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.
@@ -14,6 +14,22 @@
      limitations under the License.
 -->
 
+<!--
+     Default system bookmarks for AOSP.
+     Bookmarks for vendor apps should be added to a bookmarks resource overlay; not here.
+
+     Typical shortcuts (not necessarily defined here):
+       'b': Browser
+       'c': Contacts
+       'e': Email
+       'g': GMail
+       'l': Calendar
+       'm': Maps
+       'p': Music
+       's': SMS
+       't': Talk
+       'y': YouTube
+-->
 <bookmarks>
     <bookmark
         package="com.android.browser"
@@ -21,30 +37,16 @@
         shortcut="b" />
     <bookmark
         package="com.android.contacts"
-        class="com.android.contacts.DialtactsContactsEntryActivity"
+        class="com.android.contacts.activities.ContactsFrontDoor"
         shortcut="c" />
     <bookmark
-        package="com.android.email"
+        package="com.google.android.email"
         class="com.android.email.activity.Welcome"
         shortcut="e" />
     <bookmark
-        package="com.google.android.gm"
-        class="com.google.android.gm.ConversationListActivityGmail"
-        shortcut="g" />
-    <bookmark
-        package="com.android.im"
-        class="com.android.im.app.LandingPage"
-        shortcut="i" />
-    <bookmark
-        package="com.android.calendar"
+        package="com.google.android.calendar"
         class="com.android.calendar.LaunchActivity"
         shortcut="l" />
-<!--
-    <bookmark
-        package="com.google.android.apps.maps"
-        class="com.google.android.maps.MapsActivity"
-        shortcut="m" />
--->
     <bookmark
         package="com.android.music"
         class="com.android.music.MusicBrowserActivity"
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_glow_back.png b/packages/SystemUI/res/drawable-nodpi/notify_glow_back.png
new file mode 100755
index 0000000..7d17a54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_glow_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_item_glow_bottom.png b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_bottom.png
new file mode 100644
index 0000000..d960c78
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_bottom.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_item_glow_left.png b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_left.png
new file mode 100755
index 0000000..3e46370
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_left.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_item_glow_top.png b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_top.png
new file mode 100755
index 0000000..afc91b9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_top.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg.png
new file mode 100755
index 0000000..7086def
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
new file mode 100755
index 0000000..e9589d9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
index 1d98458..2272e34 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
@@ -17,161 +17,178 @@
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
 <com.android.systemui.statusbar.tablet.NotificationPanel
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
-    android:animateLayoutChanges="true"
-    android:paddingTop="32dp"
-    android:paddingBottom="@dimen/status_bar_panel_bottom_offset"
     android:orientation="vertical"
     android:gravity="right"
+    android:paddingTop="32dp"
     >
 
-    <com.android.systemui.statusbar.tablet.NotificationTitleArea
-        android:id="@+id/title_area"
-        android:layout_height="160dp"
-        android:layout_width="384dp"
-        android:layout_marginLeft="24dp"
-        android:paddingTop="20dp"
-        android:orientation="vertical"
-        android:animateLayoutChanges="true"
-        >
-
-        <com.android.systemui.statusbar.tablet.HoloClock
-            android:id="@+id/clock"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:layout_alignParentTop="true"
-            android:layout_marginRight="40dip"
-            android:layout_marginBottom="4dip"
-            >
-            <TextView android:id="@+id/time_bg"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="right"
-                android:singleLine="true"
-                android:textSize="90dip"
-                android:textColor="#999999" />
-            <TextView android:id="@+id/time_fg"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="right"
-                android:singleLine="true"
-                android:textSize="90dip"
-                android:textColor="#666666" />
-        </com.android.systemui.statusbar.tablet.HoloClock>
-
-        <com.android.systemui.statusbar.policy.DateView
-            android:id="@+id/date"
-            style="@style/StatusBarNotificationText"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:layout_below="@id/clock"
-            android:layout_marginTop="4dp"
-            android:layout_marginRight="48dp"
-            android:gravity="right"
-            />
-
-        <ImageView
-            android:id="@+id/battery"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_below="@id/date"
-            android:layout_marginLeft="48dp"
-            android:layout_marginTop="18dp"
-            android:layout_marginRight="8dp"
-            android:baseline="15dp"
-            />
-
-        <TextView
-            android:id="@+id/battery_text"
-            style="@style/StatusBarNotificationText"
-            android:layout_width="56dp"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/battery"
-            android:layout_alignBaseline="@id/battery"
-            android:singleLine="true"
-            android:text="@string/status_bar_settings_settings_button"
-            />
-
-        <ImageView
-            android:id="@+id/network_signal"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_toRightOf="@id/battery_text"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_marginRight="8dp"
-            android:baseline="15dp"
-            />
-
-        <ImageView
-            android:id="@+id/network_type"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_toRightOf="@id/battery_text"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_marginRight="8dp"
-            android:baseline="15dp"
-            />
-
-        <TextView
-            android:id="@+id/network_text"
-            style="@style/StatusBarNotificationText"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/network_signal"
-            android:layout_alignBaseline="@id/battery"
-            android:singleLine="true"
-            android:text="@string/status_bar_settings_settings_button"
-            />
-
-        <ImageView
-            android:id="@+id/settings_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_alignParentRight="true"
-            android:paddingRight="16dp"
-            android:src="@drawable/ic_notification_open"
-            android:baseline="21dp"
-            />
-
-        <ImageView
-            android:id="@+id/notification_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true"
-            android:layout_alignBaseline="@id/battery"
-            android:paddingRight="16dp"
-            android:visibility="invisible"
-            android:src="@drawable/status_bar_veto"
-            android:baseline="21dp"
-            />
-    </com.android.systemui.statusbar.tablet.NotificationTitleArea>
-
-    <FrameLayout
-        android:id="@+id/content_frame"
+    <LinearLayout
+        android:id="@+id/content_parent"
         android:layout_height="wrap_content"
-        android:layout_width="408dp"
+        android:layout_width="wrap_content"
+        android:animateLayoutChanges="true"
+        android:orientation="vertical"
         >
-        <ScrollView
-            android:id="@+id/notificationScroller"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
+
+        <com.android.systemui.statusbar.tablet.NotificationTitleArea
+            android:id="@+id/title_area"
+            android:layout_height="160dp"
+            android:layout_width="384dp"
+            android:layout_marginLeft="24dp"
+            android:paddingTop="20dp"
+            android:orientation="vertical"
+            android:animateLayoutChanges="true"
             >
-            <LinearLayout 
-                android:id="@+id/content"
-                android:layout_width="match_parent"
+
+            <com.android.systemui.statusbar.tablet.HoloClock
+                android:id="@+id/clock"
                 android:layout_height="wrap_content"
-                android:gravity="center_horizontal|bottom"
-                android:animateLayoutChanges="true"
-                android:animationCache="false"
-                android:orientation="vertical"
-                android:clickable="true"
-                android:focusable="true"
-                android:descendantFocusability="afterDescendants"
+                android:layout_width="match_parent"
+                android:layout_alignParentTop="true"
+                android:layout_marginRight="40dip"
+                android:layout_marginBottom="4dip"
                 >
-            </LinearLayout>
-        </ScrollView>
-    </FrameLayout>
+                <TextView android:id="@+id/time_bg"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="right"
+                    android:singleLine="true"
+                    android:textSize="90dip"
+                    android:textColor="#999999" />
+                <TextView android:id="@+id/time_fg"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="right"
+                    android:singleLine="true"
+                    android:textSize="90dip"
+                    android:textColor="#666666" />
+            </com.android.systemui.statusbar.tablet.HoloClock>
+
+            <com.android.systemui.statusbar.policy.DateView
+                android:id="@+id/date"
+                style="@style/StatusBarNotificationText"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:layout_below="@id/clock"
+                android:layout_marginTop="4dp"
+                android:layout_marginRight="48dp"
+                android:gravity="right"
+                />
+
+            <ImageView
+                android:id="@+id/battery"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_below="@id/date"
+                android:layout_marginLeft="48dp"
+                android:layout_marginTop="18dp"
+                android:layout_marginRight="8dp"
+                android:baseline="15dp"
+                />
+
+            <TextView
+                android:id="@+id/battery_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_width="56dp"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@id/battery"
+                android:layout_alignBaseline="@id/battery"
+                android:singleLine="true"
+                android:text="@string/status_bar_settings_settings_button"
+                />
+
+            <ImageView
+                android:id="@+id/network_signal"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_toRightOf="@id/battery_text"
+                android:layout_alignBaseline="@id/battery"
+                android:layout_marginRight="8dp"
+                android:baseline="15dp"
+                />
+
+            <ImageView
+                android:id="@+id/network_type"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_toRightOf="@id/battery_text"
+                android:layout_alignBaseline="@id/battery"
+                android:layout_marginRight="8dp"
+                android:baseline="15dp"
+                />
+
+            <TextView
+                android:id="@+id/network_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@id/network_signal"
+                android:layout_alignBaseline="@id/battery"
+                android:singleLine="true"
+                android:text="@string/status_bar_settings_settings_button"
+                />
+
+            <ImageView
+                android:id="@+id/settings_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignBaseline="@id/battery"
+                android:layout_alignParentRight="true"
+                android:paddingRight="16dp"
+                android:src="@drawable/ic_notification_open"
+                android:baseline="21dp"
+                />
+
+            <ImageView
+                android:id="@+id/notification_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_alignBaseline="@id/battery"
+                android:paddingRight="16dp"
+                android:visibility="invisible"
+                android:src="@drawable/status_bar_veto"
+                android:baseline="21dp"
+                />
+        </com.android.systemui.statusbar.tablet.NotificationTitleArea>
+
+        <LinearLayout
+            android:id="@+id/content_frame"
+            android:layout_height="wrap_content"
+            android:layout_width="408dp"
+            android:orientation="vertical"
+            >
+            <ScrollView
+                android:id="@+id/notificationScroller"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                >
+                <com.android.systemui.statusbar.tablet.NotificationLinearLayout
+                    android:id="@+id/content"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_horizontal|bottom"
+                    android:animateLayoutChanges="true"
+                    android:animationCache="false"
+                    android:orientation="vertical"
+                    android:clickable="true"
+                    android:focusable="true"
+                    android:descendantFocusability="afterDescendants"
+                    systemui:insetLeft="16dp"
+                    >
+                </com.android.systemui.statusbar.tablet.NotificationLinearLayout>
+            </ScrollView>
+            <ImageView
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/status_bar_panel_bottom_offset"
+                android:layout_marginLeft="16dp"
+                android:src="@drawable/notify_item_glow_bottom"
+                />
+        </LinearLayout>
+    </LinearLayout>
 </com.android.systemui.statusbar.tablet.NotificationPanel>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
index c7e6dbd..97cbfca 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_panel.xml
@@ -28,8 +28,8 @@
     android:orientation="vertical">
 
     <TextView android:id="@+id/recents_no_recents"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:text="@string/recent_tasks_empty"
         android:textSize="22dip"
         android:gravity="center_horizontal|center_vertical"
@@ -42,15 +42,19 @@
         android:layout_weight="1"
     />
 
-    <LinearLayout android:id="@+id/recents_container"
-        android:layout_width="match_parent"
+    <LinearLayout android:id="@+id/recents_glow"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:layout_alignParentBottom="true"
-        android:layout_marginBottom="16dip"
-        android:layout_alignParentLeft="true"
-        android:layout_marginRight="100dip"
-        android:background="@drawable/recents_blue_glow"
-    />
+        android:orientation="horizontal"
+        android:background="@drawable/recents_blue_glow">
+
+        <LinearLayout android:id="@+id/recents_container"
+            android:layout_width="356dip"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:layout_marginRight="100dip"
+        />
+
+    </LinearLayout>
 
 </com.android.systemui.statusbar.tablet.RecentAppsPanel>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 87395c1..fb2f7d63 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -21,5 +21,8 @@
     <declare-styleable name="ToggleSlider">
         <attr name="text" format="string" />
     </declare-styleable>
+    <declare-styleable name="NotificationLinearLayout">
+        <attr name="insetLeft" format="dimension" />
+    </declare-styleable>
 </resources>
 
diff --git a/packages/SystemUI/res/xml/bookmarks.xml b/packages/SystemUI/res/xml/bookmarks.xml
deleted file mode 100644
index dfaeeaf..0000000
--- a/packages/SystemUI/res/xml/bookmarks.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<bookmarks>
-    <bookmark
-        package="com.android.browser"
-        class="com.android.browser.BrowserActivity"
-        shortcut="b" />
-    <bookmark
-        package="com.android.contacts"
-        class="com.android.contacts.DialtactsContactsEntryActivity"
-        shortcut="c" />
-    <bookmark
-        package="com.android.email"
-        class="com.android.email.activity.Welcome"
-        shortcut="e" />
-    <bookmark
-        package="com.google.android.gm"
-        class="com.google.android.gm.ConversationListActivityGmail"
-        shortcut="g" />
-    <bookmark
-        package="com.android.im"
-        class="com.android.im.app.LandingPage"
-        shortcut="i" />
-    <bookmark
-        package="com.android.calendar"
-        class="com.android.calendar.LaunchActivity"
-        shortcut="l" />
-<!--
-    <bookmark
-        package="com.google.android.apps.maps"
-        class="com.google.android.maps.MapsActivity"
-        shortcut="m" />
--->
-    <bookmark
-        package="com.android.music"
-        class="com.android.music.MusicBrowserActivity"
-        shortcut="p" />
-    <bookmark
-        package="com.android.mms"
-        class="com.android.mms.ui.ConversationList"
-        shortcut="s" />
-</bookmarks>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
index a98ef0b..8c6eefb3 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
@@ -409,7 +409,8 @@
     }
 
     void updateRunningTasks() {
-        mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver);
+        mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS,
+                ActivityManager.TASKS_GET_THUMBNAILS, mThumbnailReceiver);
         if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode);
         for (RunningTaskInfo r : mRunningTaskList) {
             if (r.thumbnail != null) {
@@ -440,7 +441,8 @@
         final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
 
         final List<ActivityManager.RecentTaskInfo> recentTasks =
-                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+                        | ActivityManager.TASKS_GET_THUMBNAILS);
 
         ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
                     .resolveActivityInfo(pm, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
index 66ed727..aa431bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -157,6 +157,17 @@
         return null;
     }
 
+    // Display IME switcher icon only when all of the followings are true:
+    // * There is only one enabled IME on the device.  (Note that the IME should be the system IME)
+    // * There are no explicitly enabled (by the user) subtypes of the IME, or the IME doesn't have
+    // its subtypes at all
+    private boolean needsToShowIMEButton() {
+        List<InputMethodInfo> imis = mImm.getInputMethodList();
+        final int size = imis.size();
+        return size > 1
+                || (size == 1 && mImm.getEnabledInputMethodSubtypeList(imis.get(0)).size() > 1);
+    }
+
     private void refreshStatusIcon(boolean keyboardShown) {
         if (!keyboardShown) {
             setVisibility(View.INVISIBLE);
@@ -187,7 +198,7 @@
 
     public void setIMEButtonVisible(IBinder token, boolean visible) {
         mToken = token;
-        mKeyboardShown = visible;
+        mKeyboardShown = visible ? needsToShowIMEButton() : false;
         refreshStatusIcon(mKeyboardShown);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
new file mode 100644
index 0000000..9ecb2e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.tablet;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+public class NotificationLinearLayout extends LinearLayout {
+    private static final String TAG = "NotificationLinearLayout";
+
+    Drawable mItemGlow;
+    int mInsetLeft;
+    Rect mTmp = new Rect();
+
+    public NotificationLinearLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public NotificationLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final Resources res = context.getResources();
+
+        mItemGlow = res.getDrawable(R.drawable.notify_item_glow_bottom);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationLinearLayout,
+                defStyle, 0);
+        mInsetLeft = a.getDimensionPixelSize(R.styleable.NotificationLinearLayout_insetLeft, 0);
+        a.recycle();
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+        setWillNotDraw(false);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        final Rect padding = mTmp;
+        final Drawable glow = mItemGlow;
+        glow.getPadding(padding);
+        final int glowHeight = glow.getIntrinsicHeight();
+        final int insetLeft = mInsetLeft;
+
+        final int N = getChildCount();
+        for (int i=0; i<N; i++) {
+            final View child = getChildAt(i);
+
+            final int childBottom = child.getBottom();
+
+            glow.setBounds(child.getLeft() - padding.left + insetLeft, childBottom,
+                    child.getRight() - padding.right, childBottom + glowHeight);
+            glow.draw(canvas);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index baf4a0f..82c1d17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -16,11 +16,20 @@
 
 package com.android.systemui.statusbar.tablet;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -32,12 +41,20 @@
         View.OnClickListener {
     static final String TAG = "NotificationPanel";
 
+    boolean mShowing;
     View mTitleArea;
     View mSettingsButton;
     View mNotificationButton;
     View mNotificationScroller;
-    FrameLayout mContentFrame;
+    ViewGroup mContentFrame;
+    Rect mContentArea;
     View mSettingsView;
+    ViewGroup mContentParent;
+
+    Choreographer mChoreo = new Choreographer();
+    int mStatusBarHeight;
+    Drawable mBgDrawable;
+    Drawable mGlowDrawable;
 
     public NotificationPanel(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -45,12 +62,22 @@
 
     public NotificationPanel(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+
+        final Resources res = context.getResources();
+
+        mStatusBarHeight = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mBgDrawable = res.getDrawable(R.drawable.notify_panel_bg_protect);
+        mGlowDrawable = res.getDrawable(R.drawable.notify_glow_back);
     }
 
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
 
+        setWillNotDraw(false);
+
+        mContentParent = (ViewGroup)findViewById(R.id.content_parent);
         mTitleArea = findViewById(R.id.title_area);
 
         mSettingsButton = (ImageView)findViewById(R.id.settings_button);
@@ -59,7 +86,31 @@
         mNotificationButton.setOnClickListener(this);
 
         mNotificationScroller = findViewById(R.id.notificationScroller);
-        mContentFrame = (FrameLayout)findViewById(R.id.content_frame);
+        mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
+    }
+
+    public void show(boolean show, boolean animate) {
+        if (animate) {
+            if (mShowing != show) {
+                mShowing = show;
+                if (show) {
+                    setVisibility(View.VISIBLE);
+                }
+                mChoreo.startAnimation(show);
+            }
+        } else {
+            mShowing = show;
+            setVisibility(show ? View.VISIBLE : View.GONE);
+            mChoreo.jumpTo(show);
+        }
+    }
+
+    /**
+     * Whether the panel is showing, or, if it's animating, whether it will be
+     * when the animation is done.
+     */
+    public boolean isShowing() {
+        return mShowing;
     }
 
     @Override
@@ -93,6 +144,34 @@
             final View c = getChildAt(i);
             c.layout(c.getLeft(), c.getTop() + shift, c.getRight(), c.getBottom() + shift);
         }
+
+        mChoreo.setPanelHeight(mContentParent.getHeight());
+    }
+
+    @Override
+    public void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mContentArea = null;
+        mBgDrawable.setBounds(0, 0, w, h-mStatusBarHeight);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        int saveCount;
+        final int w = getWidth();
+        final int h = getHeight();
+
+        super.onDraw(canvas);
+
+        // Background protection
+        mBgDrawable.draw(canvas);
+
+        // The panel glow (behind status bar)
+
+        saveCount = canvas.save();
+        canvas.clipRect(0, 0, w, h-mStatusBarHeight);
+        mGlowDrawable.draw(canvas);
+        canvas.restoreToCount(saveCount);
     }
 
     public void onClick(View v) {
@@ -119,11 +198,14 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        final int l = mContentFrame.getLeft();
-        final int r = mContentFrame.getRight();
-        final int t = mTitleArea.getTop();
-        final int b = mContentFrame.getBottom();
-        return x >= l && x < r && y >= t && y < b;
+        if (mContentArea == null) {
+            mContentArea = new Rect(mContentFrame.getLeft(),
+                    mTitleArea.getTop(),
+                    mContentFrame.getRight(),
+                    mContentFrame.getBottom());
+            offsetDescendantRectToMyCoords(mContentParent, mContentArea);
+        }
+        return mContentArea.contains(x, y);
     }
 
     void removeSettingsView() {
@@ -138,5 +220,102 @@
         mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
         mContentFrame.addView(mSettingsView);
     }
+
+    private class Choreographer implements Animator.AnimatorListener {
+        int mBgAlpha;
+        ValueAnimator mBgAnim;
+        int mPanelHeight;
+        int mPanelBottom;
+        ValueAnimator mPositionAnim;
+
+        // should group this into a multi-property animation
+        final int OPEN_DURATION = 200;
+
+        Choreographer() {
+        }
+
+        void createAnimation(boolean visible) {
+            mBgAnim = ObjectAnimator.ofInt(this, "bgAlpha", mBgAlpha, visible ? 255 : 0)
+                    .setDuration(OPEN_DURATION);
+            mBgAnim.addListener(this);
+
+            mPositionAnim = ObjectAnimator.ofInt(this, "panelBottom", mPanelBottom,
+                        visible ? mPanelHeight : 0)
+                    .setDuration(OPEN_DURATION);
+        }
+
+        void startAnimation(boolean visible) {
+            if (mBgAnim == null) {
+                createAnimation(visible);
+                mBgAnim.start();
+                mPositionAnim.start();
+            } else {
+                mBgAnim.reverse();
+                mPositionAnim.reverse();
+            }
+        }
+
+        void jumpTo(boolean visible) {
+            setBgAlpha(visible ? 255 : 0);
+            setPanelBottom(visible ? mPanelHeight : 0);
+        }
+
+        public void setBgAlpha(int alpha) {
+            mBgAlpha = alpha;
+            mBgDrawable.setAlpha((int)(alpha));
+            invalidate();
+        }
+
+        // 0 is closed, the height of the panel is open
+        public void setPanelBottom(int y) {
+            mPanelBottom = y;
+            int translationY = mPanelHeight - y;
+            mContentParent.setTranslationY(translationY);
+
+            final int glowXOffset = 100;
+            final int glowYOffset = 100;
+            int glowX = mContentParent.getLeft() - glowXOffset;
+            int glowY = mContentParent.getTop() - glowYOffset + translationY;
+            mGlowDrawable.setBounds(glowX, glowY, glowX + mGlowDrawable.getIntrinsicWidth(),
+                    glowY + mGlowDrawable.getIntrinsicHeight());
+
+            float alpha;
+            if (mPanelBottom > glowYOffset) {
+                alpha = 1;
+            } else {
+                alpha = ((float)mPanelBottom) / glowYOffset;
+            }
+            mContentParent.setAlpha(alpha);
+            mGlowDrawable.setAlpha((int)(255 * alpha));
+
+            if (false) {
+                Slog.d(TAG, "mPanelBottom=" + mPanelBottom + "translationY=" + translationY
+                        + " alpha=" + alpha + " glowY=" + glowY);
+            }
+        }
+
+        public void setPanelHeight(int h) {
+            mPanelHeight = h;
+            setPanelBottom(mPanelBottom);
+        }
+
+        public void onAnimationCancel(Animator animation) {
+            //Slog.d(TAG, "onAnimationCancel mBgAlpha=" + mBgAlpha);
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            //Slog.d(TAG, "onAnimationEnd mBgAlpha=" + mBgAlpha);
+            if (mBgAlpha == 0) {
+                setVisibility(View.GONE);
+            }
+            mBgAnim = null;
+        }
+
+        public void onAnimationRepeat(Animator animation) {
+        }
+
+        public void onAnimationStart(Animator animation) {
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 25a2f2b..1301329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -20,13 +20,9 @@
 import java.util.List;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IThumbnailReceiver;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.content.Context;
@@ -50,12 +46,10 @@
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
-import android.view.animation.AnimationSet;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-import android.widget.ImageView.ScaleType;
 
 import com.android.systemui.R;
 
@@ -64,10 +58,11 @@
     private static final boolean DEBUG = TabletStatusBar.DEBUG;
     private static final int DISPLAY_TASKS_PORTRAIT = 8;
     private static final int DISPLAY_TASKS_LANDSCAPE = 5; // number of recent tasks to display
-    private static final int MAX_TASKS = 2 * DISPLAY_TASKS_PORTRAIT; // allow extra for non-apps
+    private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 2; // allow extra for non-apps
     private TabletStatusBar mBar;
     private TextView mNoRecents;
     private LinearLayout mRecentsContainer;
+    private View mRecentsGlowView;
     private ArrayList<ActivityDescription> mActivityDescriptions;
     private int mIconDpi;
     private AnimatorSet mAnimationSet;
@@ -85,8 +80,8 @@
         int position; // position in list
 
         public ActivityDescription(Bitmap _thumbnail,
-                Drawable _icon, String _label, String _desc, Intent _intent, int _id, int _pos,
-                String _packageName)
+                Drawable _icon, String _label, CharSequence _desc, Intent _intent,
+                int _id, int _pos, String _packageName)
         {
             thumbnail = _thumbnail;
             icon = _icon;
@@ -99,21 +94,6 @@
         }
     };
 
-    private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() {
-
-        public void finished() throws RemoteException {
-        }
-
-        public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description)
-                throws RemoteException {
-            ActivityDescription info = findActivityDescription(id);
-            if (info != null) {
-                info.thumbnail = bitmap;
-                info.description = description;
-            }
-        }
-    };
-
     public boolean isInContentArea(int x, int y) {
         final int l = mRecentsContainer.getPaddingLeft();
         final int r = mRecentsContainer.getWidth() - mRecentsContainer.getPaddingRight();
@@ -145,6 +125,7 @@
         super.onFinishInflate();
         mNoRecents = (TextView) findViewById(R.id.recents_no_recents);
         mRecentsContainer = (LinearLayout) findViewById(R.id.recents_container);
+        mRecentsGlowView = findViewById(R.id.recents_glow);
         mBackgroundProtector = (View) findViewById(R.id.recents_bg_protect);
 
         // In order to save space, we make the background texture repeat in the Y direction
@@ -205,7 +186,8 @@
                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
 
         final List<ActivityManager.RecentTaskInfo> recentTasks =
-                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+                        | ActivityManager.TASKS_GET_THUMBNAILS);
 
         ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
                     .resolveActivityInfo(pm, 0);
@@ -238,7 +220,8 @@
                 if (title != null && title.length() > 0 && icon != null) {
                     if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
                     ActivityDescription item = new ActivityDescription(
-                            null, icon, title, null, intent, id, index, info.packageName);
+                            crop(recentInfo.thumbnail), icon, title, recentInfo.description,
+                            intent, id, index, info.packageName);
                     activityDescriptions.add(item);
                     ++index;
                 } else {
@@ -262,28 +245,8 @@
         return desc;
     }
 
-    private void getThumbnails(ArrayList<ActivityDescription> tasks) {
-        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        List<RunningTaskInfo> runningTasks = am.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver);
-        for (RunningTaskInfo runningTaskInfo : runningTasks) {
-            // Find the activity description associted with the given id
-            ActivityDescription desc = findActivityDescription(runningTaskInfo.id);
-            if (desc != null) {
-                if (runningTaskInfo.thumbnail != null) {
-                    desc.thumbnail = crop(runningTaskInfo.thumbnail);
-                    desc.description = runningTaskInfo.description;
-                } else {
-                    if (DEBUG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
-                }
-            } else {
-                if (DEBUG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + runningTaskInfo.id);
-            }
-        }
-    }
-
     private void refreshApplicationList() {
         mActivityDescriptions = getRecentTasks();
-        getThumbnails(mActivityDescriptions);
         updateUiElements(getResources().getConfiguration(), true);
     }
 
@@ -308,11 +271,6 @@
     private void updateUiElements(Configuration config, boolean animate) {
         mRecentsContainer.removeAllViews();
 
-
-        // TODO: disabled until I have a chance to tune animations with UX
-        animate = false;
-
-
         final float initialAlpha = 0.0f;
         final int first = 0;
         final boolean isPortrait = config.orientation == Configuration.ORIENTATION_PORTRAIT;
@@ -339,8 +297,8 @@
             if (animate) {
                 view.setAlpha(initialAlpha);
                 ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", initialAlpha, 1.0f);
-                anim.setDuration(25);
-                anim.setStartDelay((last-i)*25);
+                anim.setDuration(200);
+                anim.setStartDelay((last-i)*80);
                 anim.setInterpolator(interp);
                 anims.add(anim);
             }
@@ -349,11 +307,12 @@
         int views = mRecentsContainer.getChildCount();
         mNoRecents.setVisibility(View.GONE); // views == 0 ? View.VISIBLE : View.GONE);
         mRecentsContainer.setVisibility(views > 0 ? View.VISIBLE : View.GONE);
+        mRecentsGlowView.setVisibility(views > 0 ? View.VISIBLE : View.GONE);
 
-        if (animate) {
-            ObjectAnimator anim = ObjectAnimator.ofFloat(mRecentsContainer, "alpha",
+        if (animate && views > 0) {
+            ObjectAnimator anim = ObjectAnimator.ofFloat(mRecentsGlowView, "alpha",
                     initialAlpha, 1.0f);
-            anim.setDuration(last*25);
+            anim.setDuration((last-first)*80);
             anim.setInterpolator(interp);
             anims.add(anim);
         }
@@ -361,7 +320,7 @@
         if (animate) {
             ObjectAnimator anim = ObjectAnimator.ofFloat(mBackgroundProtector, "alpha",
                     initialAlpha, 1.0f);
-            anim.setDuration(last*25);
+            anim.setDuration(last*80);
             anim.setInterpolator(interp);
             anims.add(anim);
         }
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 90cf3dc..7a7976a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -161,7 +161,7 @@
         // Notification Panel
         mNotificationPanel = (NotificationPanel)View.inflate(context,
                 R.layout.status_bar_notification_panel, null);
-        mNotificationPanel.setVisibility(View.GONE);
+        mNotificationPanel.show(false, false);
         mNotificationPanel.setOnTouchListener(
                 new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
 
@@ -186,10 +186,14 @@
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                     | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
         lp.setTitle("NotificationPanel");
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+        lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
 
         WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
 
@@ -244,7 +248,8 @@
                     WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                     WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                         | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                     PixelFormat.TRANSLUCENT);
             lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
             lp.setTitle("RecentsPanel");
@@ -390,7 +395,7 @@
                             mNotificationPeekRow.addView(copy.row);
 
                             mNotificationPeekWindow.setVisibility(View.VISIBLE);
-                            mNotificationPanel.setVisibility(View.GONE);
+                            mNotificationPanel.show(false, true);
 
                             mNotificationPeekIndex = peekIndex;
                             mNotificationPeekKey = entry.key;
@@ -412,9 +417,9 @@
                     break;
                 case MSG_OPEN_NOTIFICATION_PANEL:
                     if (DEBUG) Slog.d(TAG, "opening notifications panel");
-                    if (mNotificationPanel.getVisibility() == View.GONE) {
+                    if (!mNotificationPanel.isShowing()) {
                         mNotificationPeekWindow.setVisibility(View.GONE);
-                        mNotificationPanel.setVisibility(View.VISIBLE);
+                        mNotificationPanel.show(true, true);
                         // synchronize with current shadow state
                         mShadowController.hideElement(mNotificationArea);
                         mTicker.halt();
@@ -422,8 +427,8 @@
                     break;
                 case MSG_CLOSE_NOTIFICATION_PANEL:
                     if (DEBUG) Slog.d(TAG, "closing notifications panel");
-                    if (mNotificationPanel.getVisibility() == View.VISIBLE) {
-                        mNotificationPanel.setVisibility(View.GONE);
+                    if (mNotificationPanel.isShowing()) {
+                        mNotificationPanel.show(false, true);
                         // synchronize with current shadow state
                         mShadowController.showElement(mNotificationArea);
                     }
@@ -458,8 +463,7 @@
         if (mNotificationTrigger == null) return;
 
         int resId;
-        boolean panel = (mNotificationPanel != null 
-                && mNotificationPanel.getVisibility() == View.VISIBLE);
+        boolean panel = (mNotificationPanel != null && mNotificationPanel.isShowing();
         if (!mNotificationsOn) {
             resId = R.drawable.ic_sysbar_noti_dnd;
         } else if (mNotns.size() > 0) {
@@ -657,7 +661,7 @@
 
     private void tick(IBinder key, StatusBarNotification n) {
         // Don't show the ticker when the windowshade is open.
-        if (mNotificationPanel.getVisibility() == View.VISIBLE) {
+        if (mNotificationPanel.isShowing()) {
             return;
         }
         // Show the ticker if one is requested. Also don't do this
@@ -785,7 +789,7 @@
                 mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
                 refreshNotificationTrigger();
             } else {
-                int msg = (mNotificationPanel.getVisibility() == View.GONE)
+                int msg = !mNotificationPanel.isShowing()
                     ? MSG_OPEN_NOTIFICATION_PANEL
                     : MSG_CLOSE_NOTIFICATION_PANEL;
                 mHandler.removeMessages(msg);
@@ -894,7 +898,7 @@
 
         public boolean onTouch(View v, MotionEvent event) {
             boolean peeking = mNotificationPeekWindow.getVisibility() != View.GONE;
-            boolean panelShowing = mNotificationPanel.getVisibility() != View.GONE;
+            boolean panelShowing = mNotificationPanel.isShowing();
             if (panelShowing) return false;
 
             switch (event.getAction()) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 79bf9d0..c6984a4 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1330,38 +1330,40 @@
                 }
             } else if (keyCode == mShortcutKeyPressed) {
                 mShortcutKeyPressed = -1;
-                
                 if (mConsumeShortcutKeyUp) {
-                    // Consume the up-event
                     mConsumeShortcutKeyUp = false;
                     return true;
                 }
             }
+            return false;
         } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
             if (!down) {
                 showRecentAppsDialog();
             }
             return true;
         }
-        
+
         // Shortcuts are invoked through Search+key, so intercept those here
-        if (mShortcutKeyPressed != -1 && !mConsumeShortcutKeyUp) {
-            if (down && repeatCount == 0 && !keyguardOn) {
-                final KeyCharacterMap kcm = event.getKeyCharacterMap();
-                Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
-                if (shortcutIntent != null) {
-                    shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    mContext.startActivity(shortcutIntent);
-                    
-                    /*
-                     * We launched an app, so the up-event of the search key
-                     * should be consumed
-                     */
-                    if (mShortcutKeyPressed != -1) {
-                        mConsumeShortcutKeyUp = true;
+        // Any printing key that is chorded with Search should be consumed
+        // even if no shortcut was invoked.  This prevents text from being
+        // inadvertently inserted when using a keyboard that has built-in macro
+        // shortcut keys (that emit Search+x) and some of them are not registered.
+        if (mShortcutKeyPressed != -1) {
+            final KeyCharacterMap kcm = event.getKeyCharacterMap();
+            if (kcm.isPrintingKey(keyCode)) {
+                mConsumeShortcutKeyUp = true;
+                if (down && repeatCount == 0 && !keyguardOn) {
+                    Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
+                    if (shortcutIntent != null) {
+                        shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        mContext.startActivity(shortcutIntent);
+                    } else {
+                        Slog.i(TAG, "Dropping unregistered shortcut key combination: "
+                                + KeyEvent.keyCodeToString(mShortcutKeyPressed)
+                                + "+" + KeyEvent.keyCodeToString(keyCode));
                     }
-                    return true;
                 }
+                return true;
             }
         }
 
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
index f53092d..db66346 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
@@ -33,7 +33,6 @@
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.RemoteException;
 import android.util.Log;
 import android.view.View;
 import android.view.Window;
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 1617a4e..601fa21 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -107,6 +107,7 @@
     private static final int MSG_RUN_INITIALIZE = 5;
     private static final int MSG_RUN_GET_RESTORE_SETS = 6;
     private static final int MSG_TIMEOUT = 7;
+    private static final int MSG_RESTORE_TIMEOUT = 8;
 
     // Timeout interval for deciding that a bind or clear-data has taken too long
     static final long TIMEOUT_INTERVAL = 10 * 1000;
@@ -396,6 +397,21 @@
                 }
                 break;
             }
+
+            case MSG_RESTORE_TIMEOUT:
+            {
+                synchronized (BackupManagerService.this) {
+                    if (mActiveRestoreSession != null) {
+                        // Client app left the restore session dangling.  We know that it
+                        // can't be in the middle of an actual restore operation because
+                        // those are executed serially on this same handler thread.  Clean
+                        // up now.
+                        Slog.w(TAG, "Restore session timed out; aborting");
+                        post(mActiveRestoreSession.new EndRestoreRunnable(
+                                BackupManagerService.this, mActiveRestoreSession));
+                    }
+                }
+            }
             }
         }
     }
@@ -1826,6 +1842,11 @@
                     } catch (RemoteException e) { /* can't happen */ }
                 }
 
+                // Furthermore we need to reset the session timeout clock
+                mBackupHandler.removeMessages(MSG_RESTORE_TIMEOUT);
+                mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_TIMEOUT,
+                        TIMEOUT_RESTORE_INTERVAL);
+
                 // done; we can finally release the wakelock
                 mWakelock.release();
             }
@@ -2506,10 +2527,23 @@
                 return null;
             }
             mActiveRestoreSession = new ActiveRestoreSession(packageName, transport);
+            mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
         }
         return mActiveRestoreSession;
     }
 
+    void clearRestoreSession(ActiveRestoreSession currentSession) {
+        synchronized(this) {
+            if (currentSession != mActiveRestoreSession) {
+                Slog.e(TAG, "ending non-current restore session");
+            } else {
+                if (DEBUG) Slog.v(TAG, "Clearing restore session and halting timeout");
+                mActiveRestoreSession = null;
+                mBackupHandler.removeMessages(MSG_RESTORE_TIMEOUT);
+            }
+        }
+    }
+
     // Note that a currently-active backup agent has notified us that it has
     // completed the given outstanding asynchronous backup/restore operation.
     public void opComplete(int token) {
@@ -2528,6 +2562,7 @@
         private String mPackageName;
         private IBackupTransport mRestoreTransport = null;
         RestoreSet[] mRestoreSets = null;
+        boolean mEnded = false;
 
         ActiveRestoreSession(String packageName, String transport) {
             mPackageName = packageName;
@@ -2542,6 +2577,10 @@
                 throw new IllegalArgumentException("Observer must not be null");
             }
 
+            if (mEnded) {
+                throw new IllegalStateException("Restore session already ended");
+            }
+
             long oldId = Binder.clearCallingIdentity();
             try {
                 if (mRestoreTransport == null) {
@@ -2569,6 +2608,10 @@
             if (DEBUG) Slog.d(TAG, "restoreAll token=" + Long.toHexString(token)
                     + " observer=" + observer);
 
+            if (mEnded) {
+                throw new IllegalStateException("Restore session already ended");
+            }
+
             if (mRestoreTransport == null || mRestoreSets == null) {
                 Slog.e(TAG, "Ignoring restoreAll() with no restore set");
                 return -1;
@@ -2600,6 +2643,10 @@
         public synchronized int restorePackage(String packageName, IRestoreObserver observer) {
             if (DEBUG) Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer);
 
+            if (mEnded) {
+                throw new IllegalStateException("Restore session already ended");
+            }
+
             if (mPackageName != null) {
                 if (! mPackageName.equals(packageName)) {
                     Slog.e(TAG, "Ignoring attempt to restore pkg=" + packageName
@@ -2656,32 +2703,48 @@
             return 0;
         }
 
+        // Posted to the handler to tear down a restore session in a cleanly synchronized way
+        class EndRestoreRunnable implements Runnable {
+            BackupManagerService mBackupManager;
+            ActiveRestoreSession mSession;
+
+            EndRestoreRunnable(BackupManagerService manager, ActiveRestoreSession session) {
+                mBackupManager = manager;
+                mSession = session;
+            }
+
+            public void run() {
+                // clean up the session's bookkeeping
+                synchronized (mSession) {
+                    try {
+                        if (mSession.mRestoreTransport != null) {
+                            mSession.mRestoreTransport.finishRestore();
+                        }
+                    } catch (Exception e) {
+                        Slog.e(TAG, "Error in finishRestore", e);
+                    } finally {
+                        mSession.mRestoreTransport = null;
+                        mSession.mEnded = true;
+                    }
+                }
+
+                // clean up the BackupManagerService side of the bookkeeping
+                // and cancel any pending timeout message
+                mBackupManager.clearRestoreSession(mSession);
+            }
+        }
+
         public synchronized void endRestoreSession() {
             if (DEBUG) Slog.d(TAG, "endRestoreSession");
 
-            synchronized (this) {
-                long oldId = Binder.clearCallingIdentity();
-                try {
-                    if (mRestoreTransport != null) mRestoreTransport.finishRestore();
-                } catch (Exception e) {
-                    Slog.e(TAG, "Error in finishRestore", e);
-                } finally {
-                    mRestoreTransport = null;
-                    Binder.restoreCallingIdentity(oldId);
-                }
+            if (mEnded) {
+                throw new IllegalStateException("Restore session already ended");
             }
 
-            synchronized (BackupManagerService.this) {
-                if (BackupManagerService.this.mActiveRestoreSession == this) {
-                    BackupManagerService.this.mActiveRestoreSession = null;
-                } else {
-                    Slog.e(TAG, "ending non-current restore session");
-                }
-            }
+            mBackupHandler.post(new EndRestoreRunnable(BackupManagerService.this, this));
         }
     }
 
-
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         synchronized (mQueueLock) {
diff --git a/services/java/com/android/server/DropBoxManagerService.java b/services/java/com/android/server/DropBoxManagerService.java
index 0a28da7..4305c358 100644
--- a/services/java/com/android/server/DropBoxManagerService.java
+++ b/services/java/com/android/server/DropBoxManagerService.java
@@ -218,8 +218,14 @@
                 }
             } while (read > 0);
 
-            createEntry(temp, tag, flags);
+            long time = createEntry(temp, tag, flags);
             temp = null;
+
+            Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
+            dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag);
+            dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time);
+            mContext.sendBroadcast(dropboxIntent, android.Manifest.permission.READ_LOGS);
+
         } catch (IOException e) {
             Slog.e(TAG, "Can't write: " + tag, e);
         } finally {
@@ -604,7 +610,7 @@
     }
 
     /** Moves a temporary file to a final log filename and enrolls it. */
-    private synchronized void createEntry(File temp, String tag, int flags) throws IOException {
+    private synchronized long createEntry(File temp, String tag, int flags) throws IOException {
         long t = System.currentTimeMillis();
 
         // Require each entry to have a unique timestamp; if there are entries
@@ -643,6 +649,7 @@
         } else {
             enrollEntry(new EntryFile(temp, mDropBoxDir, tag, t, flags, mBlockSize));
         }
+        return t;
     }
 
     /**
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index c121808..2691e1d 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -5774,9 +5774,6 @@
         res.removedInfo.removedPackage = packageName;
         // Remove existing system package
         removePackageLI(oldPkg, true);
-        synchronized (mPackages) {
-            res.removedInfo.removedUid = mSettings.disableSystemPackageLP(packageName);
-        }
 
         // Successfully disabled the old package. Now proceed with re-installation
         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index fff1874..a1f43b4 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -16,18 +16,16 @@
 
 package com.android.server;
 
-import android.app.backup.AbsoluteFileBackupHelper;
 import android.app.backup.BackupDataInput;
-import android.app.backup.BackupDataInputStream;
 import android.app.backup.BackupDataOutput;
-import android.app.backup.BackupHelper;
 import android.app.backup.BackupAgentHelper;
+import android.app.backup.WallpaperBackupHelper;
 import android.content.Context;
 import android.os.ParcelFileDescriptor;
 import android.os.ServiceManager;
-import android.os.SystemService;
 import android.util.Slog;
 
+
 import java.io.File;
 import java.io.IOException;
 
@@ -54,7 +52,7 @@
             // TODO: Send a delete for any stored wallpaper image in this case?
             files = new String[] { WALLPAPER_INFO };
         }
-        addHelper("wallpaper", new AbsoluteFileBackupHelper(SystemBackupAgent.this, files));
+        addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files));
         super.onBackup(oldState, data, newState);
     }
 
@@ -62,12 +60,11 @@
     public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
             throws IOException {
         // On restore, we also support a previous data schema "system_files"
-        addHelper("wallpaper", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
+        addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this,
                 new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }));
-        addHelper("system_files", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
+        addHelper("system_files", new WallpaperBackupHelper(SystemBackupAgent.this,
                 new String[] { WALLPAPER_IMAGE }));
 
-        boolean success = false;
         try {
             super.onRestore(data, appVersionCode, newState);
 
@@ -75,7 +72,7 @@
                     Context.WALLPAPER_SERVICE);
             wallpaper.settingsRestored();
         } catch (IOException ex) {
-            // If there was a failure, delete everything for the wallpaper, this is too aggresive,
+            // If there was a failure, delete everything for the wallpaper, this is too aggressive,
             // but this is hopefully a rare failure.
             Slog.d(TAG, "restore failed", ex);
             (new File(WALLPAPER_IMAGE)).delete();
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 7f81a25..07813b0 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -39,6 +39,7 @@
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WpsConfiguration;
 import android.net.ConnectivityManager;
 import android.net.InterfaceConfiguration;
 import android.net.DhcpInfo;
@@ -843,23 +844,13 @@
         mWifiStateMachine.forgetNetwork(netId);
     }
 
-    public void startWpsPbc(String bssid) {
-        enforceChangePermission();
-        mWifiStateMachine.startWpsPbc(bssid);
-    }
-
-    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
-        enforceChangePermission();
-        mWifiStateMachine.startWpsWithPinFromAccessPoint(bssid, apPin);
-    }
-
-    public int startWpsWithPinFromDevice(String bssid) {
+    public String startWps(WpsConfiguration config) {
         enforceChangePermission();
         if (mChannel != null) {
-            return mWifiStateMachine.syncStartWpsWithPinFromDevice(mChannel, bssid);
+            return mWifiStateMachine.startWps(mChannel, config);
         } else {
             Slog.e(TAG, "mChannel is not initialized");
-            return -1;
+            return "";
         }
     }
 
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 8e33011..ba7692d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4908,7 +4908,7 @@
         SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
     }
 
-    public Bitmap screenshotApplications(int maxWidth, int maxHeight) {
+    public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
         if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                 "screenshotApplications()")) {
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
@@ -4916,6 +4916,8 @@
 
         Bitmap rawss;
 
+        int maxLayer = 0;
+        boolean foundApp;
         final Rect frame = new Rect();
 
         float scale;
@@ -4939,6 +4941,13 @@
                 if (ws.mLayer >= aboveAppLayer) {
                     break;
                 }
+                if (appToken != null && (ws.mAppToken == null
+                        || ws.mAppToken.token != appToken)) {
+                    continue;
+                }
+                if (maxLayer < ws.mAnimLayer) {
+                    maxLayer = ws.mAnimLayer;
+                }
                 final Rect wf = ws.mFrame;
                 final Rect cr = ws.mContentInsets;
                 int left = wf.left + cr.left;
@@ -4978,7 +4987,7 @@
                 dh = tmp;
                 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
             }
-            rawss = Surface.screenshot(dw, dh);
+            rawss = Surface.screenshot(dw, dh, 0, maxLayer);
         }
 
         Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1bfdcae..a26fe5f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3808,8 +3808,14 @@
                 r.haveState = true;
                 if (thumbnail != null) {
                     r.thumbnail = thumbnail;
+                    if (r.task != null) {
+                        r.task.lastThumbnail = r.thumbnail;
+                    }
                 }
                 r.description = description;
+                if (r.task != null) {
+                    r.task.lastDescription = r.description;
+                }
                 r.stopped = true;
                 r.state = ActivityState.STOPPED;
                 if (!r.finishing) {
@@ -4826,9 +4832,10 @@
                 throw new SecurityException(msg);
             }
 
-            final boolean canReadFb = checkCallingPermission(
-                    android.Manifest.permission.READ_FRAME_BUFFER)
-                    == PackageManager.PERMISSION_GRANTED;
+            final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
+                    && checkCallingPermission(
+                            android.Manifest.permission.READ_FRAME_BUFFER)
+                            == PackageManager.PERMISSION_GRANTED;
 
             int pos = mMainStack.mHistory.size()-1;
             ActivityRecord next =
@@ -4878,7 +4885,7 @@
                         if (top.thumbnail != null) {
                             ci.thumbnail = top.thumbnail;
                         } else if (top.state == ActivityState.RESUMED) {
-                            ci.thumbnail = top.stack.screenshotActivities();
+                            ci.thumbnail = top.stack.screenshotActivities(top);
                         }
                     }
                     ci.description = topDescription;
@@ -4949,8 +4956,15 @@
             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
                     "getRecentTasks()");
 
+            final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
+                    && checkCallingPermission(
+                            android.Manifest.permission.READ_FRAME_BUFFER)
+                            == PackageManager.PERMISSION_GRANTED;
+            
             IPackageManager pm = AppGlobals.getPackageManager();
             
+            ActivityRecord resumed = mMainStack.mResumedActivity;
+            
             final int N = mRecentTasks.size();
             ArrayList<ActivityManager.RecentTaskInfo> res
                     = new ArrayList<ActivityManager.RecentTaskInfo>(
@@ -4968,6 +4982,15 @@
                             tr.intent != null ? tr.intent : tr.affinityIntent);
                     rti.origActivity = tr.origActivity;
                     
+                    if (canReadFb) {
+                        if (resumed != null && resumed.task == tr) {
+                            rti.thumbnail = resumed.stack.screenshotActivities(resumed);
+                        } else {
+                            rti.thumbnail = tr.lastThumbnail;
+                        }
+                    }
+                    rti.description = tr.lastDescription;
+                    
                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
                         // Check whether this activity is currently available.
                         try {
@@ -7340,6 +7363,9 @@
                 pw.println("    prov[iders]: content provider state");
                 pw.println("    s[ervices]: service state");
                 pw.println("    service [name]: service client-side state");
+                pw.println("  cmd may also be a component name (com.foo/.myApp),");
+                pw.println("    a partial substring in a component name, or an");
+                pw.println("    ActivityRecord hex object identifier.");
                 return;
             } else {
                 pw.println("Unknown argument: " + opt + "; use -h for help");
@@ -7393,7 +7419,9 @@
                 if (dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
                     return;
                 }
-                pw.println("Bad activity command: " + cmd);
+                pw.println("Bad activity command, or no activities match: " + cmd);
+                pw.println("Use -h for help.");
+                return;
             }
         }
         
@@ -7811,11 +7839,14 @@
         String[] newArgs;
         ComponentName componentName = ComponentName.unflattenFromString(name);
         int objectId = 0;
-        try {
-            objectId = Integer.parseInt(name, 16);
-            name = null;
-            componentName = null;
-        } catch (RuntimeException e) {
+        if (componentName == null) {
+            // Not a '/' separated full component name; maybe an object ID?
+            try {
+                objectId = Integer.parseInt(name, 16);
+                name = null;
+                componentName = null;
+            } catch (RuntimeException e) {
+            }
         }
         newArgs = new String[args.length - opti];
         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
@@ -7831,7 +7862,7 @@
                     if (r1.intent.getComponent().flattenToString().contains(name)) {
                         activities.add(r1);
                     }
-                } else if (System.identityHashCode(this) == objectId) {
+                } else if (System.identityHashCode(r1) == objectId) {
                     activities.add(r1);
                 }
             }
@@ -7841,8 +7872,18 @@
             return false;
         }
 
-        for (int i=0; i<activities.size(); i++) {
-            dumpActivity(fd, pw, activities.get(i), newArgs, dumpAll);
+        TaskRecord lastTask = null;
+        for (int i=activities.size()-1; i>=0; i--) {
+            ActivityRecord r = (ActivityRecord)activities.get(i);
+            if (lastTask != r.task) {
+                lastTask = r.task;
+                pw.print("* Task "); pw.print(lastTask.affinity);
+                        pw.print(" id="); pw.println(lastTask.taskId);
+                if (dumpAll) {
+                    lastTask.dump(pw, "  ");
+                }
+            }
+            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
         }
         return true;
     }
@@ -7851,23 +7892,24 @@
      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
      * there is a thread associated with the activity.
      */
-    private void dumpActivity(FileDescriptor fd, PrintWriter pw, ActivityRecord r, String[] args,
-            boolean dumpAll) {
-        pw.println("  Activity " + r.intent.getComponent().flattenToString());
-        if (dumpAll) {
-            synchronized (this) {
-                pw.print("  * "); pw.println(r);
-                r.dump(pw, "    ");
+    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
+            ActivityRecord r, String[] args, boolean dumpAll) {
+        synchronized (this) {
+            pw.print(prefix); pw.print("* Activity ");
+                    pw.print(Integer.toHexString(System.identityHashCode(r)));
+                    pw.print(" "); pw.print(r.shortComponentName); pw.print(" pid=");
+                    if (r.app != null) pw.println(r.app.pid);
+                    else pw.println("(not running)");
+            if (dumpAll) {
+                r.dump(pw, prefix + "  ");
             }
-            pw.println("");
         }
         if (r.app != null && r.app.thread != null) {
             try {
                 // flush anything that is already in the PrintWriter since the thread is going
                 // to write to the file descriptor directly
                 pw.flush();
-                r.app.thread.dumpActivity(fd, r, args);
-                pw.print("\n");
+                r.app.thread.dumpActivity(fd, r, prefix + "  ", args);
                 pw.flush();
             } catch (RemoteException e) {
                 pw.println("got a RemoteException while dumping the activity");
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index c2f8d67..b4e426f 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -587,7 +587,7 @@
             return stringName;
         }
         StringBuilder sb = new StringBuilder(128);
-        sb.append("HistoryRecord{");
+        sb.append("ActivityRecord{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         sb.append(' ');
         sb.append(intent.getComponent().flattenToShortString());
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index d92695c..920bbc9 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -650,7 +650,7 @@
         }
     }
     
-    public final Bitmap screenshotActivities() {
+    public final Bitmap screenshotActivities(ActivityRecord who) {
         Resources res = mService.mContext.getResources();
         int w = mThumbnailWidth;
         int h = mThumbnailHeight;
@@ -662,7 +662,7 @@
         }
 
         if (w > 0) {
-            //return mService.mWindowManager.screenshotApplications(w, h);
+            //return mService.mWindowManager.screenshotApplications(who, w, h);
         }
         return null;
     }
@@ -686,7 +686,10 @@
         mLastPausedActivity = prev;
         prev.state = ActivityState.PAUSING;
         prev.task.touchActiveTime();
-        prev.thumbnail = screenshotActivities();
+        prev.thumbnail = screenshotActivities(prev);
+        if (prev.task != null) {
+            prev.task.lastThumbnail = prev.thumbnail;
+        }
 
         mService.updateCpuStats();
         
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 0a98ebd..963a691 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -20,6 +20,7 @@
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -27,6 +28,7 @@
 import android.os.ServiceManager;
 import android.os.WorkSource;
 import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
 import android.util.Slog;
 
 import com.android.internal.app.IBatteryStats;
@@ -35,6 +37,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 
 /**
  * All information we are collecting about things that can happen that impact
@@ -217,8 +220,9 @@
 
     public void notePhoneState(int state) {
         enforceCallingPermission();
+        int simState = TelephonyManager.getDefault().getSimState();
         synchronized (mStats) {
-            mStats.notePhoneStateLocked(state);
+            mStats.notePhoneStateLocked(state, simState);
         }
     }
 
@@ -444,19 +448,28 @@
     
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (mStats) {
-            boolean isCheckin = false;
-            if (args != null) {
-                for (String arg : args) {
-                    if ("--checkin".equals(arg)) {
-                        isCheckin = true;
-                    } else if ("--reset".equals(arg)) {
+        boolean isCheckin = false;
+        if (args != null) {
+            for (String arg : args) {
+                if ("--checkin".equals(arg)) {
+                    isCheckin = true;
+                } else if ("--reset".equals(arg)) {
+                    synchronized (mStats) {
                         mStats.resetAllStatsLocked();
+                        pw.println("Battery stats reset.");
                     }
                 }
             }
-            if (isCheckin) mStats.dumpCheckinLocked(pw, args);
-            else mStats.dumpLocked(pw);
+        }
+        if (isCheckin) {
+            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
+            synchronized (mStats) {
+                mStats.dumpCheckinLocked(pw, args, apps);
+            }
+        } else {
+            synchronized (mStats) {
+                mStats.dumpLocked(pw);
+            }
         }
     }
 }
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 09d9c3b6..86cec42 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -19,7 +19,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.os.SystemClock;
+import android.graphics.Bitmap;
 
 import java.io.PrintWriter;
 
@@ -34,6 +34,8 @@
     long lastActiveTime;    // Last time this task was active, including sleep.
     boolean rootWasReset;   // True if the intent at the root of the task had
                             // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
+    Bitmap lastThumbnail;   // Last thumbnail captured for this task.
+    CharSequence lastDescription; // Last description captured for this task.
 
     String stringName;      // caching of toString() result.
     
diff --git a/tests/CoreTests/android/core/HashMapTest.java b/tests/CoreTests/android/core/HashMapTest.java
deleted file mode 100644
index 99b2a47..0000000
--- a/tests/CoreTests/android/core/HashMapTest.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import junit.framework.TestCase;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Test cases for Hashmap.
- */
-public class HashMapTest extends TestCase {
-    private static final Integer ONE = new Integer(1);
-    private static final Integer TWO = new Integer(2);
-    private static final Integer THREE = new Integer(3);
-    private static final Integer FOUR = new Integer(4);
-
-    private void addItems(HashMap map) {
-        map.put("one", ONE);
-        map.put("two", TWO);
-        map.put("three", THREE);
-        map.put("four", FOUR);
-
-        assertEquals(4, map.size());
-
-        assertEquals(ONE, map.get("one"));
-        assertEquals(TWO, map.get("two"));
-        assertEquals(THREE, map.get("three"));
-        assertEquals(FOUR, map.get("four"));
-    }
-
-    /**
-     * checks if simple adding elements works.
-     */
-    @SmallTest
-    public void testAdd() throws Exception {
-        HashMap map = new HashMap();
-        addItems(map);
-    }
-
-    /**
-     * checks if clearing the map works.
-     */
-    @SmallTest
-    public void testClear() throws Exception {
-        HashMap map = new HashMap();
-
-        addItems(map);
-        map.clear();
-        assertEquals(0, map.size());
-    }
-
-    /**
-     * checks if removing an elemt works.
-     */
-    @SmallTest
-    public void testRemove() throws Exception {
-        HashMap map = new HashMap();
-
-        addItems(map);
-        map.remove("three");
-        assertNull(map.get("three"));
-    }
-
-    /**
-     * does some manipulation with a filled HashMap and checks
-     * if they work as intended
-     */
-    @SmallTest
-    public void testManipulate() throws Exception {
-        HashMap map = new HashMap();
-
-        assertTrue(map.isEmpty());
-        assertEquals(0, map.size());
-        assertNull(map.get(null));
-        assertNull(map.get("one"));
-        assertFalse(map.containsKey("one"));
-        assertFalse(map.containsValue(new Integer(1)));
-        assertNull(map.remove(null));
-        assertNull(map.remove("one"));
-
-        assertNull(map.put(null, new Integer(-1)));
-        assertNull(map.put("one", new Integer(1)));
-        assertNull(map.put("two", new Integer(2)));
-        assertNull(map.put("three", new Integer(3)));
-        assertEquals(-1, ((Integer) map.put(null, new Integer(0))).intValue());
-
-        assertEquals(0, ((Integer) map.get(null)).intValue());
-        assertEquals(1, ((Integer) map.get("one")).intValue());
-        assertEquals(2, ((Integer) map.get("two")).intValue());
-        assertEquals(3, ((Integer) map.get("three")).intValue());
-
-        assertTrue(map.containsKey(null));
-        assertTrue(map.containsKey("one"));
-        assertTrue(map.containsKey("two"));
-        assertTrue(map.containsKey("three"));
-
-        assertTrue(map.containsValue(new Integer(0)));
-        assertTrue(map.containsValue(new Integer(1)));
-        assertTrue(map.containsValue(new Integer(2)));
-        assertTrue(map.containsValue(new Integer(3)));
-
-        assertEquals(0, ((Integer) map.remove(null)).intValue());
-        assertEquals(1, ((Integer) map.remove("one")).intValue());
-        assertEquals(2, ((Integer) map.remove("two")).intValue());
-        assertEquals(3, ((Integer) map.remove("three")).intValue());
-
-        assertTrue(map.isEmpty());
-        assertEquals(0, map.size());
-        assertNull(map.get(null));
-        assertNull(map.get("one"));
-        assertFalse(map.containsKey("one"));
-        assertFalse(map.containsValue(new Integer(1)));
-        assertNull(map.remove(null));
-        assertNull(map.remove("one"));
-    }
-
-    /**
-     * checks if the key iterator of HashMaps work.
-     */
-    @SmallTest
-    public void testKeyIterator() throws Exception {
-        HashMap map = new HashMap();
-
-        boolean[] slots = new boolean[4];
-
-        addItems(map);
-
-        Iterator iter = map.keySet().iterator();
-
-        while (iter.hasNext()) {
-            int slot = 0;
-            Object key = iter.next();
-
-            if (key.equals("one"))
-                slot = 0;
-            else if (key.equals("two"))
-                slot = 1;
-            else if (key.equals("three"))
-                slot = 2;
-            else if (key.equals("four"))
-                slot = 3;
-            else
-                fail("Unkown key in hashmap");
-
-            if (slots[slot])
-                fail("key returned more than once");
-            else
-                slots[slot] = true;
-        }
-
-        assertTrue(slots[0]);
-        assertTrue(slots[1]);
-        assertTrue(slots[2]);
-        assertTrue(slots[3]);
-    }
-
-    /**
-     * checks if the value iterator works.
-     */
-    @SmallTest
-    public void testValueIterator() throws Exception {
-        HashMap map = new HashMap();
-
-        boolean[] slots = new boolean[4];
-
-        addItems(map);
-
-        Iterator iter = map.values().iterator();
-
-        while (iter.hasNext()) {
-            int slot = 0;
-            Object value = iter.next();
-
-            if (value.equals(ONE))
-                slot = 0;
-            else if (value.equals(TWO))
-                slot = 1;
-            else if (value.equals(THREE))
-                slot = 2;
-            else if (value.equals(FOUR))
-                slot = 3;
-            else
-                fail("Unkown value in hashmap");
-
-            if (slots[slot])
-                fail("value returned more than once");
-            else
-                slots[slot] = true;
-        }
-
-        assertTrue(slots[0]);
-        assertTrue(slots[1]);
-        assertTrue(slots[2]);
-        assertTrue(slots[3]);
-    }
-
-    /**
-     * checks if the entry iterator works for HashMaps.
-     */
-    @SmallTest
-    public void testEntryIterator() throws Exception {
-        HashMap map = new HashMap();
-
-        boolean[] slots = new boolean[4];
-
-        addItems(map);
-
-        Iterator iter = map.entrySet().iterator();
-
-        while (iter.hasNext()) {
-            int slot = 0;
-            Object entry = iter.next();
-
-            if (entry.toString().equals("one=1"))
-                slot = 0;
-            else if (entry.toString().equals("two=2"))
-                slot = 1;
-            else if (entry.toString().equals("three=3"))
-                slot = 2;
-            else if (entry.toString().equals("four=4"))
-                slot = 3;
-            else
-                fail("Unkown entry in hashmap");
-
-            if (slots[slot])
-                fail("entry returned more than once");
-            else
-                slots[slot] = true;
-        }
-
-        assertTrue(slots[0]);
-        assertTrue(slots[1]);
-        assertTrue(slots[2]);
-        assertTrue(slots[3]);
-    }
-
-    /**
-     * checks if the HashMap equals method works.
-     */
-    @SmallTest
-    public void testEquals() throws Exception {
-        HashMap map1 = new HashMap();
-        HashMap map2 = new HashMap();
-        HashMap map3 = new HashMap();
-
-        map1.put("one", "1");
-        map1.put("two", "2");
-        map1.put("three", "3");
-
-        map2.put("one", new String("1"));
-        map2.put(new String("two"), "2");
-        map2.put(new String("three"), new String("3"));
-
-        assertTrue(map1.equals(map2));
-
-        map3.put("one", "1");
-        map3.put("two", "1");
-        map3.put("three", "1");
-
-        assertFalse(map1.equals(map3));
-        assertFalse(map2.equals(map3));
-    }
-}
-
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 16fa95a..8ac7590 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -907,10 +907,10 @@
                                     error.string());
                                 goto bail;
                         }
-                    } else if (tag == "uses-gl-texture") {
+                    } else if (tag == "supports-gl-texture") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
-                            printf("uses-gl-texture:'%s'\n", name.string());
+                            printf("supports-gl-texture:'%s'\n", name.string());
                         } else {
                             fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
                                     error.string());
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 7204ace..2102eb1 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -6,7 +6,7 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_PLAT_SRC/development/tools/ninepatch/src"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
index b7a602a..9b7bc5f 100644
--- a/tools/layoutlib/bridge/Android.mk
+++ b/tools/layoutlib/bridge/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_JAVA_LIBRARIES := \
 	kxml2-2.3.0 \
 	layoutlib_api-prebuilt \
-	ninepatch
+	ninepatch-prebuilt
 
 LOCAL_STATIC_JAVA_LIBRARIES := temp_layoutlib
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
index cd62baf..626f878 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
@@ -351,6 +351,7 @@
                 If the exception happened on open, bm will be null.
                 If it happened on close, bm is still valid.
             */
+            Bridge.getLog().error(null, e);
         } finally {
             try {
                 if (is != null) is.close();
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index b116d2b..f6d7b3a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -170,7 +170,8 @@
     }
 
     /*package*/ static boolean clipRect(Canvas thisCanvas, RectF rect) {
-        return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
+        return clipRect(thisCanvas,
+                (int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
     }
 
     /*package*/ static boolean clipRect(Canvas thisCanvas, Rect rect) {
@@ -179,16 +180,7 @@
 
     /*package*/ static boolean clipRect(Canvas thisCanvas, float left, float top, float right,
             float bottom) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
-        if (canvasDelegate == null) {
-            assert false;
-            return false;
-        }
-
-        canvasDelegate.getGraphics2d().clipRect((int)left, (int)top, (int)(right-left),
-                (int)(bottom-top));
-        return true;
+        return clipRect(thisCanvas, (int) left, (int) top, (int) right, (int) bottom);
     }
 
     /*package*/ static boolean clipRect(Canvas thisCanvas, int left, int top, int right,
@@ -200,8 +192,7 @@
             return false;
         }
 
-        canvasDelegate.getGraphics2d().clipRect(left, top, right - left, bottom - top);
-        return true;
+        return canvasDelegate.clipRect(left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
     }
 
     /*package*/ static int save(Canvas thisCanvas) {
@@ -277,8 +268,31 @@
 
     /*package*/ static void drawLines(Canvas thisCanvas, float[] pts, int offset, int count,
             Paint paint) {
-        // FIXME
-        throw new UnsupportedOperationException();
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            assert false;
+            return;
+        }
+
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint.mNativePaint);
+        if (paintDelegate == null) {
+            assert false;
+            return;
+        }
+
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
+
+        try {
+            for (int i = 0 ; i < count ; i += 4) {
+                g.drawLine((int)pts[i + offset], (int)pts[i + offset + 1],
+                        (int)pts[i + offset + 2], (int)pts[i + offset + 3]);
+            }
+        } finally {
+            // dispose Graphics2D object
+            g.dispose();
+        }
     }
 
     /*package*/ static void freeCaches() {
@@ -410,8 +424,16 @@
                                                   float left, float top,
                                                   float right, float bottom,
                                                   int regionOp) {
-        // FIXME
-        throw new UnsupportedOperationException();
+
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            assert false;
+        }
+
+        return canvasDelegate.clipRect(
+                (int) left, (int) top, (int) right, (int) bottom,
+                regionOp);
     }
 
     /*package*/ static boolean native_clipPath(int nativeCanvas,
@@ -1001,6 +1023,16 @@
         }
     }
 
+    private boolean clipRect(int left, int top, int right, int bottom, int regionOp) {
+        if (regionOp == Region.Op.INTERSECT.nativeInt) {
+            Graphics2D gc = getGraphics2d();
+            gc.clipRect(left, top, right - left, bottom - top);
+            return gc.getClip().getBounds().isEmpty() == false;
+        } else {
+            throw new UnsupportedOperationException();
+        }
+    }
+
     private void setBitmap(BufferedImage image) {
         mBufferedImage = image;
         mGraphicsStack.push(mBufferedImage.createGraphics());
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index b2333f6..bef8c8c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -869,7 +869,7 @@
              tmpDest = new float[dstIndex + pointCount * 2];
          }
 
-         for (int i = 0 ; i < pointCount ; i++) {
+         for (int i = 0 ; i < pointCount * 2 ; i += 2) {
              // just in case we are doing in place, we better put this in temp vars
              float x = mValues[0] * src[i + srcIndex] +
                        mValues[1] * src[i + srcIndex + 1] +
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
index a6c6dfd..95663ec 100644
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -167,7 +167,7 @@
 
        try {
            chunkObject.draw(bitmap_delegate.getImage(), graphics,
-                   left, top, right - left, bottom - top);
+                   left, top, right - left, bottom - top, destDensity, srcDensity);
        } finally {
            if (paint_delegate != null) {
                graphics.dispose();
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index c09f8ad..fa26bcf 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -390,13 +390,37 @@
     }
 
     /*package*/ static float ascent(Paint thisPaint) {
-        // FIXME
-        throw new UnsupportedOperationException();
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            assert false;
+            return 0;
+        }
+
+        if (delegate.mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
+            // Android expects negative ascent so we invert the value from Java.
+            return - javaMetrics.getAscent();
+        }
+
+        return 0;
     }
 
     /*package*/ static float descent(Paint thisPaint) {
-        // FIXME
-        throw new UnsupportedOperationException();
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            assert false;
+            return 0;
+        }
+
+        if (delegate.mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
+            return javaMetrics.getDescent();
+        }
+
+        return 0;
+
     }
 
     /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
@@ -407,21 +431,7 @@
             return 0;
         }
 
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
+        return delegate.getFontMetrics(metrics);
     }
 
     /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
@@ -698,8 +708,14 @@
     }
 
     /*package*/ static float native_getFontMetrics(int native_paint, FontMetrics metrics) {
-        // FIXME
-        throw new UnsupportedOperationException();
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_paint);
+        if (delegate == null) {
+            assert false;
+            return 0.f;
+        }
+
+        return delegate.getFontMetrics(metrics);
     }
 
     /*package*/ static int native_getTextWidths(int native_object, char[] text, int index,
@@ -941,9 +957,28 @@
         }
 
         return 0;
-
     }
 
+    private float getFontMetrics(FontMetrics metrics) {
+        if (mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
+            if (metrics != null) {
+                // Android expects negative ascent so we invert the value from Java.
+                metrics.top = - javaMetrics.getMaxAscent();
+                metrics.ascent = - javaMetrics.getAscent();
+                metrics.descent = javaMetrics.getDescent();
+                metrics.bottom = javaMetrics.getMaxDescent();
+                metrics.leading = javaMetrics.getLeading();
+            }
+
+            return javaMetrics.getHeight();
+        }
+
+        return 0;
+    }
+
+
+
     private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 605b378..f484e7a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -319,6 +319,8 @@
             BridgeXmlBlockParser parser = null;
             parser = (BridgeXmlBlockParser)set;
 
+            isPlatformFile = parser.isPlatformFile();
+
             Object key = parser.getViewKey();
             if (key != null) {
                 defaultPropMap = mDefaultPropMaps.get(key);
@@ -329,7 +331,9 @@
             }
 
         } else if (set instanceof BridgeLayoutParamsMapAttributes) {
-            // good, nothing to do.
+            // this is only for temp layout params generated dynamically, so this is never
+            // platform content.
+            isPlatformFile = false;
         } else if (set != null) { // null parser is ok
             // really this should not be happening since its instantiated in Bridge
             Bridge.getLog().error(null, "Parser is not a BridgeXmlBlockParser!");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 6d52f92..fcbf5fa 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -328,6 +328,7 @@
         }
 
         // looks like were unable to resolve the color value.
+        assert false;
         Bridge.getLog().warning(null, String.format(
                 "Unable to resolve color value \"%1$s\" in attribute \"%2$s\"",
                 value, mNames[index]));
@@ -405,6 +406,7 @@
         }
 
         // looks like we were unable to resolve the dimension value
+        assert false;
         Bridge.getLog().warning(null, String.format(
                 "Unable to resolve dimension value \"%1$s\" in attribute \"%2$s\"",
                 s, mNames[index]));
@@ -534,6 +536,7 @@
         }
 
         // looks like we were unable to resolve the fraction value
+        assert false;
         Bridge.getLog().warning(null, String.format(
                 "Unable to resolve fraction value \"%1$s\" in attribute \"%2$s\"",
                 value, mNames[index]));
@@ -641,6 +644,7 @@
             return idValue.intValue();
         }
 
+        assert false;
         Bridge.getLog().warning(null, String.format(
                 "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]));
         return defValue;
@@ -675,6 +679,7 @@
         }
 
         // looks like we were unable to resolve the drawable
+        assert false;
         Bridge.getLog().warning(null, String.format(
                 "Unable to resolve drawable \"%1$s\" in attribute \"%2$s\"", stringValue,
                 mNames[index]));
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index d8cd2c1..24cf380 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -152,6 +152,8 @@
             return result;
         }
 
+        Bridge.setLog(mParams.getLog());
+
         // setup the display Metrics.
         DisplayMetrics metrics = new DisplayMetrics();
         metrics.densityDpi = mParams.getDensity();
@@ -918,6 +920,7 @@
             return (StyleResourceValue)parent;
         }
 
+        assert false;
         mParams.getLog().error(null,
                 String.format("Unable to resolve parent style name: %s", parentName));
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 13f0f4a7..f03931f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -48,7 +48,7 @@
 import java.util.regex.Pattern;
 
 /**
- * Helper class to provide various convertion method used in handling android resources.
+ * Helper class to provide various conversion method used in handling android resources.
  */
 public final class ResourceHelper {
 
@@ -133,7 +133,8 @@
                 // if either chunk or bitmap is null, then we reload the 9-patch file.
                 if (chunk == null || bitmap == null) {
                     try {
-                        NinePatch ninePatch = NinePatch.load(file.toURL(), false /* convert */);
+                        NinePatch ninePatch = NinePatch.load(file.toURI().toURL(),
+                                false /* convert */);
                         if (ninePatch != null) {
                             if (chunk == null) {
                                 chunk = ninePatch.getChunk();
@@ -161,6 +162,7 @@
                         // URL is wrong, we'll return null below
                     } catch (IOException e) {
                         // failed to read the file, we'll return null below.
+                        Bridge.getLog().error(null, e);
                     }
                 }
 
@@ -176,7 +178,7 @@
 
             return null;
         } else if (lowerCaseValue.endsWith(".xml")) {
-            // create a blockparser for the file
+            // create a block parser for the file
             File f = new File(stringValue);
             if (f.isFile()) {
                 try {
@@ -220,7 +222,7 @@
                     return new BitmapDrawable(context.getResources(), bitmap);
                 } catch (IOException e) {
                     // we'll return null below
-                    // TODO: log the error.
+                    Bridge.getLog().error(null, e);
                 }
             } else {
                 // attempt to get a color from the value
@@ -229,7 +231,8 @@
                     return new ColorDrawable(color);
                 } catch (NumberFormatException e) {
                     // we'll return null below.
-                    // TODO: log the error
+                    Bridge.getLog().error(null,
+                            "failed to convert " + stringValue + " into a drawable");
                 }
             }
         }
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 24001bb..9dbba20 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -18,6 +18,7 @@
 
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WpsConfiguration;
 import android.net.wifi.ScanResult;
 import android.net.DhcpInfo;
 
@@ -108,10 +109,6 @@
 
     void forgetNetwork(int networkId);
 
-    void startWpsPbc(String bssid);
-
-    void startWpsWithPinFromAccessPoint(String bssid, int apPin);
-
-    int startWpsWithPinFromDevice(String bssid);
+    String startWps(in WpsConfiguration config);
 }
 
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index a83a0ad..f823314 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -32,7 +32,6 @@
  * that is based on these state changes:
  * - detect a failed WPA handshake that loops indefinitely
  * - password failure handling
- * - Enable networks after a WPS success/failure
  */
 class SupplicantStateTracker extends HierarchicalStateMachine {
 
@@ -49,10 +48,6 @@
     /* Maximum retries on a password failure notification */
     private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
 
-    /* Track if WPS was started since we need to re-enable networks
-     * and load configuration afterwards */
-    private boolean mWpsStarted = false;
-
     private Context mContext;
 
     private HierarchicalState mUninitializedState = new UninitializedState();
@@ -156,11 +151,6 @@
                     mPasswordFailuresCount++;
                     mAuthFailureInSupplicantBroadcast = true;
                     break;
-                case WifiStateMachine.CMD_START_WPS_PBC:
-                case WifiStateMachine.CMD_START_WPS_PIN_FROM_AP:
-                case WifiStateMachine.CMD_START_WPS_PIN_FROM_DEVICE:
-                    mWpsStarted = true;
-                    break;
                 case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
                     StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
                     sendSupplicantStateChangedBroadcast(stateChangeResult,
@@ -192,12 +182,6 @@
         @Override
          public void enter() {
              if (DBG) Log.d(TAG, getName() + "\n");
-             /* A failed WPS connection */
-             if (mWpsStarted) {
-                 Log.e(TAG, "WPS set up failed, enabling other networks");
-                 WifiConfigStore.enableAllNetworks();
-                 mWpsStarted = false;
-             }
              mWifiStateMachine.setNetworkAvailable(false);
          }
         @Override
@@ -289,13 +273,6 @@
              if (DBG) Log.d(TAG, getName() + "\n");
              /* Reset password failure count */
              mPasswordFailuresCount = 0;
-
-             /* A successful WPS connection */
-             if (mWpsStarted) {
-                 WifiConfigStore.enableAllNetworks();
-                 WifiConfigStore.loadConfiguredNetworks();
-                 mWpsStarted = false;
-             }
          }
         @Override
         public boolean processMessage(Message message) {
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index c6b0299..f597934 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -366,8 +366,8 @@
      * Start WPS pin method configuration with pin obtained
      * from the access point
      */
-    static boolean startWpsWithPinFromAccessPoint(String bssid, int apPin) {
-        if (WifiNative.startWpsWithPinFromAccessPointCommand(bssid, apPin)) {
+    static boolean startWpsWithPinFromAccessPoint(WpsConfiguration config) {
+        if (WifiNative.startWpsWithPinFromAccessPointCommand(config.BSSID, config.pin)) {
             /* WPS leaves all networks disabled */
             markAllNetworksDisabled();
             return true;
@@ -379,14 +379,16 @@
     /**
      * Start WPS pin method configuration with pin obtained
      * from the device
+     * @return empty string on failure. null is never returned.
      */
-    static int startWpsWithPinFromDevice(String bssid) {
-        int pin = WifiNative.startWpsWithPinFromDeviceCommand(bssid);
+    static String startWpsWithPinFromDevice(WpsConfiguration config) {
+        String pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID);
         /* WPS leaves all networks disabled */
-        if (pin != -1) {
+        if (!TextUtils.isEmpty(pin)) {
             markAllNetworksDisabled();
         } else {
             Log.e(TAG, "Failed to start WPS pin method configuration");
+            pin = "";
         }
         return pin;
     }
@@ -394,8 +396,8 @@
     /**
      * Start WPS push button configuration
      */
-    static boolean startWpsPbc(String bssid) {
-        if (WifiNative.startWpsPbcCommand(bssid)) {
+    static boolean startWpsPbc(WpsConfiguration config) {
+        if (WifiNative.startWpsPbcCommand(config.BSSID)) {
             /* WPS leaves all networks disabled */
             markAllNetworksDisabled();
             return true;
@@ -527,6 +529,18 @@
         sendConfiguredNetworksChangedBroadcast();
     }
 
+    static void updateIpAndProxyFromWpsConfig(int netId, WpsConfiguration wpsConfig) {
+        synchronized (sConfiguredNetworks) {
+            WifiConfiguration config = sConfiguredNetworks.get(netId);
+            if (config != null) {
+                config.ipAssignment = wpsConfig.ipAssignment;
+                config.proxySettings = wpsConfig.proxySettings;
+                config.linkProperties = wpsConfig.linkProperties;
+                writeIpAndProxyConfigurations();
+            }
+        }
+    }
+
     /* Mark all networks except specified netId as disabled */
     private static void markAllNetworksDisabledExcept(int netId) {
         synchronized (sConfiguredNetworks) {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e3be5b3..4623721 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1071,45 +1071,18 @@
     }
 
     /**
-     * Start Wi-fi protected setup push button Configuration
+     * Start Wi-fi Protected Setup
      *
-     * @param bssid BSSID of the access point
+     * @param config WPS configuration
+     * @return pin generated by device, if any
      * @hide
+     * TODO: with use of AsyncChannel, return value should go away
      */
-    public void startWpsPbc(String bssid) {
+    public String startWps(WpsConfiguration config) {
         try {
-            mService.startWpsPbc(bssid);
-        } catch (RemoteException e) { }
-    }
-
-    /**
-     * Start Wi-fi Protected Setup pin method configuration
-     * with pin obtained from the access point
-     *
-     * @param bssid BSSID of the access point
-     * @param apPin PIN issued by the access point
-     *
-     * @hide
-     */
-    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
-        try {
-            mService.startWpsWithPinFromAccessPoint(bssid, apPin);
-        } catch (RemoteException e) { }
-    }
-
-    /**
-     * Start Wi-fi Protected Setup pin method configuration
-     * with pin obtained from the device
-     *
-     * @param bssid BSSID of the access point
-     * @return pin generated by device
-     * @hide
-     */
-    public int startWpsWithPinFromDevice(String bssid) {
-        try {
-            return mService.startWpsWithPinFromDevice(bssid);
+            return mService.startWps(config);
         } catch (RemoteException e) {
-            return -1;
+            return null;
         }
     }
 
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 06f945b..0310420 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -149,9 +149,9 @@
 
     public native static boolean startWpsPbcCommand(String bssid);
 
-    public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, int apPin);
+    public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, String apPin);
 
-    public native static int startWpsWithPinFromDeviceCommand(String bssid);
+    public native static String startWpsWithPinFromDeviceCommand(String bssid);
 
     public native static boolean doDhcpRequest(DhcpInfo results);
 
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 18385b7..5474b3f 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -147,6 +147,8 @@
     private WifiInfo mWifiInfo;
     private NetworkInfo mNetworkInfo;
     private SupplicantStateTracker mSupplicantStateTracker;
+    private WpsStateMachine mWpsStateMachine;
+
     /* Connection to a specific network involves disabling all networks,
      * this flag tracks if networks need to be re-enabled */
     private boolean mEnableAllNetworks = false;
@@ -307,19 +309,19 @@
      * supplicant config.
      */
     static final int CMD_FORGET_NETWORK                   = 88;
-    /* Start Wi-Fi protected setup push button configuration */
-    static final int CMD_START_WPS_PBC                    = 89;
-    /* Start Wi-Fi protected setup pin method configuration with pin obtained from AP */
-    static final int CMD_START_WPS_PIN_FROM_AP            = 90;
-    /* Start Wi-Fi protected setup pin method configuration with pin obtained from device */
-    static final int CMD_START_WPS_PIN_FROM_DEVICE        = 91;
+    /* Start Wi-Fi protected setup */
+    static final int CMD_START_WPS                        = 89;
     /* Set the frequency band */
-    static final int CMD_SET_FREQUENCY_BAND               = 92;
+    static final int CMD_SET_FREQUENCY_BAND               = 90;
 
     /* Commands from the SupplicantStateTracker */
     /* Indicates whether a wifi network is available for connection */
     static final int CMD_SET_NETWORK_AVAILABLE             = 111;
 
+    /* Commands/events reported by WpsStateMachine */
+    /* Indicates the completion of WPS activity */
+    static final int WPS_COMPLETED_EVENT                   = 121;
+
     private static final int CONNECT_MODE   = 1;
     private static final int SCAN_ONLY_MODE = 2;
 
@@ -387,6 +389,8 @@
     private HierarchicalState mDisconnectingState = new DisconnectingState();
     /* Network is not connected, supplicant assoc+auth is not complete */
     private HierarchicalState mDisconnectedState = new DisconnectedState();
+    /* Waiting for WPS to be completed*/
+    private HierarchicalState mWaitForWpsCompletionState = new WaitForWpsCompletionState();
 
     /* Soft Ap is running */
     private HierarchicalState mSoftApStartedState = new SoftApStartedState();
@@ -457,6 +461,7 @@
         mWifiInfo = new WifiInfo();
         mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
         mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
+        mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
 
         mLinkProperties = new LinkProperties();
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -518,6 +523,7 @@
                         addState(mConnectedState, mConnectModeState);
                         addState(mDisconnectingState, mConnectModeState);
                         addState(mDisconnectedState, mConnectModeState);
+                        addState(mWaitForWpsCompletionState, mConnectModeState);
                 addState(mDriverStoppingState, mDriverSupReadyState);
                 addState(mDriverStoppedState, mDriverSupReadyState);
             addState(mSoftApStartedState, mDefaultState);
@@ -808,18 +814,20 @@
         sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
     }
 
-    public void startWpsPbc(String bssid) {
-        sendMessage(obtainMessage(CMD_START_WPS_PBC, bssid));
-    }
-
-    public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
-        sendMessage(obtainMessage(CMD_START_WPS_PIN_FROM_AP, apPin, 0, bssid));
-    }
-
-    public int syncStartWpsWithPinFromDevice(AsyncChannel channel, String bssid) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN_FROM_DEVICE, bssid);
-        int result = resultMsg.arg1;
-        resultMsg.recycle();
+    public String startWps(AsyncChannel channel, WpsConfiguration config) {
+        String result = null;
+        switch (config.setup) {
+            case PIN_FROM_DEVICE:
+                //TODO: will go away with AsyncChannel use from settings
+                Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
+                result = (String) resultMsg.obj;
+                resultMsg.recycle();
+                break;
+            case PBC:
+            case PIN_FROM_ACCESS_POINT:
+                sendMessage(obtainMessage(CMD_START_WPS, config));
+                break;
+        }
         return result;
     }
 
@@ -1554,7 +1562,6 @@
                 case CMD_ADD_OR_UPDATE_NETWORK:
                 case CMD_REMOVE_NETWORK:
                 case CMD_SAVE_CONFIG:
-                case CMD_START_WPS_PIN_FROM_DEVICE:
                     mReplyChannel.replyToMessage(message, message.what, FAILURE);
                     break;
                 case CMD_ENABLE_RSSI_POLL:
@@ -1598,10 +1605,17 @@
                 case CMD_CONNECT_NETWORK:
                 case CMD_SAVE_NETWORK:
                 case CMD_FORGET_NETWORK:
-                case CMD_START_WPS_PBC:
-                case CMD_START_WPS_PIN_FROM_AP:
                 case CMD_RSSI_POLL:
                     break;
+                case CMD_START_WPS:
+                    WpsConfiguration config = (WpsConfiguration) message.obj;
+                    switch (config.setup) {
+                        case PIN_FROM_DEVICE:
+                            String pin = "";
+                            mReplyChannel.replyToMessage(message, message.what, pin);
+                            break;
+                    }
+                    break;
                 default:
                     Log.e(TAG, "Error! unhandled message" + message);
                     break;
@@ -2306,9 +2320,8 @@
                         mWifiInfo.setBSSID(stateChangeResult.BSSID);
                     }
 
-                    Message newMsg = obtainMessage();
-                    newMsg.copyFrom(message);
-                    mSupplicantStateTracker.sendMessage(newMsg);
+                    mSupplicantStateTracker.sendMessage(Message.obtain(message));
+                    mWpsStateMachine.sendMessage(Message.obtain(message));
                     break;
                     /* Do a redundant disconnect without transition */
                 case CMD_DISCONNECT:
@@ -2348,51 +2361,9 @@
                     /* Expect a disconnection from the old connection */
                     transitionTo(mDisconnectingState);
                     break;
-                case CMD_START_WPS_PBC:
-                    String bssid = (String) message.obj;
-                    /* WPS push button configuration */
-                    boolean success = WifiConfigStore.startWpsPbc(bssid);
-
-                    /* During WPS setup, all other networks are disabled. After
-                     * a successful connect a new config is created in the supplicant.
-                     *
-                     * We need to enable all networks after a successful connection
-                     * or when supplicant goes inactive due to failure. Enabling all
-                     * networks after a disconnect is observed as done with connectNetwork
-                     * does not lead to a successful WPS setup.
-                     *
-                     * Upon success, the configuration list needs to be reloaded
-                     */
-                    if (success) {
-                        mSupplicantStateTracker.sendMessage(message.what);
-                        /* Expect a disconnection from the old connection */
-                        transitionTo(mDisconnectingState);
-                    }
-                    break;
-                case CMD_START_WPS_PIN_FROM_AP:
-                    bssid = (String) message.obj;
-                    int apPin = message.arg1;
-
-                    /* WPS pin from access point */
-                    success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
-
-                    if (success) {
-                        mSupplicantStateTracker.sendMessage(message.what);
-                        /* Expect a disconnection from the old connection */
-                        transitionTo(mDisconnectingState);
-                    }
-                    break;
-                case CMD_START_WPS_PIN_FROM_DEVICE:
-                    bssid = (String) message.obj;
-                    int pin = WifiConfigStore.startWpsWithPinFromDevice(bssid);
-                    success = (pin != FAILURE);
-                    mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN_FROM_DEVICE, pin);
-
-                    if (success) {
-                        mSupplicantStateTracker.sendMessage(message.what);
-                        /* Expect a disconnection from the old connection */
-                        transitionTo(mDisconnectingState);
-                    }
+                case CMD_START_WPS:
+                    mWpsStateMachine.sendMessage(Message.obtain(message));
+                    transitionTo(mWaitForWpsCompletionState);
                     break;
                 case SCAN_RESULTS_EVENT:
                     /* Set the scan setting back to "connect" mode */
@@ -2436,7 +2407,6 @@
         public void enter() {
             if (DBG) Log.d(TAG, getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
-
             mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
             if (!mUseStaticIp) {
                 mDhcpThread = null;
@@ -2799,6 +2769,45 @@
         }
     }
 
+    class WaitForWpsCompletionState extends HierarchicalState {
+        @Override
+        public void enter() {
+            if (DBG) Log.d(TAG, getName() + "\n");
+            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+        }
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            switch (message.what) {
+                /* Defer all commands that can cause connections to a different network
+                 * or put the state machine out of connect mode
+                 */
+                case CMD_STOP_DRIVER:
+                case CMD_SET_SCAN_MODE:
+                case CMD_CONNECT_NETWORK:
+                case CMD_ENABLE_NETWORK:
+                case CMD_RECONNECT:
+                case CMD_REASSOCIATE:
+                case NETWORK_CONNECTION_EVENT: /* Handled after IP & proxy update */
+                    deferMessage(message);
+                    break;
+                case NETWORK_DISCONNECTION_EVENT:
+                    Log.d(TAG,"Network connection lost");
+                    handleNetworkDisconnect();
+                    break;
+                case WPS_COMPLETED_EVENT:
+                    /* we are still disconnected until we see a network connection
+                     * notification */
+                    transitionTo(mDisconnectedState);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+            return HANDLED;
+        }
+    }
+
     class SoftApStartedState extends HierarchicalState {
         @Override
         public void enter() {
diff --git a/wifi/java/android/net/wifi/WpsConfiguration.aidl b/wifi/java/android/net/wifi/WpsConfiguration.aidl
new file mode 100644
index 0000000..6c26833
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsConfiguration.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+parcelable WpsConfiguration;
diff --git a/wifi/java/android/net/wifi/WpsConfiguration.java b/wifi/java/android/net/wifi/WpsConfiguration.java
new file mode 100644
index 0000000..12d951f
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsConfiguration.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.net.LinkProperties;
+import android.net.wifi.WifiConfiguration.IpAssignment;
+import android.net.wifi.WifiConfiguration.ProxySettings;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.BitSet;
+
+/**
+ * A class representing a WPS network configuration
+ * @hide
+ */
+public class WpsConfiguration implements Parcelable {
+
+    public enum Setup {
+        /* Wi-Fi protected setup push button configuration */
+        PBC,
+        /* Wi-Fi protected setup pin method configuration with pin obtained from access point */
+        PIN_FROM_ACCESS_POINT,
+        /* Wi-Fi protected setup pin method configuration with pin obtained from device */
+        PIN_FROM_DEVICE,
+        /* Invalid config */
+        INVALID
+    }
+
+    public Setup setup;
+
+    public String BSSID;
+
+    public String pin;
+
+    public IpAssignment ipAssignment;
+
+    public ProxySettings proxySettings;
+
+    public LinkProperties linkProperties;
+
+    public WpsConfiguration() {
+        setup = Setup.INVALID;
+        BSSID = null;
+        pin = null;
+        ipAssignment = IpAssignment.UNASSIGNED;
+        proxySettings = ProxySettings.UNASSIGNED;
+        linkProperties = new LinkProperties();
+    }
+
+    public String toString() {
+        StringBuffer sbuf = new StringBuffer();
+        sbuf.append(" setup: ").append(setup.toString());
+        sbuf.append('\n');
+        sbuf.append(" BSSID: ").append(BSSID);
+        sbuf.append('\n');
+        sbuf.append(" pin: ").append(pin);
+        sbuf.append('\n');
+        sbuf.append("IP assignment: " + ipAssignment.toString());
+        sbuf.append("\n");
+        sbuf.append("Proxy settings: " + proxySettings.toString());
+        sbuf.append("\n");
+        sbuf.append(linkProperties.toString());
+        sbuf.append("\n");
+        return sbuf.toString();
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** copy constructor {@hide} */
+    public WpsConfiguration(WpsConfiguration source) {
+        if (source != null) {
+            setup = source.setup;
+            BSSID = source.BSSID;
+            pin = source.pin;
+            ipAssignment = source.ipAssignment;
+            proxySettings = source.proxySettings;
+            linkProperties = new LinkProperties(source.linkProperties);
+        }
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(setup.name());
+        dest.writeString(BSSID);
+        dest.writeString(pin);
+        dest.writeString(ipAssignment.name());
+        dest.writeString(proxySettings.name());
+        dest.writeParcelable(linkProperties, flags);
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<WpsConfiguration> CREATOR =
+        new Creator<WpsConfiguration>() {
+            public WpsConfiguration createFromParcel(Parcel in) {
+                WpsConfiguration config = new WpsConfiguration();
+                config.setup = Setup.valueOf(in.readString());
+                config.BSSID = in.readString();
+                config.pin = in.readString();
+                config.ipAssignment = IpAssignment.valueOf(in.readString());
+                config.proxySettings = ProxySettings.valueOf(in.readString());
+                config.linkProperties = in.readParcelable(null);
+                return config;
+            }
+
+            public WpsConfiguration[] newArray(int size) {
+                return new WpsConfiguration[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java
new file mode 100644
index 0000000..381444c
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsStateMachine.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.HierarchicalState;
+import com.android.internal.util.HierarchicalStateMachine;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiStateMachine.StateChangeResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Manages a WPS connection.
+ *
+ * WPS consists as a series of EAP exchange triggered
+ * by a user action that leads to a successful connection
+ * after automatic creation of configuration in the
+ * supplicant. We currently support the following methods
+ * of WPS setup
+ * 1. Pin method: Pin can be either obtained from the device
+ *    or from the access point to connect to.
+ * 2. Push button method: This involves pushing a button on
+ *    the access point and the device
+ *
+ * After a successful WPS setup, the state machine
+ * reloads the configuration and updates the IP and proxy
+ * settings, if any.
+ */
+class WpsStateMachine extends HierarchicalStateMachine {
+
+    private static final String TAG = "WpsStateMachine";
+    private static final boolean DBG = false;
+
+    private WifiStateMachine mWifiStateMachine;
+
+    private WpsConfiguration mWpsConfig;
+
+    private Context mContext;
+    AsyncChannel mReplyChannel = new AsyncChannel();
+
+    private HierarchicalState mDefaultState = new DefaultState();
+    private HierarchicalState mInactiveState = new InactiveState();
+    private HierarchicalState mActiveState = new ActiveState();
+
+    public WpsStateMachine(Context context, WifiStateMachine wsm, Handler target) {
+        super(TAG, target.getLooper());
+
+        mContext = context;
+        mWifiStateMachine = wsm;
+        addState(mDefaultState);
+            addState(mInactiveState, mDefaultState);
+            addState(mActiveState, mDefaultState);
+
+        setInitialState(mInactiveState);
+
+        //start the state machine
+        start();
+    }
+
+
+    /********************************************************
+     * HSM states
+     *******************************************************/
+
+    class DefaultState extends HierarchicalState {
+        @Override
+         public void enter() {
+             if (DBG) Log.d(TAG, getName() + "\n");
+         }
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            WpsConfiguration wpsConfig;
+            switch (message.what) {
+                case WifiStateMachine.CMD_START_WPS:
+                    mWpsConfig = (WpsConfiguration) message.obj;
+                    boolean success = false;
+                    switch (mWpsConfig.setup) {
+                        case PBC:
+                            success = WifiConfigStore.startWpsPbc(mWpsConfig);
+                            break;
+                        case PIN_FROM_ACCESS_POINT:
+                            success = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig);
+                            break;
+                        case PIN_FROM_DEVICE:
+                            String pin = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig);
+                            success = (pin != null);
+                            mReplyChannel.replyToMessage(message, message.what, pin);
+                            break;
+                        default:
+                            Log.e(TAG, "Invalid setup for WPS");
+                            break;
+                    }
+                    if (success) {
+                        transitionTo(mActiveState);
+                    } else {
+                        Log.e(TAG, "Failed to start WPS with config " + mWpsConfig.toString());
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Failed to handle " + message);
+                    break;
+            }
+            return HANDLED;
+        }
+    }
+
+    class ActiveState extends HierarchicalState {
+        @Override
+         public void enter() {
+             if (DBG) Log.d(TAG, getName() + "\n");
+         }
+
+        @Override
+        public boolean processMessage(Message message) {
+            boolean retValue = HANDLED;
+            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            switch (message.what) {
+                case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+                    SupplicantState supState = (SupplicantState) stateChangeResult.state;
+                    switch (supState) {
+                        case COMPLETED:
+                            /* During WPS setup, all other networks are disabled. After
+                             * a successful connect a new config is created in the supplicant.
+                             *
+                             * We need to enable all networks after a successful connection
+                             * and the configuration list needs to be reloaded from the supplicant.
+                             */
+                            Log.d(TAG, "WPS set up successful");
+                            WifiConfigStore.enableAllNetworks();
+                            WifiConfigStore.loadConfiguredNetworks();
+                            WifiConfigStore.updateIpAndProxyFromWpsConfig(
+                                    stateChangeResult.networkId, mWpsConfig);
+                            mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT);
+                            transitionTo(mInactiveState);
+                            break;
+                        case INACTIVE:
+                            /* A failed WPS connection */
+                            Log.d(TAG, "WPS set up failed, enabling other networks");
+                            WifiConfigStore.enableAllNetworks();
+                            mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT);
+                            transitionTo(mInactiveState);
+                            break;
+                        default:
+                            if (DBG) Log.d(TAG, "Ignoring supplicant state " + supState.name());
+                            break;
+                    }
+                    break;
+                case WifiStateMachine.CMD_START_WPS:
+                    deferMessage(message);
+                    break;
+                default:
+                    retValue = NOT_HANDLED;
+            }
+            return retValue;
+        }
+    }
+
+    class InactiveState extends HierarchicalState {
+        @Override
+        public void enter() {
+            if (DBG) Log.d(TAG, getName() + "\n");
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            boolean retValue = HANDLED;
+            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            switch (message.what) {
+                //Ignore supplicant state changes
+                case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+                    break;
+                default:
+                    retValue = NOT_HANDLED;
+            }
+            return retValue;
+        }
+    }
+
+}
\ No newline at end of file