Merge "Import translations. DO NOT MERGE" into jb-mr1-dev
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 773e0fe..de97481 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -25,6 +25,7 @@
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -336,6 +337,7 @@
 
     private int mNextHistoryId = 0;
     private SparseArray<Boolean> mMasterSyncAutomatically = new SparseArray<Boolean>();
+    private boolean mDefaultMasterSyncAutomatically;
 
     private OnSyncRequestListener mSyncRequestListener;
 
@@ -345,6 +347,9 @@
 
         mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
 
+        mDefaultMasterSyncAutomatically = mContext.getResources().getBoolean(
+               com.android.internal.R.bool.config_syncstorageengine_masterSyncAutomatically);
+
         File systemDir = new File(dataDir, "system");
         File syncDir = new File(systemDir, "sync");
         syncDir.mkdirs();
@@ -780,7 +785,7 @@
     public boolean getMasterSyncAutomatically(int userId) {
         synchronized (mAuthorities) {
             Boolean auto = mMasterSyncAutomatically.get(userId);
-            return auto == null ? true : auto;
+            return auto == null ? mDefaultMasterSyncAutomatically : auto;
         }
     }
 
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index ed1c5b3..2d9dae9 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -688,7 +688,8 @@
                         }
                     } catch (FormatException e) {  }
                 } else if (Arrays.equals(mType, RTD_URI)) {
-                    return parseWktUri().normalizeScheme();
+                    Uri wktUri = parseWktUri();
+                    return (wktUri != null ? wktUri.normalizeScheme() : null);
                 }
                 break;
 
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 1b23b18..6074a0c 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -247,7 +247,6 @@
         mWebViewCore = w;
 
         mSearchBox = new SearchBoxImpl(mWebViewCore, mCallbackProxy);
-        mJavaScriptObjects.put(SearchBoxImpl.JS_INTERFACE_NAME, mSearchBox);
 
         AssetManager am = context.getAssets();
         nativeCreateFrame(w, am, proxy.getBackForwardList());
@@ -598,8 +597,6 @@
             }
         }
         mRemovedJavaScriptObjects.clear();
-
-        stringByEvaluatingJavaScriptFromString(SearchBoxImpl.JS_BRIDGE);
     }
 
     /**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f502de4..c9688c8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -302,6 +302,7 @@
 
     // The alignment to pass to Layout, or null if not resolved.
     private Layout.Alignment mLayoutAlignment;
+    private int mResolvedTextAlignment;
 
     private boolean mResolvedDrawables;
 
@@ -5639,9 +5640,8 @@
     @Override
     public void onResolvedLayoutDirectionReset() {
         if (mLayoutAlignment != null) {
-            int resolvedTextAlignment = getResolvedTextAlignment();
-            if (resolvedTextAlignment == TEXT_ALIGNMENT_VIEW_START ||
-                 resolvedTextAlignment == TEXT_ALIGNMENT_VIEW_END) {
+            if (mResolvedTextAlignment == TEXT_ALIGNMENT_VIEW_START ||
+                    mResolvedTextAlignment == TEXT_ALIGNMENT_VIEW_END) {
                 mLayoutAlignment = null;
             }
         }
@@ -5649,8 +5649,8 @@
 
     private Layout.Alignment getLayoutAlignment() {
         if (mLayoutAlignment == null) {
-            int textAlign = getResolvedTextAlignment();
-            switch (textAlign) {
+            mResolvedTextAlignment = getResolvedTextAlignment();
+            switch (mResolvedTextAlignment) {
                 case TEXT_ALIGNMENT_GRAVITY:
                     switch (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) {
                         case Gravity.START:
diff --git a/core/res/res/anim/keyguard_security_fade_in.xml b/core/res/res/anim/keyguard_security_fade_in.xml
new file mode 100644
index 0000000..7d5516a
--- /dev/null
+++ b/core/res/res/anim/keyguard_security_fade_in.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@interpolator/decelerate_quad"
+    android:fromAlpha="0.0" android:toAlpha="1.0"
+    android:duration="@integer/kg_security_fade_duration" />
+
+
diff --git a/core/res/res/anim/keyguard_security_fade_out.xml b/core/res/res/anim/keyguard_security_fade_out.xml
new file mode 100644
index 0000000..caf896e
--- /dev/null
+++ b/core/res/res/anim/keyguard_security_fade_out.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/accelerate_quad"
+    android:fromAlpha="1.0"
+    android:toAlpha="0.0"
+    android:duration="@integer/kg_security_fade_duration"
+/>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
index 4ceb907..4f94f96 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
@@ -154,7 +154,7 @@
 
         <!-- Area to overlay FaceLock -->
         <RelativeLayout
-            android:id="@+id/faceLockAreaView"
+            android:id="@+id/face_unlock_area_view"
             android:visibility="invisible"
             android:layout_width="530dip"
             android:layout_height="530dip"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
index da627b5..9a649fbb 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
@@ -157,7 +157,7 @@
 
         <!-- Area to overlay FaceLock -->
         <RelativeLayout
-            android:id="@+id/faceLockAreaView"
+            android:id="@+id/face_unlock_area_view"
             android:visibility="invisible"
             android:layout_width="440dip"
             android:layout_height="440dip"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml
index 51b946a..a71ef30 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml
@@ -126,7 +126,7 @@
 
         <!-- Area to overlay FaceLock -->
         <RelativeLayout
-            android:id="@+id/faceLockAreaView"
+            android:id="@+id/face_unlock_area_view"
             android:visibility="invisible"
             android:layout_width="530dip"
             android:layout_height="530dip"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml
index 1d6b6a9..0c4a2c7 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml
@@ -119,7 +119,7 @@
 
         <!-- Area to overlay FaceLock -->
         <RelativeLayout
-            android:id="@+id/faceLockAreaView"
+            android:id="@+id/face_unlock_area_view"
             android:visibility="invisible"
             android:layout_width="440dip"
             android:layout_height="440dip"
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
index 572c013..60f0492 100644
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ b/core/res/res/layout/keyguard_face_unlock_view.xml
@@ -17,15 +17,45 @@
 */
 -->
 
-<!-- This is the screen that shows the 9 circle unlock widget and instructs
-     the user how to unlock their device, or make an emergency call.  This
-     is the portrait layout.  -->
+<!-- This is the screen that allows the user to unlock by showing their face.  -->
 <com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/keyguard_face_unlock_view"
+    android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <!-- TODO -->
+    <include layout="@layout/keyguard_navigation"/>
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1" />
+
+    <RelativeLayout
+        android:id="@+id/face_unlock_area_view"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/face_unlock_height"
+        android:background="@drawable/intro_bg"
+        android:gravity="center">
+
+        <View
+            android:id="@+id/spotlightMask"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/facelock_spotlight_mask"
+        />
+
+        <ImageView
+            android:id="@+id/cancel_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="5dip"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentEnd="true"
+            android:src="@drawable/ic_facial_backup"
+        />
+
+    </RelativeLayout>
 
 </com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView>
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 71fb363..e0a3ce3 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -209,7 +209,7 @@
 
     <!-- Area to overlay FaceLock -->
     <RelativeLayout
-        android:id="@+id/faceLockAreaView"
+        android:id="@+id/face_unlock_area_view"
         android:visibility="invisible"
         android:layout_row="0"
         android:layout_column="2"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 486c7fe..0212f73 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -200,7 +200,7 @@
 
     <!-- Area to overlay FaceLock -->
     <RelativeLayout
-        android:id="@+id/faceLockAreaView"
+        android:id="@+id/face_unlock_area_view"
         android:visibility="invisible"
         android:layout_row="3"
         android:layout_column="0"
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index edd74e2..27f6629 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -162,7 +162,7 @@
 
     <!-- Area to overlay FaceLock -->
     <RelativeLayout
-        android:id="@+id/faceLockAreaView"
+        android:id="@+id/face_unlock_area_view"
         android:visibility="invisible"
         android:layout_row="0"
         android:layout_column="1"
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index f20cbcd..de94451 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -171,7 +171,7 @@
 
     <!-- Area to overlay FaceLock -->
     <RelativeLayout
-        android:id="@+id/faceLockAreaView"
+        android:id="@+id/face_unlock_area_view"
         android:visibility="invisible"
         android:layout_row="4"
         android:layout_column="0"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 096ff21..bba2252 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -919,6 +919,9 @@
     <!-- Set to true to add links to Cell Broadcast app from Settings and MMS app. -->
     <bool name="config_cellBroadcastAppLinks">false</bool>
 
+    <!-- The default value if the SyncStorageEngine should sync automatically or not -->
+    <bool name="config_syncstorageengine_masterSyncAutomatically">true</bool>
+
     <!--  Maximum number of supported users -->
     <integer name="config_multiuserMaximumUsers">10</integer>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 372a1ee..48c52cc 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -193,6 +193,9 @@
     <!-- Padding on left margin of PIN text entry field to center it when del button is showing -->
     <dimen name="keyguard_lockscreen_pin_margin_left">40dip</dimen>
 
+    <!-- Height of FaceUnlock widget in keyguard -->
+    <dimen name="face_unlock_height">330dip</dimen>
+
     <!-- Minimum popup width for selecting an activity in ActivityChooserDialog/ActivityChooserView. -->
     <dimen name="activity_chooser_popup_min_width">200dip</dimen>
 
diff --git a/core/res/res/values/integers.xml b/core/res/res/values/integers.xml
index 859eefc..7834997 100644
--- a/core/res/res/values/integers.xml
+++ b/core/res/res/values/integers.xml
@@ -18,4 +18,5 @@
 -->
 <resources>
     <integer name="kg_security_flip_duration">150</integer>
+    <integer name="kg_security_fade_duration">150</integer>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0f39cc6..307fc81 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -255,6 +255,7 @@
   <java-symbol type="bool" name="config_sms_capable" />
   <java-symbol type="bool" name="config_sms_utf8_support" />
   <java-symbol type="bool" name="config_swipeDisambiguation" />
+  <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
   <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
   <java-symbol type="bool" name="config_ui_enableFadingMarquee" />
   <java-symbol type="bool" name="config_use_strict_phone_number_comparation" />
@@ -1213,6 +1214,8 @@
   <java-symbol type="anim" name="dock_right_exit" />
   <java-symbol type="anim" name="keyguard_security_animate_in" />
   <java-symbol type="anim" name="keyguard_security_animate_out" />
+  <java-symbol type="anim" name="keyguard_security_fade_in" />
+  <java-symbol type="anim" name="keyguard_security_fade_out" />
   <java-symbol type="array" name="config_keyboardTapVibePattern" />
   <java-symbol type="array" name="config_longPressVibePattern" />
   <java-symbol type="array" name="config_safeModeDisabledVibePattern" />
@@ -1272,7 +1275,7 @@
   <java-symbol type="id" name="date" />
   <java-symbol type="id" name="eight" />
   <java-symbol type="id" name="emergencyCallButton" />
-  <java-symbol type="id" name="faceLockAreaView" />
+  <java-symbol type="id" name="face_unlock_area_view" />
   <java-symbol type="id" name="five" />
   <java-symbol type="id" name="forgotPatternButton" />
   <java-symbol type="id" name="four" />
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 4a75b91..c3da3bf 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -20,44 +20,43 @@
 <p>The following pie chart and table is based on the number of Android devices that have accessed
 Google Play within a 14-day period ending on the data collection date noted below.</p>
 
-<div class="col-6" style="margin-left:0">
+<div class="col-5" style="margin-left:0">
 
 
 <table>
 <tr>
   <th>Version</th>
   <th>Codename</th>
-  <th>API Level</th>
+  <th>API</th>
   <th>Distribution</th>
 </tr>
 <tr><td><a href="/about/versions/android-1.5.html">1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.2%</td></tr>
-<tr><td><a href="/about/versions/android-1.6.html">1.6</a></td><td>Donut</td>    <td>4</td><td>0.5%</td></tr>
-<tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>4.2%</td></tr>
-<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>15.5%</td></tr>
+<tr><td><a href="/about/versions/android-1.6.html">1.6</a></td><td>Donut</td>    <td>4</td><td>0.4%</td></tr>
+<tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>3.7%</td></tr>
+<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>14%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.html">2.3 - 2.3.2</a>
                                    </td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.3%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.3.html">2.3.3 - 2.3.7
-        </a></td><!-- Gingerbread -->                                       <td>10</td><td>60.3%</td></tr>
+        </a></td><!-- Gingerbread -->                                       <td>10</td><td>57.2%</td></tr>
 <tr><td><a href="/about/versions/android-3.1.html">3.1</a></td>
                                                    <td rowspan="2">Honeycomb</td>      <td>12</td><td>0.5%</td></tr>
-<tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>1.8%</td></tr> 
+<tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>1.6%</td></tr> 
 <tr><td><a href="/about/versions/android-4.0.html">4.0 - 4.0.2</a></td>
                                                 <td rowspan="2">Ice Cream Sandwich</td><td>14</td><td>0.1%</td></tr> 
 <tr><td><a href="/about/versions/android-4.0.3.html">4.0.3 - 4.0.4</a></td>
-                                                                     <!-- ICS     -->  <td>15</td><td>15.8%</td></tr> 
-<tr><td><a href="/about/versions/android-4.1.html">4.1</a></td>   <td>Jelly Bean</td><td>16</td><td>0.8%</td></tr> 
+                                                                     <!-- ICS     -->  <td>15</td><td>20.8%</td></tr> 
+<tr><td><a href="/about/versions/android-4.1.html">4.1</a></td>   <td>Jelly Bean</td><td>16</td><td>1.2%</td></tr> 
 </table>
 
-
 </div>
 
-<div class="col-7" style="margin-right:0">
+<div class="col-8" style="margin-right:0">
 <img alt=""
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x310&chd=t:0.2,0.5,4.2,15.5,0.3,60.3,0.5,1.8,0.1,15.8,0.8&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0|Android%204.0.3|Android%204.1&chco=c4df9b,6fad0c&chf=bg,s,00000000" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x245&chd=t:4.3,14,57.5,2.1,20.9,1.2&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c&chf=bg,s,00000000" />
 
 </div><!-- end dashboard-panel -->
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2012</em></p>
+<p style="clear:both"><em>Data collected during a 14-day period ending on September 4, 2012</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -82,9 +81,9 @@
 Google Play within a 14-day period ending on the date indicated on the x-axis.</p>
 
 <img alt="" height="250" width="660"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chf=bg,s,00000000&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C02/01%7C02/15%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C1%3A%7C2012%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:98.6,98.4,98.4,98.6,98.5,98.6,98.8,98.7,98.9,99.1,99.1,99.2,98.6|97.6,97.5,97.6,97.8,97.8,97.9,98.1,98.1,98.3,98.5,98.6,98.7,98.1|89.9,90.3,90.8,91.4,91.8,92.1,92.5,92.7,93.1,93.5,93.9,94.2,93.9|62.0,63.7,65.2,66.8,68.6,69.9,71.5,72.6,74.0,75.2,76.5,77.8,78.4|4.0,4.1,4.3,4.6,5.5,6.5,7.6,8.2,9.4,11.0,12.8,15.6,18.1|2.6,3.0,3.2,3.5,4.5,5.5,6.6,7.4,8.7,10.4,12.3,15.1,17.6|0.7,0.8,1.1,1.3,2.3,3.3,4.4,5.3,6.7,8.4,10.4,13.2,15.8&chm=b,c3df9b,0,1,0|b,b6dc7d,1,2,0|tAndroid%202.2,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|tAndroid%202.3.3,496c13,3,0,15,,t::-5|b,9ddb3d,3,4,0|b,91da1e,4,5,0|b,80c414,5,6,0|tAndroid%204.0.3,131d02,6,10,15,,t::-5|B,6fad0c,6,7,0&chg=7,25&chdl=Android%201.6|Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0.3&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chf=bg,s,00000000&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C1%3A%7C2012%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:97.6,97.8,97.8,97.9,98.1,98.1,98.3,98.5,98.6,98.7,98.9,98.9,99.0|90.8,91.4,91.8,92.1,92.5,92.7,93.1,93.5,93.9,94.2,94.7,94.9,95.3|65.2,66.8,68.6,69.9,71.5,72.6,74.0,75.2,76.5,77.8,79.2,80.1,81.1|4.3,4.6,5.5,6.5,7.6,8.2,9.4,11.0,12.8,15.6,18.9,21.2,23.7|3.2,3.5,4.5,5.5,6.6,7.4,8.7,10.4,12.3,15.1,18.4,20.7,23.2|1.1,1.3,2.3,3.3,4.4,5.3,6.7,8.4,10.4,13.2,16.6,19.0,21.5|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8,0.9,1.1&chm=b,c3df9b,0,1,0|tAndroid%202.2,6c9729,1,0,15,,t::-5|b,b6dc7d,1,2,0|tAndroid%202.3.3,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|b,9ddb3d,3,4,0|b,91da1e,4,5,0|tAndroid%204.0.3,253a06,5,8,15,,t::-5|b,80c414,5,6,0|B,6fad0c,6,7,0&chg=7,25&chdl=Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0.3|Android%204.1&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08" />
 
-<p><em>Last historical dataset collected during a 14-day period ending on August 1, 2012</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on September 1, 2012</em></p>
 
 
 
@@ -111,6 +110,14 @@
 
 <h2 id="Screens">Screen Sizes and Densities</h2>
 
+
+<img alt="" style="float:right;"
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.7,6.5,86,2.8" />
+
+
+<img alt="" style="float:right;clear:right"
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=ldpi%7Cmdpi%7Chdpi%7Cxhdpi&chd=t%3A1.6,18.6,53.6,26.2" />
+
 <p>This section provides data about the relative number of active devices that have a particular
 screen configuration, defined by a combination of screen size and density. To simplify the way that
 you design your user interfaces for different screen configurations, Android divides the range of
@@ -132,10 +139,7 @@
 ending on the data collection date noted below.</p>
 
 
-<div class="col-6" style="margin-left:0">
-
-
-<table>
+<table style="width:350px">
 <tr>
 <th></th>
 <th scope="col">ldpi</th>
@@ -144,22 +148,22 @@
 <th scope="col">xhdpi</th>
 </tr>
 <tr><th scope="row">small</th> 
-<td>1.5%</td>     <!-- small/ldpi -->
+<td>1.1%</td>     <!-- small/ldpi -->
 <td></td>     <!-- small/mdpi -->
-<td>1.2%</td> <!-- small/hdpi -->
+<td>1.7%</td> <!-- small/hdpi -->
 <td></td>     <!-- small/xhdpi -->
 </tr> 
 <tr><th scope="row">normal</th> 
-<td>0.5%</td>  <!-- normal/ldpi -->
-<td>12.1%</td> <!-- normal/mdpi -->
-<td>55.3%</td> <!-- normal/hdpi -->
-<td>17.4%</td>      <!-- normal/xhdpi -->
+<td>0.4%</td>  <!-- normal/ldpi -->
+<td>11.4%</td> <!-- normal/mdpi -->
+<td>51.9%</td> <!-- normal/hdpi -->
+<td>22.3%</td>      <!-- normal/xhdpi -->
 </tr> 
 <tr><th scope="row">large</th> 
 <td>0.1%</td>     <!-- large/ldpi -->
-<td>2.7%</td> <!-- large/mdpi -->
+<td>2.5%</td> <!-- large/mdpi -->
 <td></td>     <!-- large/hdpi -->
-<td>4.5%</td>     <!-- large/xhdpi -->
+<td>3.9%</td>     <!-- large/xhdpi -->
 </tr> 
 <tr><th scope="row">xlarge</th> 
 <td></td>     <!-- xlarge/ldpi -->
@@ -169,16 +173,7 @@
 </tr> 
 </table>
 
-
-</div>
-
-<div class="col-7" style="margin-right:0">
-<img alt=""
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Large%20/%20xhdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Normal%20/%20xhdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A4.7,0.1,2.7,4.5,55.3,0.5,12.1,17.4,1.2,1.5" />
-
-</div>
-
-<p style="clear:both"><em>Data collected during a 7-day period ending on August 1, 2012</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2012</em></p>
 
 
 
@@ -196,6 +191,10 @@
 support for any lower version (for example, support for version 2.0 also implies support for
 1.1).</p>
 
+
+<img alt="" style="float:right"
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1%20only|GL%202.0%20%26%201.1&chd=t%3A9.2,90.8&chf=bg,s,00000000" />
+
 <p>To declare which version of OpenGL ES your application requires, you should use the {@code
 android:glEsVersion} attribute of the <a
 href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature&gt;}</a>
@@ -209,28 +208,21 @@
 ending on the data collection date noted below.</p>
 
 
-<div class="col-6" style="margin-left:0">
-<table>
+<table style="width:350px">
 <tr>
 <th scope="col">OpenGL ES Version</th>
 <th scope="col">Distribution</th>
 </tr>
 <tr>
 <td>1.1 only</th>
-<td>9.3%</td>
+<td>9.2%</td>
 </tr>
 <tr>
 <td>2.0 &amp; 1.1</th>
-<td>90.7%</td>
+<td>90.8%</td>
 </tr>
 </table>
-</div>
-
-<div class="col-7" style="margin-right:0">
-<img alt=""
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1%20only|GL%202.0%20%26%201.1&chd=t%3A9.3,90.7&chf=bg,s,00000000" />
-
-</div>
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on August 1, 2012</em></p>
+
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2012</em></p>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 9465f18..e812ccb 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -8,7 +8,7 @@
 <ul id="nav">
   <!--  Walkthrough for Developers -- quick overview of what it's like to develop on Android -->
   <!--<li style="color:red">Overview</li> -->
-  
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/components/index.html">
         <span class="en">App Components</span>
@@ -223,7 +223,7 @@
             <li><a href="<?cs var:toroot ?>guide/topics/search/adding-custom-suggestions.html">Adding Custom Suggestions</a></li>
             <li><a href="<?cs var:toroot ?>guide/topics/search/searchable-config.html">Searchable Configuration</a></li>
           </ul>
-      </li>  
+      </li>
       <li><a href="<?cs var:toroot ?>guide/topics/ui/drag-drop.html">
           <span class="en">Drag and Drop</span>
         </a></li>
@@ -235,6 +235,9 @@
           <li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/apps.html">
               <span class="en">Making Applications Accessible</span>
             </a></li>
+          <li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/checklist.html">
+              <span class="en">Accessibility Developer Checklist</span>
+            </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/accessibility/services.html">
               <span class="en">Building Accessibility Services</span>
             </a></li>
@@ -382,9 +385,9 @@
             </a></li>
         </ul>
       </li><!-- end of location and sensors -->
-      
 
-      
+
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/connectivity/index.html">
                <span class="en">Connectivity</span>
@@ -419,10 +422,10 @@
             <span class="en">SIP</span>
           </a>
      </li>
-     
+
     </ul>
   </li><!-- end of connectivity -->
-  
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/text/index.html">
             <span class="en">Text and Input</span>
@@ -439,7 +442,7 @@
             </a></li>
         </ul>
       </li><!-- end of text and input -->
-      
+
      <li class="nav-section">
       <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/data/index.html">
           <span class="en">Data Storage</span>
@@ -457,7 +460,7 @@
       </ul>
     </li><!-- end of data storage -->
 
-  
+
   <li class="nav-section">
            <div class="nav-section-header"><a href="<?cs var:toroot?>guide/topics/admin/index.html">
                <span class="en">Administration</span>
@@ -475,7 +478,7 @@
             -->
            </ul>
   </li><!-- end of administration -->
-  
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/webapps/index.html">
     <span class="en">Web Apps</span>
@@ -498,7 +501,7 @@
           </a></li>
     </ul>
   </li><!-- end of web apps -->
-  
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/practices/index.html">
       <span class="en">Best Practices</span>
@@ -555,13 +558,13 @@
 
     </ul>
   </li>
-  
-  
+
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/google/index.html">
         <span class="en">Google Services</span>
       </a></div>
-    <ul>      
+    <ul>
 
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot?>guide/google/play/billing/index.html">
@@ -623,7 +626,7 @@
       <li><a href="<?cs var:toroot ?>guide/google/play/expansion-files.html">
           <span class="en">APK Expansion Files</span></a>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/google/gcm/index.html">
           <span class="en">Google Cloud Messaging</span></a>
@@ -649,9 +652,9 @@
 
     </ul>
   </li><!-- end Google Play -->
-  
-  
-  
+
+
+
       <!-- this needs to move
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/index.html">
@@ -691,9 +694,9 @@
               </a></div>
           </li>
         </ul>
-      </li> 
+      </li>
         </ul> -->
-        
+
 <!-- Remove
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/appendix/index.html">
@@ -710,7 +713,7 @@
       <li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
             <span class="en">Intents List: Google Apps</span>
           </a></li>
-       
+
 
       <li><a href="<?cs var:toroot ?>guide/appendix/glossary.html">
             <span class="en">Glossary</span>
diff --git a/docs/html/guide/topics/ui/accessibility/apps.jd b/docs/html/guide/topics/ui/accessibility/apps.jd
index d23512b..13b4538 100644
--- a/docs/html/guide/topics/ui/accessibility/apps.jd
+++ b/docs/html/guide/topics/ui/accessibility/apps.jd
@@ -21,14 +21,11 @@
         <li><a href="#accessibility-methods">Implementing accessibility API methods</a></li>
         <li><a href="#send-events">Sending accessibility events</a></li>
         <li><a href="#populate-events">Populating accessibility events</a></li>
+        <li><a href="#virtual-hierarchy">Providing a customized accessibility context</a></li>
+        <li><a href="#custom-touch-events">Handling custom touch events</a></li>
       </ol>
     </li>
-    <li><a href="#test">Testing Accessibility</a>
-      <ol>
-        <li><a href="#test-audibles">Testing audible feedback</a></li>
-        <li><a href="#test-navigation">Testing focus navigation</a></li>
-      </ol>
-    </li>
+    <li><a href="#test">Testing Accessibility</a></li>
   </ol>
 
   <h2>Key classes</h2>
@@ -42,60 +39,79 @@
 
   <h2>See also</h2>
   <ol>
-    <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
-    <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a>
-      </li>
-    <li><a href="{@docRoot}design/index.html">Android Design</a></li>
+    <li><a href="checklist.html">Accessibility Developer Checklist</a><li>
+    <li><a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing Checklist</a><li>
+    <li><a href="{@docRoot}design/patterns/accessibility.html">Android Design: Accessibility</a></li>
+    <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
+    <li><a href="{@docRoot}training/accessibility/index.html">Training: Implementing Accessibility</a></li>
   </ol>
 
 </div>
 </div>
 
-<p>Applications built for Android are accessible to users with visual, physical or age-related
-disabilities when they activate accessibility features and services on a device. By default,
-these services make your application more accessible. However, there are further steps you should
-take to optimize the accessibility of your application and ensure a pleasant experience for all your
-users.</p>
+<p>Applications built for Android are more accessible to users with visual, physical or age-related
+limitations when those users activate accessibility services and features on a device. These
+services make your application more accessible even if you do not make any accessibility changes
+to your code. However, there are steps you should take to optimize the accessibility of your
+application and ensure a pleasant experience for all your users.</p>
 
-<p>Making sure your application is accessible to all users is relatively easy, particularly when you
-use framework-provided user interface components. If you only use these standard components for your
-application, there are just a few steps required to ensure your application is accessible:</p>
+<p>Making sure your application is accessible to all users requires only a few steps, particularly
+when you create your user interface with the components provided by the Android framework. If you
+use only the standard components for your application, the steps are:</p>
 
 <ol>
-  <li>Label your {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link
-android.widget.EditText}, {@link android.widget.CheckBox} and other user interface controls using
-the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
-    {@code android:contentDescription}</a> attribute.</li>
-  <li>Make all of your user interface elements accessible with a directional controller,
-    such as a trackball or D-pad.</li>
-  <li>Test your application by turning on accessibility services like TalkBack and Explore by
-    Touch, and try using your application using only directional controls.</li>
+  <li>Add descriptive text to user interface controls in your application using the
+    <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+    {@code android:contentDescription}</a> attribute. Pay particular attention to
+    {@link android.widget.ImageButton}, {@link android.widget.ImageView}
+    and {@link android.widget.CheckBox}.</li>
+  <li>Make sure that all user interface elements that can accept input (touches or typing) can be
+    reached with a directional controller, such as a trackball, D-pad (physical or virtual) or
+    navigation <a href="http://support.google.com/android/bin/topic.py?hl=en&topic=2492346">gestures
+    </a>.</li>
+  <li>Make sure that audio prompts are always accompanied by another visual prompt or notification,
+    to assist users who are deaf or hard of hearing.</li>
+  <li>Test your application using only accessibility navigation services and features. Turn on
+    <a href="{@docRoot}tools/testing/testing_accessibility.html#testing-talkback">TalkBack</a> and
+    <a href="{@docRoot}tools/testing/testing_accessibility.html#testing-ebt">Explore by Touch</a>,
+    and then try using your application using only directional controls. For more information on
+    testing for accessibility, see the <a href="{@docRoot}tools/testing/testing_accessibility.html">
+    Accessibility Testing Checklist</a>.</li>
 </ol>
 
-<p>Developers who create custom controls that extend from the {@link android.view.View} class have
-some additional responsibilities for making sure their components are accessible for users. This
-document also discusses how to make custom view controls compatible with accessibility services.</p>
+<p>If you build custom controls that extend the {@link android.view.View} class, you must complete
+some additional work to make sure your components are accessible. This document discusses how to
+make custom view controls compatible with accessibility services.</p>
+
+<p class="note">
+<strong>Note:</strong> The implementation steps in this document describe the requirements for
+making your application accessible for users with blindness or low-vision. Be sure to review the
+requirements for serving users who are deaf and hard of hearing in the
+<a href="{@docRoot}guide/topics/ui/accessibility/checklist.html">Accessibility Developer
+Checklist</a></p>.
+
 
 
 <h2 id="label-ui">Labeling User Interface Elements</h2>
 
-<p>Many user interface controls rely on visual cues to inform users of their meaning. For
+<p>Many user interface controls depend on visual cues to indicate their meaning and usage. For
 example, a note-taking application might use an {@link android.widget.ImageButton} with a
-picture of a plus sign to indicate that the user can add a new note. Or, an {@link
-android.widget.EditText} component may have a label near it that indicates its purpose. When a user
-with impaired vision accesses your application, these visual cues are often useless.</p>
+picture of a plus sign to indicate that the user can add a new note. An {@link
+android.widget.EditText} component may have a label near it that indicates its purpose. A user
+with impaired vision can't see these cues well enough to follow them, which makes them useless.</p>
 
-<p>To provide textual information about interface controls (as an alternative to the visual cues),
-use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
-{@code android:contentDescription}</a> attribute. The text you provide in this attribute is not
-visible on the screen, but if a user has enabled accessibility services that provide audible
-prompts, then the description in this attribute is read aloud to the user.</p>
+<p>You can make these controls more accessible with the
+<a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+{@code android:contentDescription}</a> XML layout attribute. The text in this attribute does not
+appear on screen, but if the user enables accessibility services that provide audible prompts, then
+when the user navigates to that control, the text is spoken.</p>
 
-<p>Set the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+<p>For this reason, set the
+<a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
 {@code android:contentDescription}</a> attribute for every {@link android.widget.ImageButton},
-{@link android.widget.ImageView}, {@link android.widget.EditText}, {@link android.widget.CheckBox}
-in your application's user interface, and on any other input controls that might require additional
-information for users who are not able to see it.</p>
+{@link android.widget.ImageView}, {@link android.widget.CheckBox}
+in your application's user interface, and add descriptions to any other input controls that might
+require additional information for users who are not able to see it.</p>
 
 <p>For example, the following {@link android.widget.ImageButton} sets the content description for
 the plus button to the {@code add_note} string resource, which could be defined as “Add note" for an
@@ -108,32 +124,38 @@
     android:contentDescription=”@string/add_note”/&gt;
 </pre>
 
-<p>By including the description, speech-based accessibility services can announce "Add note" when a
-user moves focus to this button or hovers over it.</p>
+<p>By including the description, an accessibility service that provides spoken feedback can announce
+"Add note" when a user moves focus to this button or hovers over it.</p>
 
 <p class="note"><strong>Note:</strong> For {@link android.widget.EditText} fields, provide an
 <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a>
-attribute to help users understand what content is expected.</p>
+attribute <em>instead</em> of a content description, to help users understand what content is
+expected when the text field is empty. When the field is filled, TalkBack reads the entered
+content to the user, instead of the hint text.</p>
+
 
 <h2 id="focus-nav">Enabling Focus Navigation</h2>
 
 <p>Focus navigation allows users with disabilities to step through user interface controls using a
-directional controller. Directional controllers can be physical, such as a clickable trackball,
-directional pad (D-pad) or arrow keys, tab key navigation with an attached keyboard or a software
-application, such as the
+directional controller. Directional controllers can be physical, such as a trackball, directional
+pad (D-pad) or arrow keys, or virtual, such as the
 <a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin">
-Eyes-Free Keyboard</a>, that provides an on-screen directional control.</p>
+Eyes-Free Keyboard</a>, or the gestures navigation mode available in Android 4.1 and higher.
+Directional controllers are a primary means of navigation for many Android users.
+</p>
 
-<p>A directional controller is a primary means of navigation for many users.
-Verify that all user interface (UI) controls in your application are accessible
-without using the touchscreen and that clicking with the center button (or OK button) of a
-directional controller has the same effect as touching the controls on the touchscreen. For
-information on testing directional controls, see <a href="#test-navigation">Testing focus
-navigation</a>.</p>
+<p>To ensure that users can navigate your application using only a directional controller, verify
+that all user interface (UI) input controls in your application can be reached and activated
+without using the touchscreen. You should also verify that clicking with the center button (or OK
+button) of a directional controller has the same effect as touching a control that already has
+focus. For information on testing directional controls, see
+<a href="{@docRoot}tools/testing/testing_accessibility.html#test-navigation">Testing
+focus navigation</a>.</p>
+
 
 <h3 id="focus-enable">Enabling view focus</h3>
 
-<p>A user interface element is accessible using directional controls when its
+<p>A user interface element is reachable using directional controls when its
 <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
 {@code android:focusable}</a> attribute is set to {@code true}. This setting allows users to focus
 on the element using the directional controls and then interact with it. The user interface controls
@@ -149,44 +171,44 @@
   <li>{@link android.view.View#requestFocus requestFocus()}</li>
 </ul>
 
-<p>When working with a view that is not focusable by default, you can make it focusable from the XML
-layout file by setting the
-<a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
-{@code android:focusable}</a> attribute to {@code true} or by using the {@link
+<p>If a view is not focusable by default, you can make it focusable in your layout file by setting
+the <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
+{@code android:focusable}</a> attribute to {@code true} or by calling the its {@link
 android.view.View#setFocusable setFocusable()} method.</p>
 
+
 <h3 id="focus-order">Controlling focus order</h3>
 
 <p>When users navigate in any direction using directional controls, focus is passed from one
-user interface element (View) to another, as determined by the focus ordering. The ordering of the
-focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In
-rare cases, the default algorithm may not match the order that you intended for your UI. In these
-situations, you can provide explicit overrides to the ordering using the following XML attributes in
-the layout file:</p>
+user interface element (view) to another, as determined by the focus order. This order is based on
+an algorithm that finds the nearest neighbor in a given direction. In rare cases, the algorithm may
+not match the order that you intended or may not be logical for users. In these situations, you can
+provide explicit overrides to the ordering using the following XML attributes in your layout file:
+</p>
 
 <dl>
- <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
->{@code android:nextFocusDown}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates down.</dd>
- <a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft"
->{@code android:nextFocusLeft}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates left.</dd>
- <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight"
->{@code android:nextFocusRight}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates right.</dd>
- <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
->{@code android:nextFocusUp}</a></dt>
-  <dd>Defines the next view to receive focus when the user navigates up.</dd>
+  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown">
+  {@code android:nextFocusDown}</a></dt>
+    <dd>Defines the next view to receive focus when the user navigates down.</dd>
+  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft">
+  {@code android:nextFocusLeft}</a></dt>
+    <dd>Defines the next view to receive focus when the user navigates left.</dd>
+  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight">
+  {@code android:nextFocusRight}</a></dt>
+    <dd>Defines the next view to receive focus when the user navigates right.</dd>
+  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp">
+  {@code android:nextFocusUp}</a></dt>
+    <dd>Defines the next view to receive focus when the user navigates up.</dd>
 </dl>
 
-<p>The following example XML layout shows two focusable user interface elements where the <a
-href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown"
->{@code android:nextFocusDown}</a> and <a
-href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp"
->{@code android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is
+<p>The following example XML layout shows two focusable user interface elements where the
+<a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown">{@code
+android:nextFocusDown}</a> and
+<a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp">{@code
+android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is
 located to the right of the {@link android.widget.EditText}. However, since these properties have
 been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow
-when focus is on the {@link android.widget.EditText} element: </p>
+when focus is on the {@link android.widget.EditText} element:</p>
 
 <pre>
 &lt;LinearLayout android:orientation="horizontal"
@@ -218,8 +240,9 @@
 
 <ul>
   <li>Handle directional controller clicks</li>
-  <li>Implement Accessibility API methods</li>
-  <li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom view</li>
+  <li>Implement accessibility API methods</li>
+  <li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom
+    view</li>
   <li>Populate {@link android.view.accessibility.AccessibilityEvent} and {@link
     android.view.accessibility.AccessibilityNodeInfo} for your view</li>
 </ul>
@@ -243,9 +266,9 @@
 
 <p>Accessibility events are messages about users interaction with visual interface components in
 your application. These messages are handled by <a href="services.html">Accessibility Services</a>,
-which use the information in these events to produce supplemental feedback and prompts when users
-have enabled accessibility services. As of Android 4.0 (API Level 14) and higher, the methods for
-generating accessibility events have been expanded to provide more detailed information beyond the
+which use the information in these events to produce supplemental feedback and prompts. In
+Android 4.0 (API Level 14) and higher, the methods for
+generating accessibility events have been expanded to provide more detailed information than the
 {@link android.view.accessibility.AccessibilityEventSource} interface introduced in Android 1.6 (API
 Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well
 as the {@link android.view.View.AccessibilityDelegate} class. The methods are as follows:</p>
@@ -262,12 +285,12 @@
   <dd>(API Level 4) This method is used when the calling code needs to directly control the check
 for accessibility being enabled on the device ({@link
 android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If
-you do implement this method, you must assume that the calling method has already checked that
-accessibility is enabled and the result is {@code true}. You typically do not need to implement this
-method for a custom view.</dd>
+you do implement this method, you must perform the call as if accessibility is enabled, regardless
+of the actual system setting. You typically do not need to implement this method for a custom view.
+</dd>
 
   <dt>{@link android.view.View#dispatchPopulateAccessibilityEvent
-dispatchPopulateAccessibilityEvent()} </dt>
+dispatchPopulateAccessibilityEvent()}</dt>
   <dd>(API Level 4) The system calls this method when your custom view generates an
 accessibility event. As of API Level 14, the default implementation of this method calls {@link
 android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and
@@ -276,21 +299,21 @@
 accessibility services on revisions of Android <em>prior</em> to 4.0 (API Level 14) you
 <em>must</em> override this method and populate {@link
 android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom
-view.</dd>
+view, which is spoken by accessibility services, such as TalkBack.</dd>
 
   <dt>{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}</dt>
-  <dd>(API Level 14) This method sets the text output of an {@link
+  <dd>(API Level 14) This method sets the spoken text prompt of the {@link
 android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the
 view is a child of a view which generates an accessibility event.
 
   <p class="note"><strong>Note:</strong> Modifying additional attributes beyond the text within
-this method potentially overwrites properties set by other methods. So, while you are able modify
+this method potentially overwrites properties set by other methods. While you can modify
 attributes of the accessibility event with this method, you should limit these changes
-to text content only and use the {@link android.view.View#onInitializeAccessibilityEvent
+to text content, and use the {@link android.view.View#onInitializeAccessibilityEvent
 onInitializeAccessibilityEvent()} method to modify other properties of the event.</p>
 
-  <p class="note"><strong>Note:</strong> If your implementation of this event calls for completely
-overiding the output text without allowing other parts of your layout to modify its content, then
+  <p class="note"><strong>Note:</strong> If your implementation of this event completely
+overrides the output text without allowing other parts of your layout to modify its content, then
 do not call the super implementation of this method in your code.</p>
   </dd>
 
@@ -306,7 +329,7 @@
   <dt>{@link android.view.View#onInitializeAccessibilityNodeInfo
 onInitializeAccessibilityNodeInfo()}</dt>
   <dd>(API Level 14) This method provides accessibility services with information about the state of
-the view. The default {@link android.view.View} implementation sets a standard set of view
+the view. The default {@link android.view.View} implementation has a standard set of view
 properties, but if your custom view provides interactive control beyond a simple {@link
 android.widget.TextView} or {@link android.widget.Button}, you should override this method and set
 the additional information about your view into the {@link
@@ -315,7 +338,7 @@
   <dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent
 onRequestSendAccessibilityEvent()}</dt>
   <dd>(API Level 14) The system calls this method when a child of your view has generated an
-{@link android.view.accessibility.AccessibilityEvent}. This step allows the the parent view to amend
+{@link android.view.accessibility.AccessibilityEvent}. This step allows the parent view to amend
 the accessibility event with additional information. You should implement this method only if your
 custom view can have child views and if the parent view can provide context information to the
 accessibility event that would be useful to accessibility services.</dd>
@@ -333,7 +356,7 @@
 {@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
 ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods
 above. For an example of this approach, see the Android Support Library (revision 5 or higher)
-sample {@code AccessibilityDelegateSupportActivity} in 
+sample {@code AccessibilityDelegateSupportActivity} in
 ({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/})
   </li>
 </ul>
@@ -446,20 +469,20 @@
 }
 </pre>
 
-<p>On Android 4.0 (API Level 14) and higher, the {@link
+<p>For Android 4.0 (API Level 14) and higher, use the {@link
 android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
-methods are the recommended way to populate or modify the information in an {@link
-android.view.accessibility.AccessibilityEvent}. Use the 
+methods to populate or modify the information in an {@link
+android.view.accessibility.AccessibilityEvent}. Use the
 {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method
 specifically for adding or modifying the text content of the event, which is turned into audible
 prompts by accessibility services such as TalkBack. Use the
 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for
 populating additional information about the event, such as the selection state of the view.</p>
 
-<p>In addition, you should also implement the
+<p>In addition, implement the
 {@link android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()}
-method. {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
+method. The {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
 are used by accessibility services to investigate the view hierarchy that generated an accessibility
 event after receiving that event, to obtain a more detailed context information and provide
 appropriate feedback to users.</p>
@@ -467,8 +490,8 @@
 <p>The example code below shows how override these three methods by using
 {@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
 ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android
-<a href="{@docRoot}tools/extras/support-library.html">Support Library</a> for API Level 4 (revision 5
-or higher) is added to your project.</p>
+<a href="{@docRoot}tools/extras/support-library.html">Support Library</a> for API Level 4 (revision
+5 or higher) is added to your project.</p>
 
 <pre>
 ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() {
@@ -509,10 +532,10 @@
 }
 </pre>
 
-<p>On applications targeting Android 4.0 (API Level 14) and higher, these methods can be implemented
+<p>In applications targeting Android 4.0 (API Level 14) and higher, you can implement these methods
 directly in your custom view class. For another example of this approach, see the Android
-<a href="{@docRoot}tools/extras/support-library.html">Support Library</a> (revision 5 or higher) sample
-{@code AccessibilityDelegateSupportActivity} in 
+<a href="{@docRoot}tools/extras/support-library.html">Support Library</a> (revision 5 or higher)
+sample {@code AccessibilityDelegateSupportActivity} in
 ({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/}).</p>
 
 <p class="note"><strong>Note:</strong> You may find information on implementing accessibility for
@@ -525,50 +548,141 @@
 methods.</p>
 
 
+<h3 id="virtual-hierarchy">Providing a customized accessibility context</h3>
+
+<p>In Android 4.0 (API Level 14), the framework was enhanced to allow accessibility services to
+  inspect the containing view hierarchy of a user interface component that generates an
+  accessibility event. This enhancement allows accessibility services to provide a much richer set
+  of contextual information with which to aid users.</p>
+
+<p>There are some cases where accessibility services cannot get adequate information
+  from the view hierarchy. An example of this is a custom interface control that has two or more
+  separately clickable areas, such as a calendar control. In this case, the services cannot get
+  adequate information because the clickable subsections are not part of the view hierarchy.</p>
+
+<img src="calendar.png" alt="" id="figure1" />
+<p class="img-caption">
+  <strong>Figure 1.</strong> A custom calendar view with selectable day elements.
+</p>
+
+<p>In the example shown in Figure 1, the entire calendar is implemented as a single view, so if you
+  do not do anything else, accessibility services do not receive enough information about the
+  content of the view and the user's selection within the view. For example, if a user clicks on the
+  day containing <strong>17</strong>, the accessibility framework only receives the description
+  information for the whole calendar control. In this case, the TalkBack accessibility service would
+  simply announce "Calendar" or, only slightly better, "April Calendar" and the user would be left
+  to wonder what day was selected.</p>
+
+<p>To provide adequate context information for accessibility services in situations like this,
+  the framework provides a way to specify a virtual view hierarchy. A <em>virtual view
+  hierarchy</em> is a way for application developers to provide a complementary view hierarchy
+  to accessibility services that more closely matches the actual information on screen. This
+  approach allows accessibility services to provide more useful context information to users.</p>
+
+<p>Another situation where a virtual view hierarchy may be needed is a user interface containing
+  a set of controls (views) that have closely related functions, where an action on one control
+  affects the contents of one or more elements, such as a number picker with separate up and down
+  buttons. In this case, accessibility services cannot get adequate information because action on
+  one control changes content in another and the relationship of those controls may not be apparent
+  to the service. To handle this situation, group the related controls with a containing view and
+  provide a virtual view hierarchy from this container to clearly represent the information and
+  behavior provided by the controls.</p>
+
+<p>In order to provide a virtual view hierarchy for a view, override the {@link
+  android.view.View#getAccessibilityNodeProvider} method in your custom view or view group and
+  return an implementation of {@link android.view.accessibility.AccessibilityNodeProvider}. For an
+  example implementation of this accessibility feature, see
+  {@code AccessibilityNodeProviderActivity} in the ApiDemos sample project. You can implement a
+  virtual view hierarchy that is compatible with Android 1.6 and later by using the
+  <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> with the
+  {@link android.support.v4.view.ViewCompat#getAccessibilityNodeProvider
+  ViewCompat.getAccessibilityNodeProvider()} method and providing an implementation with
+  {@link android.support.v4.view.accessibility.AccessibilityNodeProviderCompat}.</p>
+
+
+<h3 id="custom-touch-events">Handling custom touch events</h3>
+
+<p>Custom view controls may require non-standard touch event behavior. For example, a custom
+control may use the {@link android.view.View#onTouchEvent} listener method to detect the
+{@link android.view.MotionEvent#ACTION_DOWN} and {@link android.view.MotionEvent#ACTION_UP} events
+and trigger a special click event. In order to maintain compatibility with accessibility services,
+the code that handles this custom click event must do the following:</p>
+
+<ol>
+  <li>Generate an appropriate {@link android.view.accessibility.AccessibilityEvent} for the
+  interpreted click action.</li>
+  <li>Enable accessibility services to perform the custom click action for users who are not able to
+   use a touch screen.</li>
+</ol>
+
+<p>To handle these requirements in an efficient way, your code should override the
+{@link android.view.View#performClick} method, which must call the super implementation of this
+method and then execute whatever actions are required by the click event. When the custom click
+action is detected, that code should then call your {@code performClick()} method. The following
+code example demonstrates this pattern.</p>
+
+<pre>
+class CustomTouchView extends View {
+
+    public CustomTouchView(Context context) {
+        super(context);
+    }
+
+    boolean mDownTouch = false;
+
+    &#64;Override
+    public boolean onTouchEvent(MotionEvent event) {
+        super.onTouchEvent(event);
+
+        // Listening for the down and up touch events
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mDownTouch = true;
+                return true;
+
+            case MotionEvent.ACTION_UP:
+                if (mDownTouch) {
+                    mDownTouch = false;
+                    performClick(); // Call this method to handle the response, and
+                                    // thereby enable accessibility services to
+                                    // perform this action for a user who cannot
+                                    // click the touchscreen.
+                    return true;
+                }
+        }
+        return false; // Return false for other touch events
+    }
+
+    &#64;Override
+    public boolean performClick() {
+        // Calls the super implementation, which generates an AccessibilityEvent
+        // and calls the onClick() listener on the view, if any
+        super.performClick();
+
+        // Handle the action for the custom click here
+
+        return true;
+    }
+}
+</pre>
+
+<p>The pattern shown above makes sure that the custom click event is compatible with
+accessibility services by using the {@link android.view.View#performClick} method to both generate
+an accessibility event and provide an entry point for accessibility services to act on behalf of a
+user to perform this custom click event.</p>
+
+<p class="note"><strong>Note:</strong> If your custom view has distinct clickable regions, such as
+a custom calendar view, you must implement a <a href="#virtual-hierarchy">virtual view
+hierarchy</a> by overriding {@link android.view.View#getAccessibilityNodeProvider} in your custom
+view in order to be compatible with accessibility services.</p>
+
+
 <h2 id="test">Testing Accessibility</h2>
 
 <p>Testing the accessibility of your application is an important part of ensuring your users have a
-great experience. You can test the most important parts of accessibility by testing your application
-with audible feedback enabled and testing navigation within your application using directional
-controls.</p>
+great experience. You can test the most important accessibility features by using your application
+with audible feedback enabled and navigating within your application using only directional
+controls. For more information on testing accessibility in your application, see the
+<a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing Checklist</a>.
+</p>
 
-<h3 id="test-audibles">Testing audible feedback</h3>
-<p>You can simulate the experience for many users by enabling an accessibility service that speaks
-as you move around the screen. The Explore by Touch accessibility service, which is available on
-devices with Android 4.0 and later. The <a
-href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a>
-accessibility service, by the <a href="http://code.google.com/p/eyes-free/">Eyes-Free
-Project</a> comes preinstalled on many Android devices.</p>
-
-<p>To enable TalkBack on revisions of Android prior to Android 4.0:</p>
-<ol>
-  <li>Launch the Settings application.</li>
-  <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
-  <li>Select <strong>Accessibility</strong> to enable it.</li>
-  <li>Select <strong>TalkBack</strong> to enable it.</li>
-</ol>
-
-<p class="note"><strong>Note:</strong> If the TalkBack accessibility service is not available, you
-can install it for free from <a href="http://play.google.com">Google Play</a>.</p>
-
-<p>To enable Explore by Touch on Android 4.0 and later:</p>
-<ol>
-  <li>Launch the Settings application.</li>
-  <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
-  <li>Select the <strong>TalkBack</strong> to enable it.</li>
-  <li>Return to the <strong>Accessibility</strong> category and select <strong>Explore by
-Touch</strong> to enable it.
-    <p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this
-option is not available.</p>
-  </li>
-</ol>
-
-<h3 id="test-navigation">Testing focus navigation</h3>
-
-<p>As part of your accessibility testing, you can test navigation of your application using focus,
-even if your test devices does not have a directional controller. The <a
-href="{@docRoot}tools/help/emulator.html">Android Emulator</a> provides a
-simulated directional controller that you can easily use to test navigation. You can also use a
-software-based directional controller, such as the one provided by the
-<a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin">
-Eyes-Free Keyboard</a> to simulate use of a D-pad.</p>
diff --git a/docs/html/guide/topics/ui/accessibility/calendar.png b/docs/html/guide/topics/ui/accessibility/calendar.png
new file mode 100644
index 0000000..ca5c44f
--- /dev/null
+++ b/docs/html/guide/topics/ui/accessibility/calendar.png
Binary files differ
diff --git a/docs/html/guide/topics/ui/accessibility/checklist.jd b/docs/html/guide/topics/ui/accessibility/checklist.jd
new file mode 100644
index 0000000..9473d1b
--- /dev/null
+++ b/docs/html/guide/topics/ui/accessibility/checklist.jd
@@ -0,0 +1,173 @@
+page.title=Accessibility Developer Checklist
+parent.title=Accessibility
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>In this document</h2>
+  <ol>
+    <li><a href="#requirements">Accessibility Requirements</a></li>
+    <li><a href="#recommendations">Accessibility Recommendations</a></li>
+    <li><a href="#special-cases">Special Cases and Considerations</a></li>
+  </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}design/patterns/accessibility.html">Android Design: Accessibility</a></li>
+    <li><a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing Checklist</a></li>
+    <li><a href="{@docRoot}training/accessibility/index.html">Training: Implementing Accessibility</a></li>
+    <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
+  </ol>
+
+</div>
+</div>
+
+<p>Making an application accessible is about a deep commitment to usability, getting the
+details right and delighting your users. This document provides a checklist of accessibility
+requirements, recommendations and considerations to help you make sure your application is
+accessible. Following this checklist does not guarantee your application is accessible, but it's a
+good place to start.</p>
+
+<p>Creating an accessible application is not just the responsibility of developers. Involve your
+design and testing folks as well, and make them are aware of the guidelines for these other stages
+of development:</p>
+
+<ul>
+  <li><a href="{@docRoot}design/patterns/accessibility.html">Android Design: Accessibility</a></li>
+  <li><a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing
+    Checklist</a></li>
+</ul>
+
+<p>In most cases, creating an accessible Android application does not require extensive code
+restructuring. Rather, it means working through the subtle details of how users interact with your
+application, so you can provide them with feedback they can sense and understand. This checklist
+helps you focus on the key development issues to get the details of accessibility right.</p>
+
+
+<h2 id="requirements">Accessibility Requirements</h2>
+
+<p>The following steps must be completed in order to ensure a minimum level of application
+  accessibility.</p>
+
+<ol>
+  <li><strong>Describe user interface controls:</strong> Provide content
+    <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#label-ui">descriptions</a> for user
+    interface components that do not have visible text, particularly
+    {@link android.widget.ImageButton}, {@link android.widget.ImageView}
+    and {@link android.widget.CheckBox} components. Use the
+    <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+    {@code android:contentDescription}</a> XML layout attribute or the {@link
+    android.view.View#setContentDescription} method to provide this information for accessibility
+    services. (Exception: <a href="#decorative">decorative graphics</a>)</li>
+  <li><strong>Enable focus-based navigation:</strong> Make sure
+    <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#focus-nav">users can navigate</a>
+    your screen layouts using hardware-based or software directional controls (D-pads, trackballs,
+    keyboards and navigation gestures). In a few cases, you may need to make user interface components
+    <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">focusable</a>
+    or change the <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#focus-order">focus
+    order</a> to be more logical for user actions.</li>
+  <li><strong>Custom view controls:</strong> If you build
+    <a href="{@docRoot}guide/topics/ui/custom-components.html">custom interface controls</a> for
+    your application, <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#custom-views">
+    implement accessibility interfaces</a> for your custom views and provide content descriptions.
+    For custom controls that are intended to be compatible with versions of Android back to 1.6,
+    use the <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> to implement
+    the latest accessibility features.</li>
+  <li><strong>No audio-only feedback:</strong> Audio feedback must always have a secondary
+    feedback mechanism to support users who are deaf or hard of hearing. For example, a sound alert
+    for the arrival of a message must be accompanied by a system
+    {@link android.app.Notification}, haptic feedback (if available) or other visual alert.</li>
+  <li><strong>Test:</strong> Test accessibility by navigating your application
+    using directional controls, and using eyes-free navigation with TalkBack enabled.
+    For more accessibility testing information, see the
+    <a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing
+    Checklist</a>.</li>
+</ol>
+
+
+<h2 id="recommendations">Accessibility Recommendations</h2>
+
+<p>The following steps are recommended for ensuring the accessibility of your application. If you
+  do not take these actions, it may impact the overall accessibility and quality of your
+  application.</p>
+
+<ol>
+  <li><strong>Android Design Accessibility Guidelines:</strong> Before building your layouts,
+    review and follow the accessibility guidelines provided in the
+    <a href="{@docRoot}design/patterns/accessibility.html">Design guidelines</a>.</li>
+  <li><strong>Framework-provided controls:</strong> Use Android's built-in user interface
+    controls whenever possible, as these components provide accessibility support by default.</li>
+  <li><strong>Temporary or self-hiding controls and notifications:</strong> Avoid having user
+    interface controls that fade out or disappear after a certain amount of time. If this behavior
+    is important to your application, provide an alternative interface for these functions.</li>
+</ol>
+
+
+<h2 id="special-cases">Special Cases and Considerations</h2>
+
+<p>The following list describes specific situations where action should be taken to ensure an
+  accessible app. Review this list to see if any of these special cases and considerations apply to
+  your application, and take the appropriate action.</p>
+
+<ol>
+  <li><strong>Text field hints:</strong> For {@link android.widget.EditText} fields, provide an
+    <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a>
+    attribute <em>instead</em> of a content description, to help users understand what content is
+    expected when the text field is empty and allow the contents of the field to be spoken when
+    it is filled.</li>
+  <li><strong>Custom controls with high visual context:</strong> If your application contains a
+    <a href="{@docRoot}guide/topics/ui/custom-components.html">custom control</a> with a high degree
+    of visual context (such as a calendar control), default accessibility services processing may
+    not provide adequate descriptions for users, and you should consider providing a
+    <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#virtual-hierarchy">virtual
+    view hierarchy</a> for your control using
+    {@link android.view.accessibility.AccessibilityNodeProvider}.</li>
+  <li><strong>Custom controls and click handling:</strong> If a custom control in your
+    application performs specific handling of user touch interaction, such as listening with
+    {@link android.view.View#onTouchEvent} for {@link android.view.MotionEvent#ACTION_DOWN
+    MotionEvent.ACTION_DOWN} and {@link android.view.MotionEvent#ACTION_UP MotionEvent.ACTION_UP}
+    and treating it as a click event, you must trigger an {@link
+    android.view.accessibility.AccessibilityEvent} equivalent to a click and provide a way for
+    accessibility services to perform this action for users. For more information, see
+    <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#custom-touch-events">Handling custom
+    touch events</a>.</li>
+  <li><strong>Controls that change function:</strong> If you have buttons or other controls
+    that change function during the normal activity of a user in your application (for example, a
+    button that changes from <strong>Play</strong> to <strong>Pause</strong>), make sure you also
+    change the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+    {@code android:contentDescription}</a> of the button appropriately.</li>
+  <li><strong>Prompts for related controls:</strong> Make sure sets of controls which provide a
+    single function, such as the {@link android.widget.DatePicker}, provide useful audio feedback
+    when an user interacts with the individual controls.</li>
+  <li><strong>Video playback and captioning:</strong> If your application provides video
+    playback, it must support captioning and subtitles to assist users who are deaf or hard of
+    hearing. Your video playback controls must also clearly indicate if captioning is available for
+    a video and provide a clear way of enabling captions.</li>
+  <li><strong>Supplemental accessibility audio feedback:</strong> Use only the Android accessibility
+    framework to provide accessibility audio feedback for your app. Accessibility services such as
+    <a href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback"
+    >TalkBack</a> should be the only way your application provides accessibility audio prompts to
+    users. Provide the prompting information with a
+    <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code
+    android:contentDescription}</a> XML layout attribute or dynamically add it using accessibility
+    framework APIs. For example, if your application takes action that you want to announce to a
+    user, such as automatically turning the page of a book, use the {@link
+    android.view.View#announceForAccessibility} method to have accessibility services speak this
+    information to the user.</li>
+  <li><strong>Custom controls with complex visual interactions:</strong> For custom controls that
+    provide complex or non-standard visual interactions, provide a
+    <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#virtual-hierarchy">virtual view
+    hierarchy</a> for your control using {@link android.view.accessibility.AccessibilityNodeProvider}
+    that allows accessibility services to provide a simplified interaction model for the user. If
+    this approach is not feasible, consider providing an alternate view that is accessible.</li>
+  <li><strong>Sets of small controls:</strong> If you have controls that are smaller than
+    the minimum recommended touch size in your application screens, consider grouping these controls
+    together using a {@link android.view.ViewGroup} and providing a
+    <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code
+    android:contentDescription}</a> for the group.</li>
+  <li id="decorative"><strong>Decorative images and graphics:</strong> Elements in application
+    screens that are purely decorative and do not provide any content or enable a user action should
+    not have accessibility content descriptions.</li>
+</ol>
diff --git a/docs/html/guide/topics/ui/accessibility/index.jd b/docs/html/guide/topics/ui/accessibility/index.jd
index 6fd71e2..6cdbde4 100644
--- a/docs/html/guide/topics/ui/accessibility/index.jd
+++ b/docs/html/guide/topics/ui/accessibility/index.jd
@@ -8,47 +8,67 @@
 
   <h2>Topics</h2>
   <ol>
-  <li><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>
-    </li>
-  <li><a href="{@docRoot}guide/topics/ui/accessibility/services.html">Building Accessibility
-    Services</a></li>
+  <li><a href="apps.html">
+    Making Applications Accessible</a></li>
+  <li><a href="checklist.html">
+    Accessibility Developer Checklist</a></li>
+  <li><a href="services.html">
+    Building Accessibility Services</a></li>
   </ol>
 
-  <h2>Key classes</h2>
-  <ol>
-    <li>{@link android.view.accessibility.AccessibilityEvent}</li>
-    <li>{@link android.accessibilityservice.AccessibilityService}</li>
-  </ol>
-  
   <h2>See also</h2>
   <ol>
-    <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
+    <li><a href="{@docRoot}design/patterns/accessibility.html">Android Design: Accessibility</a></li>
+    <li><a href="{@docRoot}training/accessibility/index.html">Training: Implementing Accessibility</a></li>
+    <li><a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing Checklist</a></li>
+  </ol>
+
+  <h2>Related Videos</h2>
+  <ol>
+    <li>
+      <iframe title="Google I/O 2012 - Making Android Apps Accessible"
+          width="210" height="160"
+          src="http://www.youtube.com/embed/q3HliaMjL38?rel=0&amp;hd=1"
+          frameborder="0" allowfullscreen>
+      </iframe>
+    <li>
   </ol>
 
 </div>
 </div>
 
-<p>Many Android users have disabilities that require them to interact with their Android devices in
-different ways. These include users who have visual, physical or age-related disabilities that
-prevent them from fully seeing or using a touchscreen.</p>
+<p>Many Android users have different abilities that require them to interact with their Android
+devices in different ways. These include users who have visual, physical or age-related limitations
+that prevent them from fully seeing or using a touchscreen, and users with hearing loss who may not
+be able to perceive audible information and alerts.</p>
 
 <p>Android provides accessibility features and services for helping these users navigate their
-devices more easily, including text-to-speech, haptic feedback, trackball and D-pad navigation that
-augment their experience. Android application developers can take advantage of these services to
-make their applications more accessible and also build their own accessibility services.</p>
+devices more easily, including text-to-speech, haptic feedback, gesture navigation, trackball and
+directional-pad navigation. Android application developers can take advantage of these services to
+make their applications more accessible.</p>
+
+<p>Android developers can also build their own accessibility services, which can provide
+enhanced usability features such as audio prompting, physical feedback, and alternative navigation
+modes. Accessibility services can provide these enhancements for all applications, a set of
+applications or just a single app.</p>
 
 <p>The following topics show you how to use the Android framework to make applications more
 accessible.</p>
 
 <dl>
-  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications
-Accessible</a></strong>
+  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/apps.html">
+  Making Applications Accessible</a></strong>
   </dt>
   <dd>Development practices and API features to ensure your application is accessible to users with
 disabilities.</dd>
 
-  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/services.html">Building Accessibility
-Services</a></strong>
+  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/checklist.html">
+  Accessibility Developer Checklist</a></strong>
+  </dt>
+  <dd>A checklist to help developers ensure that their applications are accessible.</dd>
+
+  <dt><strong><a href="{@docRoot}guide/topics/ui/accessibility/services.html">
+  Building Accessibility Services</a></strong>
   </dt>
   <dd>How to use API features to build services that make other applications more accessible for
 users.</dd>
diff --git a/docs/html/guide/topics/ui/accessibility/services.jd b/docs/html/guide/topics/ui/accessibility/services.jd
index 7d36181..2a6fe7a 100644
--- a/docs/html/guide/topics/ui/accessibility/services.jd
+++ b/docs/html/guide/topics/ui/accessibility/services.jd
@@ -14,8 +14,16 @@
         <li><a href="#service-config">Accessibility service configuration</a></li>
       </ol>
     </li>
+    <li><a href="#register">Registering for Accessibility Events</a></li>
     <li><a href="#methods">AccessibilityService Methods</a></li>
     <li><a href="#event-details">Getting Event Details</a></li>
+    <li><a href="#act-for-users">Taking Action for Users</a>
+      <ol>
+        <li><a href="#detect-gestures">Listening for gestures</a></li>
+        <li><a href="#using-actions">Using accessibility actions</a></li>
+        <li><a href="#focus-types">Using focus types</a></li>
+      </ol>
+    </li>
     <li><a href="#examples">Example Code</a></li>
   </ol>
 
@@ -30,7 +38,7 @@
 
   <h2>See also</h2>
   <ol>
-    <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li>
+    <li><a href="{@docRoot}training/accessibility/index.html">Training: Implementing Accessibility</a></li>
   </ol>
 
 </div>
@@ -45,20 +53,20 @@
 create and distribute their own services. This document explains the basics of building an
 accessibility service.</p>
 
-<p>The ability for you to build and deploy accessibility services was introduced with Android
-1.6 (API Level 4) and received significant improvements with Android 4.0 (API Level 14). The Android
-Support Library was also updated with the release of Android 4.0 to provide support for these
-enhanced accessibility features back to Android 1.6. Developers aiming for widely compatible
-accessibility services are encouraged to use the
-<a href="{@docRoot}tools/extras/support-library.html">Support Library</a> and develop for the more
-advanced accessibility features introduced in Android 4.0.</p>
+<p>The ability for you to build and deploy accessibility services was introduced with Android 1.6
+  (API Level 4) and received significant improvements with Android 4.0 (API Level 14). The Android
+  <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> was also updated with
+  the release of Android 4.0 to provide support for these enhanced accessibility features back to
+  Android 1.6. Developers aiming for widely compatible accessibility services are encouraged to use
+  the Support Library and develop for the more advanced accessibility features introduced in
+  Android 4.0.</p>
 
 
 <h2 id="manifest">Manifest Declarations and Permissions</h2>
 
 <p>Applications that provide accessibility services must include specific declarations in their
- application manifests in order to be treated as an accessibility service by an Android system.
- This section explains the required and optional settings for accessibility services.</p>
+ application manifests to be treated as an accessibility service by the Android system. This
+ section explains the required and optional settings for accessibility services.</p>
 
 
 <h3 id="service-declaration">Accessibility service declaration</h3>
@@ -66,7 +74,9 @@
 <p>In order to be treated as an accessibility service, your application must include the
 {@code service} element (rather than the {@code activity} element) within the {@code application}
 element in its manifest. In addition, within the {@code service} element, you must also include an
-accessibility service intent filter, as shown in the following sample:</p>
+accessibility service intent filter. For compatiblity with Android 4.1 and higher, the manifest
+must also request the {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission
+as shown in the following sample:</p>
 
 <pre>
 &lt;application&gt;
@@ -76,6 +86,7 @@
       &lt;action android:name=&quot;android.accessibilityservice.AccessibilityService&quot; /&gt;
     &lt;/intent-filter&gt;
   &lt;/service&gt;
+  &lt;uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /&gt;
 &lt;/application&gt;
 </pre>
 
@@ -123,27 +134,6 @@
 /&gt;
 </pre>
 
-<p>One of the most important functions of the accessibility service configuration parameters is to
-allow you to specify what types of accessibility events your service can handle. Being able to
-specify this information enables accessibility services to cooperate with each other, and allows you
-as a developer the flexibility to handle only specific events types from specific applications. The
-event filtering can include the following criteria:</p>
-
-<ul>
-  <li><strong>Package Names</strong> - Specify the package names of applications whose accessibility
-events you want your service to handle. If this parameter is omitted, your accessibility service is
-considered available to service accessibility events for any application. This parameter can be set
-in the accessibility service configuration files with the {@code android:packageNames} attribute as
-a comma-separated list, or set using the {@link
-android.accessibilityservice.AccessibilityServiceInfo#packageNames
-AccessibilityServiceInfo.packageNames} member.</li>
-  <li><strong>Event Types</strong> - Specify the types of accessibility events you want your service
-to handle. This parameter can be set in the accessibility service configuration files with the
-{@code android:accessibilityEventTypes} attribute as a comma-separated list, or set using the
-{@link android.accessibilityservice.AccessibilityServiceInfo#eventTypes
-AccessibilityServiceInfo.eventTypes} member. </li>
-</ul>
-
 <p>For more information about the XML attributes which can be used in the accessibility service
  configuration file, follow these links to the reference documentation:</p>
 
@@ -162,9 +152,45 @@
 the {@link android.accessibilityservice.AccessibilityServiceInfo} reference documentation.</p>
 
 
+<h2 id="register">Registering for Accessibility Events</h2>
+
+<p>One of the most important functions of the accessibility service configuration parameters is to
+allow you to specify what types of accessibility events your service can handle. Being able to
+specify this information enables accessibility services to cooperate with each other, and allows you
+as a developer the flexibility to handle only specific events types from specific applications. The
+event filtering can include the following criteria:</p>
+
+<ul>
+  <li><strong>Package Names</strong> - Specify the package names of applications whose accessibility
+events you want your service to handle. If this parameter is omitted, your accessibility service is
+considered available to service accessibility events for any application. This parameter can be set
+in the accessibility service configuration files with the {@code android:packageNames} attribute as
+a comma-separated list, or set using the {@link
+android.accessibilityservice.AccessibilityServiceInfo#packageNames
+AccessibilityServiceInfo.packageNames} member.</li>
+  <li><strong>Event Types</strong> - Specify the types of accessibility events you want your service
+to handle. This parameter can be set in the accessibility service configuration files with the
+{@code android:accessibilityEventTypes} attribute as a list separated by the {@code |} character
+(for example {@code accessibilityEventTypes="typeViewClicked|typeViewFocused"}), or set using the
+{@link android.accessibilityservice.AccessibilityServiceInfo#eventTypes
+AccessibilityServiceInfo.eventTypes} member. </li>
+</ul>
+
+<p>When setting up your accessibility service, carefully consider what events your service is able
+to handle and only register for those events. Since users can activate more than one accessibility
+services at a time, your service must not consume events that it is not able to handle. Remember
+that other services may handle those events in order to improve a user's experience.</p>
+
+<p class="note"><strong>Note:</strong> The Android framework dispatches accessibility events to
+more than one accessibility service if the services provide different
+<a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_accessibilityFeedbackType">
+feedback types</a>. However, if two or more services provide the same feedback type, then only the
+first registered service receives the event.</p>
+
+
 <h2 id="methods">AccessibilityService Methods</h2>
 
-<p>An application that provides accessibility service must extend the {@link
+<p>An accessibility service must extend the {@link
 android.accessibilityservice.AccessibilityService} class and override the following methods from
 that class. These methods are presented in the order in which they are called by the Android system,
 from when the service is started
@@ -188,15 +214,15 @@
 {@link android.view.accessibility.AccessibilityEvent} that matches the event filtering parameters
 specified by your accessibility service. For example, when the user clicks a button or focuses on a
 user interface control in an application for which your accessibility service is providing feedback.
-When this happens, the system calls this method of your service with the associated {@link
-android.view.accessibility.AccessibilityEvent}, which you can then interpret and provide feedback to
-the user. This method may be called many times over the lifecycle of your service.</li>
+When this happens, the system calls this method, passing the associated {@link
+android.view.accessibility.AccessibilityEvent}, which the service can then interpret and use to
+provide feedback to the user. This method may be called many times over the lifecycle of your
+service.</li>
 
   <li>{@link android.accessibilityservice.AccessibilityService#onInterrupt onInterrupt()} -
 (required) This method is called when the system wants to interrupt the feedback your service is
-providing, usually in response to a user taking action, such as moving focus to a different user
-interface control than the one for which you are currently providing feedback. This method may be
-called many times over the lifecycle of your service.</li>
+providing, usually in response to a user action such as moving focus to a different control. This
+method may be called many times over the lifecycle of your service.</li>
 
   <li>{@link android.accessibilityservice.AccessibilityService#onUnbind onUnbind()} - (optional)
 This method is called when the system is about to shutdown the accessibility service. Use this
@@ -206,7 +232,9 @@
 
 <p>These callback methods provide the basic structure for your accessibility service. It is up to
 you to decide on how to process data provided by the Android system in the form of {@link
-android.view.accessibility.AccessibilityEvent} objects and provide feedback to the user.</p>
+android.view.accessibility.AccessibilityEvent} objects and provide feedback to the user. For more
+information about getting information from an accessibility event, see the
+<a href="{@docRoot}training/accessibility/service.html">Implementing Accessibility</a> training.</p>
 
 
 <h2 id="event-details">Getting Event Details</h2>
@@ -214,15 +242,15 @@
 <p>The Android system provides information to accessibility services about the user interface
 interaction through {@link android.view.accessibility.AccessibilityEvent} objects. Prior to Android
 4.0, the information available in an accessibility event, while providing a significant amount of
-detail about a user interface control selected by the user, typically provided limited contextual
+detail about a user interface control selected by the user, offered limited contextual
 information. In many cases, this missing context information might be critical to understanding the
 meaning of the selected control.</p>
 
-<p>A typical example of an interface where context is of critical importance is a calendar or day
-planner. If a user selects a 4:00 PM time slot in a Monday to Friday day list and the accessibility
-service announces “4 PM”, but fails to indicate this is a Friday a Monday, the month or day, this is
-hardly ideal feedback for the user. In this case, the context of a user interface control is of
-critical importance to a user who wants to schedule a meeting.</p>
+<p>An example of an interface where context is critical is a calendar or day planner. If the
+user selects a 4:00 PM time slot in a Monday to Friday day list and the accessibility service
+announces “4 PM”, but does not announce the weekday name, the day of the month, or the month name,
+the resulting feedback is confusing. In this case, the context of a user interface control is
+critical to a user who wants to schedule a meeting.</p>
 
 <p>Android 4.0 significantly extends the amount of information that an accessibility service can
 obtain about an user interface interaction by composing accessibility events based on the view
@@ -245,26 +273,167 @@
 AccessibilityEvent.getRecordCount()} and {@link
 android.view.accessibility.AccessibilityEvent#getRecord getRecord(int)} - These methods allow you to
 retrieve the set of {@link android.view.accessibility.AccessibilityRecord} objects which contributed
-to the {@link android.view.accessibility.AccessibilityEvent} passed to you by the system, which can
-provide more context for your accessibility service.</li>
+to the {@link android.view.accessibility.AccessibilityEvent} passed to you by the system. This level
+of detail provides more context for the event that triggered your accessibility service.</li>
 
   <li>{@link android.view.accessibility.AccessibilityEvent#getSource
 AccessibilityEvent.getSource()} - This method returns an {@link
-android.view.accessibility.AccessibilityNodeInfo} object. This object allows you to request the
-parents and children of the component that originated the accessibility event and investigate their
-contents and state in order to provide
+android.view.accessibility.AccessibilityNodeInfo} object. This object allows you to request view
+layout hierarchy (parents and children) of the component that originated the accessibility event.
+This feature allows an accessibility service to investigate the full context of an event, including
+the content and state of any enclosing views or child views.
 
-    <p class="caution"><strong>Important:</strong> The ability to investigate the full view
+<p class="caution"><strong>Important:</strong> The ability to investigate the view
 hierarchy from an {@link android.view.accessibility.AccessibilityEvent} potentially exposes private
 user information to your accessibility service. For this reason, your service must request this
 level of access through the accessibility <a href="#service-config">service configuration XML</a>
 file, by including the {@code canRetrieveWindowContent} attribute and setting it to {@code true}. If
 you do not include this setting in your service configuration xml file, calls to {@link
 android.view.accessibility.AccessibilityEvent#getSource getSource()} fail.</p>
+
+<p class="note"><strong>Note:</strong> In Android 4.1 (API Level 16) and higher, the
+{@link android.view.accessibility.AccessibilityEvent#getSource getSource()} method,
+as well as {@link android.view.accessibility.AccessibilityNodeInfo#getChild
+AccessibilityNodeInfo.getChild()} and
+{@link android.view.accessibility.AccessibilityNodeInfo#getParent getParent()}, return only
+view objects that are considered important for accessibility (views that draw content or respond to
+user actions). If your service requires all views, it can request them by setting the
+{@link android.accessibilityservice.AccessibilityServiceInfo#flags flags} member of the service's
+{@link android.accessibilityservice.AccessibilityServiceInfo} instance to
+{@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS}.</p>
   </li>
 </ul>
 
 
+<h2 id="act-for-users">Taking Action for Users</h2>
+
+<p>Starting with Android 4.0 (API Level 14), accessibility services can act on behalf
+  of users, including changing the input focus and selecting (activating) user interface elements.
+  In Android 4.1 (API Level 16) the range of actions has been expanded to include scrolling lists
+  and interacting with text fields. Accessibility services can
+  also take global actions, such as navigating to the Home screen, pressing the Back button, opening
+  the notifications screen and recent applications list. Android 4.1 also includes a new type of
+  focus, <em>Accessibilty Focus</em>, which makes all visible elements selectable by an
+  accessibility service.</p>
+
+<p>These new capabilities make it possible for developers of accessibility services to create
+  alternative navigation modes such as
+  <a href="{@docRoot}tools/testing/testing_accessibility.html#test-gestures">gesture navigation</a>,
+  and give users with disabilities improved control of their Android devices.</p>
+
+
+<h3 id="detect-gestures">Listening for gestures</h3>
+
+<p>Accessibility services can listen for specific gestures and respond by taking action on behalf
+  of a user. This feature, added in Android 4.1 (API Level 16), and requires that your
+  accessibility service request activation of the Explore by Touch feature. Your service can
+  request this activation by setting the
+  {@link android.accessibilityservice.AccessibilityServiceInfo#flags flags} member of the service’s
+  {@link android.accessibilityservice.AccessibilityServiceInfo} instance to
+  {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE},
+  as shown in the following example.
+  </p>
+
+<pre>
+public class MyAccessibilityService extends AccessibilityService {
+    &#64;Override
+    public void onCreate() {
+        getServiceInfo().flags = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+    }
+    ...
+}
+</pre>
+
+<p>Once your service has requested activation of Explore by Touch, the user must allow the
+  feature to be turned on, if it is not already active. When this feature is active, your service
+  receives notification of accessibility gestures through your service's
+  {@link android.accessibilityservice.AccessibilityService#onGesture onGesture()} callback method
+  and can respond by taking actions for the user.</p>
+
+
+<h3 id="using-actions">Using accessibility actions</h3>
+
+<p>Accessibility services can take action on behalf of users to make interacting with applications
+  simpler and more productive. The ability of accessibility services to perform actions was added
+  in Android 4.0 (API Level 14) and significantly expanded with Android 4.1 (API Level 16).</p>
+
+<p>In order to take actions on behalf of users, your accessibility service must
+  <a href="#register">register</a> to receive events from a few or many applications and request
+  permission to view the content of applications by setting the
+  <a href="{@docRoot}reference/android/R.styleable.html#AccessibilityService_canRetrieveWindowContent">
+  {@code android:canRetrieveWindowContent}</a> to {@code true} in the
+  <a href="#service-config">service configuration file</a>. When events are received by your
+  service, it can then retrieve the
+  {@link android.view.accessibility.AccessibilityNodeInfo} object from the event using
+  {@link android.view.accessibility.AccessibilityEvent#getSource getSource()}.
+  With the {@link android.view.accessibility.AccessibilityNodeInfo} object, your service can then
+  explore the view hierarchy to determine what action to take and then act for the user using
+  {@link android.view.accessibility.AccessibilityNodeInfo#performAction performAction()}.</p>
+
+<pre>
+public class MyAccessibilityService extends AccessibilityService {
+
+    &#64;Override
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+        // get the source node of the event
+        AccessibilityNodeInfo nodeInfo = event.getSource();
+
+        // Use the event and node information to determine
+        // what action to take
+
+        // take action on behalf of the user
+        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+
+        // recycle the nodeInfo object
+        nodeInfo.recycle();
+    }
+    ...
+}
+</pre>
+
+<p>The {@link android.view.accessibility.AccessibilityNodeInfo#performAction performAction()} method
+  allows your service to take action within an application. If your service needs to perform a
+  global action such as navigating to the Home screen, pressing the Back button, opening the
+  notifications screen or recent applications list, then use the
+  {@link android.accessibilityservice.AccessibilityService#performGlobalAction performGlobalAction()}
+  method.</p>
+
+
+<h3 id="focus-types">Using focus types</h3>
+
+<p>Android 4.1 (API Level 16) introduces a new type of user interface focus called <em>Accessibility
+  Focus</em>. This type of focus can be used by accessibility services to select any visible user
+  interface element and act on it. This focus type is different from the more well known <em>Input
+  Focus</em>, which determines what on-screen user interface element receives input when a user
+  types characters, presses <strong>Enter</strong> on a keyboard or pushes the center button of a
+  D-pad control.</p>
+
+<p>Accessibility Focus is completely separate and independent from Input Focus. In fact, it is
+  possible for one element in a user interface to have Input Focus while another element has
+  Accessibility Focus. The purpose of Accessibility Focus is to provide accessibility services with
+  a method of interacting with any visible element on a screen, regardless of whether or not the
+  element is input-focusable from a system perspective. You can see accessibility focus in action by
+  testing accessibility gestures. For more information about testing this feature, see
+  <a href="{@docRoot}tools/testing/testing_accessibility.html#test-gestures">Testing gesture
+  navigation</a>.</p>
+
+<p class="note">
+  <strong>Note:</strong> Accessibility services that use Accessibility Focus are responsible for
+  synchronizing the current Input Focus when an element is capable of this type of focus. Services
+  that do not synchronize Input Focus with Accessibility Focus run the risk of causing problems in
+  applications that expect input focus to be in a specific location when certain actions are taken.
+  </p>
+
+<p>An accessibility service can determine what user interface element has Input Focus or
+  Accessibility Focus using the {@link android.view.accessibility.AccessibilityNodeInfo#findFocus
+  AccessibilityNodeInfo.findFocus()} method. You can also search for elements that can be selected
+  with Input Focus using the
+  {@link android.view.accessibility.AccessibilityNodeInfo#focusSearch focusSearch()} method.
+  Finally, your accessibility service can set Accessibility Focus using the
+  {@link android.view.accessibility.AccessibilityNodeInfo#performAction
+  performAction(AccessibilityNodeInfo.ACTION_SET_ACCESSIBILITY_FOCUS)} method.</p>
+
+
 <h2 id="examples">Example Code</h2>
 
 <p>The API Demo project contains two samples which can be used as a starting point for generating
diff --git a/docs/html/tools/testing/testing_accessibility.jd b/docs/html/tools/testing/testing_accessibility.jd
new file mode 100644
index 0000000..daf9b36
--- /dev/null
+++ b/docs/html/tools/testing/testing_accessibility.jd
@@ -0,0 +1,257 @@
+page.title=Accessibility Testing Checklist
+parent.title=Testing
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+  <div id="qv">
+  <h2>In this document</h2>
+  <ol>
+    <li><a href="#goals">Testing Goals</a></li>
+    <li><a href="#requirements">Testing Requirements</a></li>
+    <li><a href="#recommendations">Testing Recommendations</a></li>
+    <li><a href="#special-cases">Special Cases and Considerations</a></li>
+    <li><a href="#how-to">Testing Accessibility Features</a>
+      <ol>
+        <li><a href="#test-audibles">Testing audible feedback</a></li>
+        <li><a href="#test-navigation">Testing focus navigation</a></li>
+        <li><a href="#test-gestures">Testing gesture navigation</a></li>
+      </ol>
+    </li>
+  </ol>
+
+  <h2>See Also</h2>
+    <ol>
+      <li>
+        <a href="{@docRoot}guide/topics/ui/accessibility/checklist.html">
+        Accessibility Developer Checklist</a>
+      </li>
+      <li>
+        <a href="{@docRoot}design/patterns/accessibility.html">
+        Android Design: Accessibility</a>
+      </li>
+      <li>
+        <a href="{@docRoot}guide/topics/ui/accessibility/apps.html">
+        Making Applications Accessible</a>
+      </li>
+    </ol>
+  </div>
+</div>
+<p>
+  Testing is an important part of making your application accessible to users with varying
+  abilities. Following <a href="{@docRoot}design/patterns/accessibility.html">design</a> and
+  <a href="{@docRoot}guide/topics/ui/accessibility/checklist.html">development</a> guidelines for
+  accessibility are important steps toward that goal, but testing for accessibility can uncover
+  problems with user interaction that are not obvious during design and development.</p>
+
+<p>This accessibility testing checklist guides you through the important aspects of
+  accessibility testing, including overall goals, required testing steps, recommended testing and
+  special considerations. This document also discusses how to enable accessibility features on
+  Android devices for testing purposes.</p>
+
+
+<h2 id="goals">Testing Goals</h2>
+
+<p>Your accessibility testing should have the following, high level goals:</p>
+
+<ul>
+  <li>Set up and use the application without sighted assistance</li>
+  <li>All task workflows in the application can be easily navigated using directional controls and
+    provide clear and appropriate feedback</li>
+</ul>
+
+
+<h2 id="requirements">Testing Requirements</h2>
+
+<p>The following tests must be completed in order to ensure a minimum level of application
+  accessibility.</p>
+
+<ol>
+  <li><strong>Directional controls:</strong> Verify that the application can be operated
+    without the use of a touch screen. Attempt to use only directional controls to accomplish the
+    primary tasks in the application. Use the keyboard and directional-pad (D-Pad) controls in the
+    Android <a href="{@docRoot}tools/devices/emulator.html">Emulator</a> or use
+    <a href="http://support.google.com/nexus/bin/answer.py?hl=en&answer=2700718">gesture
+    navigation</a> on devices with Android 4.1 (API Level 16) or higher.
+    <p class="note"><strong>Note:</strong> Keyboards and D-pads provide different navigation paths
+    than accessibility gestures. While gestures allow users to focus on nearly any on-screen
+    content, keyboard and D-pad navigation only allow focus on input fields and buttons.</p>
+    </li>
+  <li><strong>TalkBack audio prompts:</strong> Verify that user interface controls that provide
+    information (graphics or text) or allow user action have clear and accurate audio descriptions
+    when <a href="#testing-talkback">TalkBack is enabled</a> and controls are focused. Use
+    directional controls to move focus between application layout elements.</li>
+  <li><strong>Explore by Touch prompts:</strong> Verify that user interface controls that
+    provide information (graphics or text) or allow user action have appropriate audio descriptions
+    when <a href="#testing-ebt">Explore by Touch is enabled</a>. There should be no
+    regions where contents or controls do not provide an audio description.</li>
+  <li><strong>Touchable control sizes:</strong> All controls where a user can select or take an
+    action must be a minimum of 48 dp (approximately 9mm) in length and width, as recommended by
+    <a href="{@docRoot}design/patterns/accessibility.html">Android Design</a>.</li>
+  <li><strong>Gestures work with TalkBack enabled:</strong> Verify that app-specific gestures,
+    such as zooming images, scrolling lists, swiping between pages or navigating carousel controls
+    continue to work when <a href="#testing-talkback">TalkBack is enabled</a>. If these gestures do
+    not function, then an alternative interface for these actions must be provided.</li>
+  <li><strong>No audio-only feedback:</strong> Audio feedback must always have a secondary
+    feedback mechanism to support users who are deaf or hard of hearing, for example: A sound alert
+    for the arrival of a message should also be accompanied by a system
+    {@link android.app.Notification}, haptic feedback (if available) or another visual alert.</li>
+</ol>
+
+
+<h2 id="recommendations">Testing Recommendations</h2>
+
+<p>The following tests are recommended for ensuring the accessibility of your application. If you
+  do not test these items, it may impact the overall accessibility and quality of your
+  application.</p>
+
+<ol>
+  <li><strong>Repetitive audio prompting:</strong> Check that closely related controls (such as
+    items with multiple components in a list) do not simply repeat the same audio prompt. For
+    example, in a contacts list that contains a contact picture, written name and title, the prompts
+    should not simply repeat “Bob Smith” for each item.</li>
+  <li><strong>Audio prompt overloading or underloading:</strong> Check that closely related
+    controls provide an appropriate level of audio information that enables users to understand and
+    act on a screen element. Too little or too much prompting can make it difficult to understand
+    and use a control.</li>
+</ol>
+
+
+<h2 id="special-cases">Special Cases and Considerations</h2>
+
+<p>The following list describes specific situations that should be tested to ensure an
+  accessible app. Some, none or all of the cases described here may apply to your application. Be
+  sure to review this list to find out if these special cases apply and take appropriate action.</p>
+
+<ol>
+  <li><strong>Review developer special cases and considerations:</strong> Review the list of
+    <a href="{@docRoot}guide/topics/ui/accessibility/checklist.html#special-cases">special cases</a>
+     for accessibility development and test your application for the cases that apply.</li>
+  <li><strong>Prompts for controls that change function:</strong> Buttons or other controls
+    that change function due to application context or workflow must provide audio prompts
+    appropriate to their current function. For example, a button that changes function from play
+    video to pause video should provide an audio prompt which is appropriate to its current state.</li>
+  <li><strong>Video playback and captioning:</strong> If the application provides video
+    playback, verify that it supports captioning and subtitles to assist users who are deaf or hard
+    of hearing. The video playback controls must clearly indicate if captioning is available for a
+    video and provide a clear way of enabling captions.</li>
+</ol>
+
+
+<h2 id="how-to">Testing Accessibility Features</h2>
+
+<p>Testing of accessibility features such as TalkBack, Explore by Touch and accessibility Gestures
+requires setup of your testing device. This section describes how to enable these features for
+accessibility testing.</p>
+
+
+<h3 id="test-audibles">Testing audible feedback</h3>
+
+<p>Audible accessibility feedback features on Android devices provide audio prompts that speaks
+  the screen content as you move around an application. By enabling these features on an Android
+  device, you can test the experience of users with blindness or low-vision using your application.
+</p>
+
+<p>Audible feedback for users on Android is typically provided by TalkBack accessibility service and
+the Explore by Touch system feature. The TalkBack accessibility service comes preinstalled on most
+Android devices and can also be downloaded for free from
+<a href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">Google
+Play</a>. The Explore by Touch system feature is available on devices running Android 4.0 and later.
+</p>
+
+<h4 id="testing-talkback">Testing with TalkBack</h4>
+
+<p>The <em>TalkBack</em> accessibility service works by speaking the contents of user interface
+controls as the user moves focus onto controls. This service should be enabled as part of testing
+focus navigation and audible prompts.</p>
+
+<p>To enable the TalkBack accessibility service:</p>
+<ol>
+  <li>Launch the <strong>Settings</strong> application.</li>
+  <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
+  <li>Select <strong>Accessibility</strong> to enable it.</li>
+  <li>Select <strong>TalkBack</strong> to enable it.</li>
+</ol>
+
+<p class="note">
+  <strong>Note:</strong> While TalkBack is the most available Android accessibility service for
+  users with disabilities, other accessibility services are available and may be installed by users.
+</p>
+
+<p>For more information about using TalkBack, see
+<a href="http://support.google.com/nexus/bin/answer.py?hl=en&answer=2700928">Use TalkBack</a>.</p>
+
+<h4 id="testing-ebt">Testing with Explore by Touch</h4>
+
+<p>The <em>Explore by Touch</em> system feature is available on devices running Android 4.0 and
+  later, and works by enabling a special accessibility mode that allows users to drag a finger
+  around the interface of an application and hear the contents of the screen spoken. This feature
+  does not require screen elements to be focused using an directional controller, but listens for
+  hover events over user interface controls.
+</p>
+
+<p>To enable Explore by Touch on Android 4.0 and later:</p>
+<ol>
+  <li>Launch the <strong>Settings</strong> application.</li>
+  <li>Navigate to the <strong>Accessibility</strong> category and select it.</li>
+  <li>Select the <strong>TalkBack</strong> to enable it.
+      <p class="note"><strong>Note:</strong> On Android 4.1 (API Level 16) and higher, the system
+      provides a popup message to enable Explore by Touch. On older versions, you must follow the
+      step below.</p>
+  </li>
+  <li>Return to the <strong>Accessibility</strong> category and select <strong>Explore by
+Touch</strong> to enable it.
+    <p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this
+option is not available.</p>
+  </li>
+</ol>
+
+<p>For more information about using the Explore by Touch features, see
+<a href="http://support.google.com/nexus/bin/answer.py?hl=en&answer=2700722">Use Explore by
+Touch</a>.</p>
+
+<h3 id="test-navigation">Testing focus navigation</h3>
+
+<p>Focus navigation is the use of directional controls to navigate between the individual user
+  interface elements of an application in order to operate it. Users with limited vision or limited
+  manual dexterity often use this mode of navigation instead of touch navigation. As part of
+  accessibility testing, you should verify that your application can be operated using only
+  directional controls.</p>
+
+<p>You can test navigation of your application using only focus controls, even if your test devices
+  does not have a directional controller. The <a href="{@docRoot}tools/help/emulator.html">Android
+  Emulator</a> provides a simulated directional controller that you can use to test navigation. You
+  can also use a software-based directional controller, such as the one provided by the
+  <a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin"
+  >Eyes-Free Keyboard</a> to simulate use of a D-pad on a test device that does not have a physical
+  D-pad.</p>
+
+
+<h3 id="test-gestures">Testing gesture navigation</h3>
+
+<p>Gesture navigation is an accessibility navigation mode that allows users to navigate Android
+  devices and applications using specific
+  <a href="http://support.google.com/nexus/bin/answer.py?hl=en&answer=2700718">gestures</a>. This
+  navigation mode is available on Android 4.1 (API Level 16) and higher.</p>
+
+<p class="note"><strong>Note:</strong> Accessibility gestures provide a different navigation path
+than keyboards and D-pads. While gestures allow users to focus on nearly any on-screen
+content, keyboard and D-pad navigation only allow focus on input fields and buttons.</p>
+
+<p>To enable gesture navigation on Android 4.1 and later:</p>
+<ul>
+  <li>Enable both TalkBack and the Explore by Touch feature as described in the
+    <a href="#testing-ebt">Testing with Explore by Touch</a>. When <em>both</em> of these
+    features are enabled, accessibility gestures are automatically enabled.</li>
+  <li>You can change gesture settings using <strong>Settings &gt; Accessibility &gt; TalkBack &gt;
+    Settings &gt; Manage shortcut gestures</strong>.
+</ul>
+
+<p>For more information about using Explore by Touch accessibility gestures, see
+<a href="http://support.google.com/android/bin/topic.py?hl=en&topic=2492346">Accessibility
+gestures</a>.</p>
+
+<p class="note">
+  <strong>Note:</strong> Accessibility services other than TalkBack may map accessibility gestures
+  to different user actions. If gestures are not producing the expected actions during testing, try
+  disabling other accessibility services before proceeding.</p>
\ No newline at end of file
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index 850e0ec..f3936b8 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -5,7 +5,7 @@
         <a href="<?cs var:toroot ?>tools/index.html"><span class="en">Developer Tools</span></a>
     </div>
   </li>
-  
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot
 ?>sdk/index.html"><span class="en">Download</span></a></div>
@@ -29,7 +29,7 @@
       </li>
     </ul>
   </li>
-  
+
   <li class="nav-section">
     <div class="nav-section-header">
         <a href="/tools/workflow/index.html"><span class="en">Workflow</span></a>
@@ -39,8 +39,8 @@
         <div class="nav-section-header"><a href="/tools/devices/index.html"><span class="en">Setting Up Virtual Devices</span></a></div>
         <ul>
           <li><a href="/tools/devices/managing-avds.html"><span class="en">With AVD Manager</span></a></li>
-          <li><a href="/tools/devices/managing-avds-cmdline.html"><span class="en">From the Command Line</span></a></li>      
-          <li><a href="/tools/devices/emulator.html"><span class="en">Using the Android Emulator</span></a></li>                  
+          <li><a href="/tools/devices/managing-avds-cmdline.html"><span class="en">From the Command Line</span></a></li>
+          <li><a href="/tools/devices/emulator.html"><span class="en">Using the Android Emulator</span></a></li>
         </ul>
       </li>
       <li><a href="/tools/device.html"><span class="en">Using Hardware Devices</span></a></li>
@@ -48,16 +48,16 @@
         <div class="nav-section-header"><a href="/tools/projects/index.html"><span class="en">Setting Up Projects</span></a></div>
         <ul>
           <li><a href="/tools/projects/projects-eclipse.html"><span class="en">From Eclipse with ADT</span></a></li>
-          <li><a href="/tools/projects/projects-cmdline.html"><span class="en">From the Command Line</span></a></li>                      
+          <li><a href="/tools/projects/projects-cmdline.html"><span class="en">From the Command Line</span></a></li>
         </ul>
       </li>
 
-  
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="/tools/building/index.html"><span class="en">Building and Running</span></a></div>
         <ul>
           <li><a href="/tools/building/building-eclipse.html"><span class="en">From Eclipse with ADT</span></a></li>
-          <li><a href="/tools/building/building-cmdline.html"><span class="en">From the Command Line</span></a></li>                    
+          <li><a href="/tools/building/building-cmdline.html"><span class="en">From the Command Line</span></a></li>
         </ul>
       </li>
 
@@ -76,7 +76,7 @@
           </li>
           <li><a href="<?cs var:toroot ?>tools/testing/testing_otheride.html">
             <span class="en">From Other IDEs</span></a>
-          </li>  
+          </li>
           <li>
             <a href="<?cs var:toroot?>tools/testing/activity_testing.html">
             <span class="en">Activity Testing</span></a>
@@ -90,6 +90,10 @@
             <span class="en">Content Provider Testing</span></a>
           </li>
           <li>
+            <a href="<?cs var:toroot?>tools/testing/testing_accessibility.html">
+            <span class="en">Accessibility Testing</span></a>
+          </li>
+          <li>
             <a href="<?cs var:toroot ?>tools/testing/what_to_test.html">
             <span class="en">What To Test</span></a>
           </li>
@@ -160,7 +164,7 @@
        <li><a href="<?cs var:toroot ?>tools/help/zipalign.html">zipalign</a></li>
     </ul>
   </li>
-  
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot
 ?>tools/revisions/index.html"><span class="en">Revisions</span></a></div>
@@ -178,8 +182,8 @@
 class="en">Platforms</span></a></li>
     </ul>
   </li>
-  
-  
+
+
   <li class="nav-section">
     <div class="nav-section-header"><a href="<?cs var:toroot
 ?>tools/extras/index.html"><span class="en">Extras</span></a></div>
@@ -192,13 +196,13 @@
     </ul>
   </li>
 
-  
+
   <li class="nav-section">
     <div class="nav-section-header empty"><a href="<?cs var:toroot
 ?>tools/samples/index.html"><span class="en">Samples</span></a></div>
   </li>
 
-  
+
   <li class="nav-section">
     <div class="nav-section-header">
     <a href="<?cs var:toroot ?>tools/adk/index.html">
@@ -217,7 +221,7 @@
       </li>
     </ul>
   </li>
-  
+
 </ul><!-- nav -->
 
 <script type="text/javascript">
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
new file mode 100644
index 0000000..41e7e00
--- /dev/null
+++ b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.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;
+import java.util.HashMap;
+
+
+/**
+ * @hide
+ **/
+public class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
+    private Matrix4f mMatrix = new Matrix4f();
+    private Allocation mInput;
+
+    ScriptIntrinsicColorMatrix(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are float, float4, uchar, uchar4
+     *
+     *
+     * @param rs
+     * @param e
+     *
+     * @return ScriptIntrinsicColorMatrix
+     */
+    public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) {
+        int id = rs.nScriptIntrinsicCreate(2, e.getID(rs));
+        return new ScriptIntrinsicColorMatrix(id, rs);
+
+    }
+
+    public void setColorMatrix(Matrix4f m) {
+        mMatrix.load(m);
+        FieldPacker fp = new FieldPacker(16*4);
+        fp.addMatrix(m);
+        setVar(0, fp);
+    }
+
+    public void forEach(Allocation ain, Allocation aout) {
+        forEach(0, ain, aout, null);
+    }
+
+}
+
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index b9a6336..6d27d6e 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -68,6 +68,7 @@
 static const GLsizei gAlphaVertexStride = sizeof(AlphaVertex);
 static const GLsizei gAAVertexStride = sizeof(AAVertex);
 static const GLsizei gMeshTextureOffset = 2 * sizeof(float);
+static const GLsizei gVertexAlphaOffset = 2 * sizeof(float);
 static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float);
 static const GLsizei gVertexAALengthOffset = 3 * sizeof(float);
 static const GLsizei gMeshCount = 4;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7abcc63..a1bb6a2 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1141,6 +1141,10 @@
     mDescription.isAA = true;
 }
 
+void OpenGLRenderer::setupDrawAARect() {
+    mDescription.isAARect = true;
+}
+
 void OpenGLRenderer::setupDrawPoint(float pointSize) {
     mDescription.isPoint = true;
     mDescription.pointSize = pointSize;
@@ -1741,9 +1745,9 @@
 
 /**
  * This function uses a similar approach to that of AA lines in the drawLines() function.
- * We expand the rectangle by a half pixel in screen space on all sides, and use a fragment
- * shader to compute the translucency of the color, determined by whether a given pixel is
- * within that boundary region and how far into the region it is.
+ * We expand the rectangle by a half pixel in screen space on all sides. However, instead of using
+ * a fragment shader to compute the translucency of the color from its position, we simply use a
+ * varying parameter to define how far a given pixel is into the region.
  */
 void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom,
         int color, SkXfermode::Mode mode) {
@@ -1755,10 +1759,8 @@
         Matrix4 *mat = mSnapshot->transform;
         float m00 = mat->data[Matrix4::kScaleX];
         float m01 = mat->data[Matrix4::kSkewY];
-        float m02 = mat->data[2];
         float m10 = mat->data[Matrix4::kSkewX];
         float m11 = mat->data[Matrix4::kScaleX];
-        float m12 = mat->data[6];
         float scaleX = sqrt(m00 * m00 + m01 * m01);
         float scaleY = sqrt(m10 * m10 + m11 * m11);
         inverseScaleX = (scaleX != 0) ? (inverseScaleX / scaleX) : 0;
@@ -1768,6 +1770,11 @@
     float boundarySizeX = .5 * inverseScaleX;
     float boundarySizeY = .5 * inverseScaleY;
 
+    float innerLeft = left + boundarySizeX;
+    float innerRight = right - boundarySizeX;
+    float innerTop = top + boundarySizeY;
+    float innerBottom = bottom - boundarySizeY;
+
     // Adjust the rect by the AA boundary padding
     left -= boundarySizeX;
     right += boundarySizeX;
@@ -1777,7 +1784,7 @@
     if (!quickReject(left, top, right, bottom)) {
         setupDraw();
         setupDrawNoTexture();
-        setupDrawAALine();
+        setupDrawAARect();
         setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
         setupDrawColorFilter();
         setupDrawShader();
@@ -1788,34 +1795,52 @@
         setupDrawColorFilterUniforms();
         setupDrawShaderIdentityUniforms();
 
-        AAVertex rects[4];
-        AAVertex* aaVertices = &rects[0];
-        void* widthCoords = ((GLbyte*) aaVertices) + gVertexAAWidthOffset;
-        void* lengthCoords = ((GLbyte*) aaVertices) + gVertexAALengthOffset;
+        AlphaVertex rects[14];
+        AlphaVertex* aVertices = &rects[0];
+        void* alphaCoords = ((GLbyte*) aVertices) + gVertexAlphaOffset;
 
-        int widthSlot;
-        int lengthSlot;
+        bool force = mCaches.unbindMeshBuffer();
+        mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position,
+                aVertices, gAlphaVertexStride);
+        mCaches.resetTexCoordsVertexPointer();
+        mCaches.unbindIndicesBuffer();
 
-        float width = right - left;
-        float height = bottom - top;
+        int alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha");
+        glEnableVertexAttribArray(alphaSlot);
+        glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
 
-        float boundaryWidthProportion = .5 - ((width != 0) ? (2 * boundarySizeX) / width : 0);
-        float boundaryHeightProportion = .5 - ((height != 0) ? (2 * boundarySizeY) / height : 0);
-        setupDrawAALine((void*) aaVertices, widthCoords, lengthCoords,
-                boundaryWidthProportion, widthSlot, lengthSlot);
+        // draw left
+        AlphaVertex::set(aVertices++, left, bottom, 0);
+        AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1);
+        AlphaVertex::set(aVertices++, left, top, 0);
+        AlphaVertex::set(aVertices++, innerLeft, innerTop, 1);
 
-        int boundaryLengthSlot = mCaches.currentProgram->getUniform("boundaryLength");
-        glUniform1f(boundaryLengthSlot, boundaryHeightProportion);
+        // draw top
+        AlphaVertex::set(aVertices++, right, top, 0);
+        AlphaVertex::set(aVertices++, innerRight, innerTop, 1);
 
-        AAVertex::set(aaVertices++, left, bottom, 1, 1);
-        AAVertex::set(aaVertices++, left, top, 1, 0);
-        AAVertex::set(aaVertices++, right, bottom, 0, 1);
-        AAVertex::set(aaVertices++, right, top, 0, 0);
+        // draw right
+        AlphaVertex::set(aVertices++, right, bottom, 0);
+        AlphaVertex::set(aVertices++, innerRight, innerBottom, 1);
+
+        // draw bottom
+        AlphaVertex::set(aVertices++, left, bottom, 0);
+        AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1);
+
+        // draw inner rect (repeating last vertex to create degenerate bridge triangles)
+        // TODO: also consider drawing the inner rect without the blending-forced shader, if
+        // blending is expensive. Note: can't use drawColorRect() since it doesn't use vertex
+        // buffers like below, resulting in slightly different transformed coordinates.
+        AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1);
+        AlphaVertex::set(aVertices++, innerLeft, innerTop, 1);
+        AlphaVertex::set(aVertices++, innerRight, innerBottom, 1);
+        AlphaVertex::set(aVertices++, innerRight, innerTop, 1);
+
         dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
 
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, 14);
 
-        finishDrawAALine(widthSlot, lengthSlot);
+        glDisableVertexAttribArray(alphaSlot);
     }
 }
 
@@ -1870,10 +1895,8 @@
             Matrix4 *mat = mSnapshot->transform;
             float m00 = mat->data[Matrix4::kScaleX];
             float m01 = mat->data[Matrix4::kSkewY];
-            float m02 = mat->data[2];
             float m10 = mat->data[Matrix4::kSkewX];
             float m11 = mat->data[Matrix4::kScaleX];
-            float m12 = mat->data[6];
 
             float scaleX = sqrtf(m00 * m00 + m01 * m01);
             float scaleY = sqrtf(m10 * m10 + m11 * m11);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 4c7cf0a..f2b5f0a 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -434,7 +434,6 @@
      * @param color The rectangle's ARGB color, defined as a packed 32 bits word
      * @param mode The Skia xfermode to use
      * @param ignoreTransform True if the current transform should be ignored
-     * @param ignoreBlending True if the blending is set by the caller
      */
     void drawColorRect(float left, float top, float right, float bottom,
             int color, SkXfermode::Mode mode, bool ignoreTransform = false);
@@ -649,6 +648,7 @@
     void setupDrawWithExternalTexture();
     void setupDrawNoTexture();
     void setupDrawAALine();
+    void setupDrawAARect();
     void setupDrawPoint(float pointSize);
     void setupDrawColor(int color);
     void setupDrawColor(int color, int alpha);
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 1818f82..a3bfaa4 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -81,6 +81,8 @@
 
 #define PROGRAM_IS_SIMPLE_GRADIENT 41
 
+#define PROGRAM_IS_AA_RECT_SHIFT 42
+
 ///////////////////////////////////////////////////////////////////////////////
 // Types
 ///////////////////////////////////////////////////////////////////////////////
@@ -128,6 +130,7 @@
     bool isBitmapNpot;
 
     bool isAA;
+    bool isAARect;
 
     bool hasGradient;
     Gradient gradientType;
@@ -165,6 +168,7 @@
         hasTextureTransform = false;
 
         isAA = false;
+        isAARect = false;
 
         modulate = false;
 
@@ -260,6 +264,7 @@
         if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
         if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
         if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
+        if (isAARect) key |= programid(0x1) << PROGRAM_IS_AA_RECT_SHIFT;
         return key;
     }
 
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 8a9a2ac..0ed8008 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -43,6 +43,8 @@
 const char* gVS_Header_Attributes_AAParameters =
         "attribute float vtxWidth;\n"
         "attribute float vtxLength;\n";
+const char* gVS_Header_Attributes_AARectParameters =
+        "attribute float vtxAlpha;\n";
 const char* gVS_Header_Uniforms_TextureTransform =
         "uniform mat4 mainTextureTransform;\n";
 const char* gVS_Header_Uniforms =
@@ -65,6 +67,8 @@
 const char* gVS_Header_Varyings_IsAA =
         "varying float widthProportion;\n"
         "varying float lengthProportion;\n";
+const char* gVS_Header_Varyings_IsAARect =
+        "varying float alpha;\n";
 const char* gVS_Header_Varyings_HasBitmap =
         "varying highp vec2 outBitmapTexCoords;\n";
 const char* gVS_Header_Varyings_PointHasBitmap =
@@ -112,6 +116,8 @@
 const char* gVS_Main_AA =
         "    widthProportion = vtxWidth;\n"
         "    lengthProportion = vtxLength;\n";
+const char* gVS_Main_AARect =
+        "    alpha = vtxAlpha;\n";
 const char* gVS_Footer =
         "}\n\n";
 
@@ -242,6 +248,8 @@
 const char* gFS_Main_AccountForAA =
         "    fragColor *= (1.0 - smoothstep(boundaryWidth, 0.5, abs(0.5 - widthProportion)))\n"
         "               * (1.0 - smoothstep(boundaryLength, 0.5, abs(0.5 - lengthProportion)));\n";
+const char* gFS_Main_AccountForAARect =
+        "    fragColor *= alpha;\n";
 
 const char* gFS_Main_FetchTexture[2] = {
         // Don't modulate
@@ -439,7 +447,9 @@
     if (description.hasTexture || description.hasExternalTexture) {
         shader.append(gVS_Header_Attributes_TexCoords);
     }
-    if (description.isAA) {
+    if (description.isAARect) {
+        shader.append(gVS_Header_Attributes_AARectParameters);
+    } else if (description.isAA) {
         shader.append(gVS_Header_Attributes_AAParameters);
     }
     // Uniforms
@@ -460,7 +470,9 @@
     if (description.hasTexture || description.hasExternalTexture) {
         shader.append(gVS_Header_Varyings_HasTexture);
     }
-    if (description.isAA) {
+    if (description.isAARect) {
+        shader.append(gVS_Header_Varyings_IsAARect);
+    } else if (description.isAA) {
         shader.append(gVS_Header_Varyings_IsAA);
     }
     if (description.hasGradient) {
@@ -479,7 +491,9 @@
         } else if (description.hasTexture || description.hasExternalTexture) {
             shader.append(gVS_Main_OutTexCoords);
         }
-        if (description.isAA) {
+        if (description.isAARect) {
+            shader.append(gVS_Main_AARect);
+        } else if (description.isAA) {
             shader.append(gVS_Main_AA);
         }
         if (description.hasGradient) {
@@ -521,7 +535,9 @@
     if (description.hasTexture || description.hasExternalTexture) {
         shader.append(gVS_Header_Varyings_HasTexture);
     }
-    if (description.isAA) {
+    if (description.isAARect) {
+        shader.append(gVS_Header_Varyings_IsAARect);
+    } else if (description.isAA) {
         shader.append(gVS_Header_Varyings_IsAA);
     }
     if (description.hasGradient) {
@@ -562,7 +578,8 @@
 
     // Optimization for common cases
     if (!description.isAA && !blendFramebuffer &&
-            description.colorOp == ProgramDescription::kColorNone && !description.isPoint) {
+            description.colorOp == ProgramDescription::kColorNone &&
+            !description.isPoint && !description.isAARect) {
         bool fast = false;
 
         const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -654,7 +671,9 @@
                 shader.append(gFS_Main_FetchColor);
             }
         }
-        if (description.isAA) {
+        if (description.isAARect) {
+            shader.append(gFS_Main_AccountForAARect);
+        } else if (description.isAA) {
             shader.append(gFS_Main_AccountForAA);
         }
         if (description.hasGradient) {
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 34e1a68..6e205b8 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -51,7 +51,7 @@
 void Font::invalidateTextureCache(CacheTexture* cacheTexture) {
     for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
         CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueAt(i);
-        if (cacheTexture || cachedGlyph->mCacheTexture == cacheTexture) {
+        if (!cacheTexture || cachedGlyph->mCacheTexture == cacheTexture) {
             cachedGlyph->mIsValid = false;
         }
     }
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 0d7b45e..88cf4ac 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1415,7 +1415,8 @@
         long lastModifiedSeconds = file.lastModified() / 1000;
 
         if (!MediaFile.isAudioFileType(fileType) && !MediaFile.isVideoFileType(fileType) &&
-            !MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType)) {
+            !MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType) &&
+            !MediaFile.isDrmFileType(fileType)) {
 
             // no need to use the media scanner, but we need to update last modified and file size
             ContentValues values = new ContentValues();
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 875d2c9..b3d9ea3 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -46,8 +46,8 @@
     <bool name="def_netstats_enabled">true</bool>
     <bool name="def_usb_mass_storage_enabled">true</bool>
     <bool name="def_wifi_on">false</bool>
-    <!-- 0 == default, 1 == never while plugged, 2 == never -->
-    <integer name="def_wifi_sleep_policy">0</integer>
+    <!-- 0 == never, 1 == only when plugged in, 2 == always -->
+    <integer name="def_wifi_sleep_policy">2</integer>
     <bool name="def_networks_available_notification_on">true</bool>
 
     <bool name="def_backup_enabled">false</bool>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 7176f32..13800a6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -193,5 +193,18 @@
                 <category android:name="android.intent.category.DREAM" />
             </intent-filter>
         </service>
+
+        <activity android:name=".Somnambulator"
+            android:label="@string/start_dreams"
+            android:icon="@mipmap/ic_dreams"
+            android:theme="@android:style/Theme.Wallpaper.NoTitleBar"
+            android:exported="true"
+            android:excludeFromRecents="true"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.CREATE_SHORTCUT" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml b/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml
index d683af9..c209055 100644
--- a/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_fg.xml
@@ -16,5 +16,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_selected="true" />
     <item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_pressed="true" />
-    <item android:drawable="@*android:color/transparent"/>
+    <item android:drawable="@drawable/recents_thumbnail_no_press"/>
 </selector>
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_no_press.xml b/packages/SystemUI/res/drawable/recents_thumbnail_no_press.xml
new file mode 100644
index 0000000..be07b2c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_no_press.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<color xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="#00000000" />
diff --git a/packages/SystemUI/res/layout-sw600dp/carrier_label.xml b/packages/SystemUI/res/layout-sw600dp/carrier_label.xml
new file mode 100644
index 0000000..b33caf8
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/carrier_label.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<Space
+    xmlns:android="http://schemas.android.com/apk/res/android"    
+    android:visibility="gone"
+    />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/carrier_label.xml b/packages/SystemUI/res/layout/carrier_label.xml
new file mode 100644
index 0000000..41a1fff
--- /dev/null
+++ b/packages/SystemUI/res/layout/carrier_label.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"    
+    android:id="@+id/carrier_label"
+    android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network"
+    android:layout_height="@dimen/carrier_label_height"
+    android:layout_width="match_parent"
+    android:layout_gravity="bottom"
+    android:layout_marginBottom="@dimen/close_handle_height"
+    android:gravity="center"
+    android:visibility="invisible"
+    />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_settings.xml b/packages/SystemUI/res/layout/quick_settings.xml
index c4b881e..8c6258a 100644
--- a/packages/SystemUI/res/layout/quick_settings.xml
+++ b/packages/SystemUI/res/layout/quick_settings.xml
@@ -19,6 +19,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:id="@+id/settings_panel"
+    android:background="#80000080"
     >
     <ImageView
         android:layout_width="match_parent"
@@ -26,7 +27,6 @@
         android:scaleType="centerInside"
         android:src="@drawable/qs_coming_soon"
         android:padding="4dp"
-        android:background="#80000080"
         />
     <LinearLayout android:id="@+id/handle"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 8eff1f4..f2e83d8 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -29,15 +29,10 @@
     android:layout_marginLeft="@dimen/notification_panel_margin_left"
     >
 
-    <TextView
-        android:id="@+id/carrier_label"
-        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network"
+    <include
+        layout="@layout/carrier_label"
         android:layout_height="@dimen/carrier_label_height"
         android:layout_width="match_parent"
-        android:layout_gravity="bottom"
-        android:layout_marginBottom="@dimen/close_handle_height"
-        android:gravity="center"
-        android:visibility="invisible"
         />
 
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index ad6b8f4..5e0d1e8 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -40,11 +40,11 @@
         >
         <include layout="@layout/status_bar_expanded"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
+            android:layout_height="match_parent"
             />
         <include layout="@layout/quick_settings"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
+            android:layout_height="match_parent"
             />
     </com.android.systemui.statusbar.phone.PanelHolder>
 
diff --git a/packages/SystemUI/res/mipmap-hdpi/ic_dreams.png b/packages/SystemUI/res/mipmap-hdpi/ic_dreams.png
new file mode 100644
index 0000000..56cbac1
--- /dev/null
+++ b/packages/SystemUI/res/mipmap-hdpi/ic_dreams.png
Binary files differ
diff --git a/packages/SystemUI/res/mipmap-mdpi/ic_dreams.png b/packages/SystemUI/res/mipmap-mdpi/ic_dreams.png
new file mode 100644
index 0000000..ea3d991
--- /dev/null
+++ b/packages/SystemUI/res/mipmap-mdpi/ic_dreams.png
Binary files differ
diff --git a/packages/SystemUI/res/mipmap-xhdpi/ic_dreams.png b/packages/SystemUI/res/mipmap-xhdpi/ic_dreams.png
new file mode 100644
index 0000000..ddc7f66
--- /dev/null
+++ b/packages/SystemUI/res/mipmap-xhdpi/ic_dreams.png
Binary files differ
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 609d63b..43070c6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -372,9 +372,6 @@
     <!-- Content description of the clear button in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_clear_all">Clear all notifications.</string>
 
-    <!-- Description of the desk dock action that invokes the Android Dreams screen saver feature -->
-    <string name="dreams_dock_launcher">Activate screen saver</string>
-
     <!-- Title shown in notification popup for inspecting the responsible
          application -->
     <string name="status_bar_notification_inspect_item_title">App info</string>
@@ -400,4 +397,8 @@
 
     <!-- Name of the Jelly Bean platlogo screensaver -->
     <string name="jelly_bean_dream_name">BeanFlinger</string>
+
+    <!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
+    <string name="start_dreams">Start dreams</string>
+
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/Somnambulator.java b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
new file mode 100644
index 0000000..89d4ef7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
@@ -0,0 +1,61 @@
+/*);
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.dreams.IDreamManager;
+import android.util.Slog;
+
+public class Somnambulator extends Activity {
+
+    public Somnambulator() {
+    }
+    
+    @Override
+    public void onStart() {
+        super.onStart();
+        final Intent launchIntent = getIntent();
+        final String action = launchIntent.getAction();
+        if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
+            Intent shortcutIntent = new Intent(this, Somnambulator.class);
+            shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                    | Intent.FLAG_ACTIVITY_NEW_TASK);
+            Intent resultIntent = new Intent();
+            resultIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+                    Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_dreams));
+            resultIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
+            resultIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.start_dreams));
+            setResult(RESULT_OK, resultIntent);
+        } else {
+            IDreamManager somnambulist = IDreamManager.Stub.asInterface(
+                    ServiceManager.checkService("dreams"));
+            if (somnambulist != null) {
+                try {
+                    Slog.v("Somnambulator", "Dreaming by user request.");
+                    somnambulist.dream();
+                } catch (RemoteException e) {
+                    // fine, stay asleep then
+                }
+            }
+        }
+        finish();
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 33f467f..2f551e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -5,7 +5,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.util.AttributeSet;
-import android.util.Log;
+import android.util.Slog;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -18,7 +18,7 @@
     public static final String TAG = PanelView.class.getSimpleName();
     public final void LOG(String fmt, Object... args) {
         if (!DEBUG) return;
-        Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
+        Slog.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
     }
 
     public static final boolean BRAKES = false;
@@ -175,6 +175,12 @@
         event.offsetLocation(-deltaX, -deltaY);
     }
 
+    // Pass all touches along to the handle, allowing the user to drag the panel closed from its interior
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        return mHandleView.dispatchTouchEvent(event);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 8cdc51ae..5646c55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -109,8 +109,6 @@
     public static final String ACTION_STATUSBAR_START
             = "com.android.internal.policy.statusbar.START";
 
-    private static final boolean SHOW_CARRIER_LABEL = false; // XXX: doesn't work with rubberband panels right now
-
     private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
     private static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
     // 1020-1030 reserved for BaseStatusBar
@@ -189,6 +187,9 @@
     private boolean mCarrierLabelVisible = false;
     private int mCarrierLabelHeight;
     private TextView mEmergencyCallLabel;
+    private int mNotificationHeaderHeight;
+
+    private boolean mShowCarrierInPanel = false;
 
     // position
     int[] mPositionTmp = new int[2];
@@ -310,14 +311,6 @@
         mStatusBarView.setPanelHolder(holder);
 
         mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
-        // don't allow clicks on the panel to pass through to the background where they will cause the panel to close
-        View.OnTouchListener clickStopper = new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                return true;
-            }
-        };
-        mNotificationPanel.setOnTouchListener(clickStopper);
         mNotificationPanelIsFullScreenWidth =
             (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
         mNotificationPanel.setSystemUiVisibility(
@@ -326,7 +319,6 @@
 
         // quick settings (WIP)
         mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
-        mSettingsPanel.setOnTouchListener(clickStopper);
 
         if (!ActivityManager.isHighEndGfx()) {
             mStatusBarWindow.setBackground(null);
@@ -419,8 +411,10 @@
                 }});
         }
 
-        if (SHOW_CARRIER_LABEL) {
-            mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
+        mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
+        mShowCarrierInPanel = (mCarrierLabel != null);
+        Slog.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
+        if (mShowCarrierInPanel) {
             mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
 
             // for mobile devices, we always show mobile connection info here (SPN/PLMN)
@@ -733,6 +727,10 @@
          */
 
         if (notification.notification.fullScreenIntent != null) {
+            // Stop screensaver if the notification has a full-screen intent.
+            // (like an incoming phone call)
+            awakenDreams();
+
             // not immersive & a full-screen alert should be shown
             Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
             try {
@@ -867,7 +865,7 @@
     }
 
     protected void updateCarrierLabelVisibility(boolean force) {
-        if (!SHOW_CARRIER_LABEL) return;
+        if (!mShowCarrierInPanel) return;
         // The idea here is to only show the carrier label when there is enough room to see it, 
         // i.e. when there aren't enough notifications to fill the panel.
         if (DEBUG) {
@@ -878,7 +876,7 @@
         final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
         final boolean makeVisible =
             !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
-            && mPile.getHeight() < (mScrollView.getHeight() - mCarrierLabelHeight);
+            && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight);
         
         if (force || mCarrierLabelVisible != makeVisible) {
             mCarrierLabelVisible = makeVisible;
@@ -1631,6 +1629,8 @@
         lp.gravity = mSettingsPanelGravity;
         lp.rightMargin = mNotificationPanelMarginPx;
         mSettingsPanel.setLayoutParams(lp);
+
+        updateCarrierLabelVisibility(false);
     }
 
     // called by makeStatusbar and also by PhoneStatusBarView
@@ -1905,6 +1905,7 @@
             + res.getDimensionPixelSize(R.dimen.close_handle_underlap);
 
         mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
+        mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
 
         if (false) Slog.v(TAG, "updateResources");
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
index 31d138b..5a0a228 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
@@ -81,13 +81,16 @@
      * Stores some of the structures that Face Unlock will need to access and creates the handler
      * will be used to execute messages on the UI thread.
      */
-    public FaceUnlock(Context context, KeyguardSecurityCallback keyguardScreenCallback) {
+    public FaceUnlock(Context context) {
         mContext = context;
         mLockPatternUtils = new LockPatternUtils(context);
-        mKeyguardScreenCallback = keyguardScreenCallback;
         mHandler = new Handler(this);
     }
 
+    public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) {
+        mKeyguardScreenCallback = keyguardScreenCallback;
+    }
+
     /**
      * Stores and displays the view that Face Unlock is allowed to draw within.
      * TODO: since the layout object will eventually be shared by multiple biometric unlock
@@ -114,11 +117,7 @@
         if (mHandler.getLooper() != Looper.myLooper()) {
             Log.e(TAG, "show() called off of the UI thread");
         }
-
         removeDisplayMessages();
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.VISIBLE);
-        }
         if (timeoutMillis > 0) {
             mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACE_UNLOCK_VIEW, timeoutMillis);
         }
@@ -270,23 +269,15 @@
      */
     void handleShowFaceUnlockView() {
         if (DEBUG) Log.d(TAG, "handleShowFaceUnlockView()");
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.VISIBLE);
-        } else {
-            Log.e(TAG, "mFaceUnlockView is null in handleShowFaceUnlockView()");
-        }
+        // Not required
     }
 
     /**
-     * Sets the Face Unlock view to invisible, thus exposing the backup lock.
+     * Hide face unlock and show backup
      */
     void handleHideFaceUnlockView() {
         if (DEBUG) Log.d(TAG, "handleHideFaceUnlockView()");
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.INVISIBLE);
-        } else {
-            Log.e(TAG, "mFaceUnlockView is null in handleHideFaceUnlockView()");
-        }
+        mKeyguardScreenCallback.showBackupSecurity();
     }
 
     /**
@@ -358,11 +349,6 @@
     void handleUnlock() {
         if (DEBUG) Log.d(TAG, "handleUnlock()");
         removeDisplayMessages();
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.VISIBLE);
-        } else {
-            Log.e(TAG, "mFaceUnlockView is null in handleUnlock()");
-        }
         stop();
         mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
         mKeyguardScreenCallback.dismiss(true);
@@ -373,11 +359,7 @@
      */
     void handleCancel() {
         if (DEBUG) Log.d(TAG, "handleCancel()");
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.INVISIBLE);
-        } else {
-            Log.e(TAG, "mFaceUnlockView is null in handleCancel()");
-        }
+        mKeyguardScreenCallback.dismiss(false);
         stop();
         mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT);
     }
@@ -397,11 +379,7 @@
      */
     void handleExposeFallback() {
         if (DEBUG) Log.d(TAG, "handleExposeFallback()");
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.INVISIBLE);
-        } else {
-            Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()");
-        }
+        // No longer required because face unlock doesn't cover backup unlock.
     }
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index 843151b..7dffca8 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -16,18 +16,25 @@
 package com.android.internal.policy.impl.keyguard;
 
 import android.content.Context;
+import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
 import android.widget.LinearLayout;
 
+import com.android.internal.R;
+import com.android.internal.policy.impl.keyguard.BiometricSensorUnlock;
+import com.android.internal.policy.impl.keyguard.FaceUnlock;
 import com.android.internal.widget.LockPatternUtils;
 
 public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView {
 
-    // Long enough to stay visible while dialer comes up
-    // Short enough to not be visible if the user goes back immediately
-    private static final int BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
+    private static final String TAG = "KeyguardFaceUnlockView";
     private KeyguardSecurityCallback mKeyguardSecurityCallback;
     private LockPatternUtils mLockPatternUtils;
+    private BiometricSensorUnlock mBiometricUnlock;
+    private KeyguardNavigationManager mNavigationManager;
+    private View mFaceUnlockAreaView;
 
     public KeyguardFaceUnlockView(Context context) {
         this(context, null);
@@ -38,8 +45,18 @@
     }
 
     @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mNavigationManager = new KeyguardNavigationManager(this);
+
+        initializeBiometricUnlockView();
+    }
+
+    @Override
     public void setKeyguardCallback(KeyguardSecurityCallback callback) {
         mKeyguardSecurityCallback = callback;
+        // TODO: formalize this in the interface or factor it out
+        ((FaceUnlock)mBiometricUnlock).setKeyguardCallback(callback);
     }
 
     @Override
@@ -54,12 +71,18 @@
 
     @Override
     public void onPause() {
-
+        if (mBiometricUnlock != null) {
+            mBiometricUnlock.hide();
+            mBiometricUnlock.stop();
+        }
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
     }
 
     @Override
     public void onResume() {
-
+        maybeStartBiometricUnlock();
+        mBiometricUnlock.show(0);
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
     }
 
     @Override
@@ -72,123 +95,59 @@
         return mKeyguardSecurityCallback;
     }
 
-    // TODO
-    //    public void onRefreshBatteryInfo(BatteryStatus status) {
-    //        // When someone plugs in or unplugs the device, we hide the biometric sensor area and
-    //        // suppress its startup for the next onScreenTurnedOn().  Since plugging/unplugging
-    //        // causes the screen to turn on, the biometric unlock would start if it wasn't
-    //        // suppressed.
-    //        //
-    //        // However, if the biometric unlock is already running, we do not want to interrupt it.
-    //        final boolean pluggedIn = status.isPluggedIn();
-    //        if (mBiometricUnlock != null && mPluggedIn != pluggedIn
-    //                && !mBiometricUnlock.isRunning()) {
-    //            mBiometricUnlock.stop();
-    //            mBiometricUnlock.hide();
-    //            mSuppressBiometricUnlock = true;
-    //        }
-    //        mPluggedIn = pluggedIn;
-    //    }
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        mBiometricUnlock.initializeView(mFaceUnlockAreaView);
+    }
 
-    // We need to stop the biometric unlock when a phone call comes in
-    //    @Override
-    //    public void onPhoneStateChanged(int phoneState) {
-    //        if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
-    //        if (phoneState == TelephonyManager.CALL_STATE_RINGING) {
-    //            mSuppressBiometricUnlock = true;
-    //            mBiometricUnlock.stop();
-    //            mBiometricUnlock.hide();
-    //        }
-    //    }
+    private void initializeBiometricUnlockView() {
+        mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view);
+        if (mFaceUnlockAreaView != null) {
+            mBiometricUnlock = new FaceUnlock(mContext);
+        } else {
+            Log.w(TAG, "Couldn't find biometric unlock view");
+        }
+    }
 
-    //    @Override
-    //    public void onUserSwitched(int userId) {
-    //        if (mBiometricUnlock != null) {
-    //            mBiometricUnlock.stop();
-    //        }
-    //        mLockPatternUtils.setCurrentUser(userId);
-    //        updateScreen(getInitialMode(), true);
-    //    }
+    /**
+     * Starts the biometric unlock if it should be started based on a number of factors including
+     * the mSuppressBiometricUnlock flag.  If it should not be started, it hides the biometric
+     * unlock area.
+     */
+    private void maybeStartBiometricUnlock() {
+        if (mBiometricUnlock != null) {
+            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+            final boolean backupIsTimedOut = (
+                    monitor.getFailedUnlockAttempts() >=
+                    LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
+            if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+                    && !monitor.getMaxBiometricUnlockAttemptsReached()
+                    && !backupIsTimedOut) {
+                mBiometricUnlock.start();
+            } else {
+                mBiometricUnlock.hide();
+            }
+        }
+    }
 
-    //    /**
-    //     * This returns false if there is any condition that indicates that the biometric unlock should
-    //     * not be used before the next time the unlock screen is recreated.  In other words, if this
-    //     * returns false there is no need to even construct the biometric unlock.
-    //     */
-    //    private boolean useBiometricUnlock() {
-    //        final ShowingMode unlockMode = getUnlockMode();
-    //        final boolean backupIsTimedOut = (mUpdateMonitor.getFailedAttempts() >=
-    //                LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
-    //        return (mLockPatternUtils.usingBiometricWeak() &&
-    //                mLockPatternUtils.isBiometricWeakInstalled() &&
-    //                !mUpdateMonitor.getMaxBiometricUnlockAttemptsReached() &&
-    //                !backupIsTimedOut &&
-    //                (unlockMode == ShowingMode.Pattern || unlockMode == ShowingMode.Password));
-    //    }
+    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
+        // We need to stop the biometric unlock when a phone call comes in
+        @Override
+        public void onPhoneStateChanged(int phoneState) {
+            if (phoneState == TelephonyManager.CALL_STATE_RINGING) {
+                mBiometricUnlock.stop();
+                mBiometricUnlock.hide();
+            }
+        }
 
-    //    private void initializeBiometricUnlockView(View view) {
-    //        boolean restartBiometricUnlock = false;
-    //
-    //        if (mBiometricUnlock != null) {
-    //            restartBiometricUnlock = mBiometricUnlock.stop();
-    //        }
-    //
-    //        // Prevents biometric unlock from coming up immediately after a phone call or if there
-    //        // is a dialog on top of lockscreen. It is only updated if the screen is off because if the
-    //        // screen is on it's either because of an orientation change, or when it first boots.
-    //        // In both those cases, we don't want to override the current value of
-    //        // mSuppressBiometricUnlock and instead want to use the previous value.
-    //        if (!mScreenOn) {
-    //            mSuppressBiometricUnlock =
-    //                    mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE
-    //                    || mHasDialog;
-    //        }
-    //
-    //        // If the biometric unlock is not being used, we don't bother constructing it.  Then we can
-    //        // simply check if it is null when deciding whether we should make calls to it.
-    //        mBiometricUnlock = null;
-    //        if (useBiometricUnlock()) {
-    //            // TODO: make faceLockAreaView a more general biometricUnlockView
-    //            // We will need to add our Face Unlock specific child views programmatically in
-    //            // initializeView rather than having them in the XML files.
-    //            View biometricUnlockView = view.findViewById(
-    //                    com.android.internal.R.id.faceLockAreaView);
-    //            if (biometricUnlockView != null) {
-    //                mBiometricUnlock = new FaceUnlock(mContext, mUpdateMonitor, mLockPatternUtils,
-    //                        mKeyguardScreenCallback);
-    //                mBiometricUnlock.initializeView(biometricUnlockView);
-    //
-    //                // If this is being called because the screen turned off, we want to cover the
-    //                // backup lock so it is covered when the screen turns back on.
-    //                if (!mScreenOn) mBiometricUnlock.show(0);
-    //            } else {
-    //                Log.w(TAG, "Couldn't find biometric unlock view");
-    //            }
-    //        }
-    //
-    //        if (mBiometricUnlock != null && restartBiometricUnlock) {
-    //            maybeStartBiometricUnlock();
-    //        }
-    //    }
-
-    //    /**
-    //     * Starts the biometric unlock if it should be started based on a number of factors including
-    //     * the mSuppressBiometricUnlock flag.  If it should not be started, it hides the biometric
-    //     * unlock area.
-    //     */
-    //    private void maybeStartBiometricUnlock() {
-    //        if (mBiometricUnlock != null) {
-    //            final boolean backupIsTimedOut = (mUpdateMonitor.getFailedAttempts() >=
-    //                    LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
-    //            if (!mSuppressBiometricUnlock
-    //                    && mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
-    //                    && !mUpdateMonitor.getMaxBiometricUnlockAttemptsReached()
-    //                    && !backupIsTimedOut) {
-    //                mBiometricUnlock.start();
-    //            } else {
-    //                mBiometricUnlock.hide();
-    //            }
-    //        }
-    //}
+        @Override
+        public void onUserSwitched(int userId) {
+            if (mBiometricUnlock != null) {
+                mBiometricUnlock.stop();
+            }
+            mLockPatternUtils.setCurrentUser(userId);
+        }
+    };
 
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index e0ba211..058bf92 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -108,6 +108,7 @@
 
     public KeyguardHostView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mLockPatternUtils = new LockPatternUtils(context);
         mAppWidgetHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID, mOnClickHandler);
         mSecurityModel = new KeyguardSecurityModel(mContext);
 
@@ -130,10 +131,6 @@
 
         // View Flipper
         mViewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);
-        mViewFlipper.setInAnimation(AnimationUtils.loadAnimation(mContext,
-                R.anim.keyguard_security_animate_in));
-        mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mContext,
-                R.anim.keyguard_security_animate_out));
 
         // Initialize all security views
         for (int i = 0; i < mViewIds.length; i++) {
@@ -362,7 +359,7 @@
      * account unlock screen and biometric unlock to show the user's normal unlock.
      */
     private void showBackupSecurity() {
-        SecurityMode currentMode = mSecurityModel.getSecurityMode();
+        SecurityMode currentMode = mSecurityModel.getAlternateFor(mSecurityModel.getSecurityMode());
         SecurityMode backup = mSecurityModel.getBackupFor(currentMode);
         showSecurityScreen(getSecurityViewIdForMode(backup));
     }
@@ -372,8 +369,7 @@
         if (SECURITY_SELECTOR_ID == mCurrentSecurityId) {
             SecurityMode securityMode = mSecurityModel.getSecurityMode();
             // Allow an alternate, such as biometric unlock
-            // TODO: un-comment when face unlock is working again:
-            // securityMode = mSecurityModel.getAlternateFor(securityMode);
+            securityMode = mSecurityModel.getAlternateFor(securityMode);
             int realSecurityId = getSecurityViewIdForMode(securityMode);
             if (SECURITY_SELECTOR_ID == realSecurityId) {
                 finish = true; // no security required
@@ -381,11 +377,28 @@
                 showSecurityScreen(realSecurityId); // switch to the "real" security view
             }
         } else if (authenticated) {
-            if (mCurrentSecurityId == SECURITY_PATTERN_ID
-                || mCurrentSecurityId == SECURITY_PASSWORD_ID
-                || mCurrentSecurityId == SECURITY_ACCOUNT_ID
-                || mCurrentSecurityId == SECURITY_BIOMETRIC_ID) {
-                finish = true;
+            switch (mCurrentSecurityId) {
+                case SECURITY_PATTERN_ID:
+                case SECURITY_PASSWORD_ID:
+                case SECURITY_ACCOUNT_ID:
+                case SECURITY_BIOMETRIC_ID:
+                    finish = true;
+                    break;
+
+                case SECURITY_SIM_PIN_ID:
+                case SECURITY_SIM_PUK_ID:
+                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
+                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
+                    if (securityMode != SecurityMode.None) {
+                        showSecurityScreen(getSecurityViewIdForMode(securityMode));
+                    } else {
+                        finish = true;
+                    }
+                    break;
+
+                default:
+                    showSecurityScreen(SECURITY_SELECTOR_ID);
+                    break;
             }
         } else {
             // Not authenticated but we were asked to dismiss so go back to selector screen.
@@ -480,10 +493,20 @@
         newView.onResume();
 
         mViewMediatorCallback.setNeedsInput(newView.needsInput());
-        mCurrentSecurityId = securityViewId;
 
         // Find and show this child.
         final int childCount = mViewFlipper.getChildCount();
+
+        // If we're go to/from the selector view, do flip animation, otherwise use fade animation.
+        final boolean doFlip = mCurrentSecurityId == SECURITY_SELECTOR_ID
+                || securityViewId == SECURITY_SELECTOR_ID;
+        final int inAnimation = doFlip ? R.anim.keyguard_security_animate_in
+                : R.anim.keyguard_security_fade_in;
+        final int outAnimation = doFlip ? R.anim.keyguard_security_animate_out
+                : R.anim.keyguard_security_fade_out;
+
+        mViewFlipper.setInAnimation(AnimationUtils.loadAnimation(mContext, inAnimation));
+        mViewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mContext, outAnimation));
         for (int i = 0; i < childCount; i++) {
             if (securityViewId == mViewFlipper.getChildAt(i).getId()) {
                 mViewFlipper.setDisplayedChild(i);
@@ -495,6 +518,8 @@
         if (securityViewId == SECURITY_SELECTOR_ID) {
             setOnDismissRunnable(null);
         }
+
+        mCurrentSecurityId = securityViewId;
     }
 
     @Override
@@ -582,7 +607,9 @@
     }
 
     private void maybePopulateWidgets() {
-        if (mLockPatternUtils.getDevicePolicyManager().getKeyguardWidgetsDisabled(null)
+        DevicePolicyManager dpm =
+                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (dpm != null && dpm.getKeyguardWidgetsDisabled(null)
                 != DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_NONE) {
             Log.v(TAG, "Keyguard widgets disabled because of device policy admin");
             return;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index a38b247..28f5e8c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -149,7 +149,6 @@
         mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
         mGlowPadView.setOnTriggerListener(mOnTriggerListener);
         mEmergencyCallButton = (Button) findViewById(R.id.emergency_call_button);
-        KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mInfoCallback);
         updateTargets();
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
index 4861b78..bc55008 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
@@ -32,6 +32,7 @@
 
 import android.util.AttributeSet;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
@@ -56,6 +57,8 @@
     private LockPatternUtils mLockPatternUtils;
     private KeyguardNavigationManager mNavigationManager;
 
+    private volatile boolean mSimCheckInProgress;
+
     public KeyguardSimPinView(Context context) {
         this(context, null);
     }
@@ -129,7 +132,7 @@
             mPin = pin;
         }
 
-        abstract void onSimLockChangedResponse(boolean success);
+        abstract void onSimCheckResponse(boolean success);
 
         @Override
         public void run() {
@@ -138,13 +141,13 @@
                         .checkService("phone")).supplyPin(mPin);
                 post(new Runnable() {
                     public void run() {
-                        onSimLockChangedResponse(result);
+                        onSimCheckResponse(result);
                     }
                 });
             } catch (RemoteException e) {
                 post(new Runnable() {
                     public void run() {
-                        onSimLockChangedResponse(false);
+                        onSimCheckResponse(false);
                     }
                 });
             }
@@ -154,8 +157,10 @@
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
         // Check if this was the result of hitting the enter key
         mCallback.userActivity(DIGIT_PRESS_WAKE_MILLIS);
-        if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
-                || actionId == EditorInfo.IME_ACTION_NEXT) {
+        if (event.getAction() == MotionEvent.ACTION_DOWN && (
+                actionId == EditorInfo.IME_NULL
+                || actionId == EditorInfo.IME_ACTION_DONE
+                || actionId == EditorInfo.IME_ACTION_NEXT)) {
             checkPin();
             return true;
         }
@@ -188,27 +193,31 @@
 
         getSimUnlockProgressDialog().show();
 
-        new CheckSimPin(mPinEntry.getText().toString()) {
-            void onSimLockChangedResponse(final boolean success) {
-                post(new Runnable() {
-                    public void run() {
-                        if (mSimUnlockProgressDialog != null) {
-                            mSimUnlockProgressDialog.hide();
+        if (!mSimCheckInProgress) {
+            mSimCheckInProgress = true; // there should be only one
+            new CheckSimPin(mPinEntry.getText().toString()) {
+                void onSimCheckResponse(final boolean success) {
+                    post(new Runnable() {
+                        public void run() {
+                            if (mSimUnlockProgressDialog != null) {
+                                mSimUnlockProgressDialog.hide();
+                            }
+                            if (success) {
+                                // before closing the keyguard, report back that the sim is unlocked
+                                // so it knows right away.
+                                KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
+                                mCallback.dismiss(true);
+                            } else {
+                                mNavigationManager.setMessage(R.string.kg_password_wrong_pin_code);
+                                mPinEntry.setText("");
+                            }
+                            mCallback.userActivity(0);
+                            mSimCheckInProgress = false;
                         }
-                        if (success) {
-                            // before closing the keyguard, report back that the sim is unlocked
-                            // so it knows right away.
-                            KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
-                            mCallback.dismiss(false); //
-                        } else {
-                            mNavigationManager.setMessage(R.string.kg_password_wrong_pin_code);
-                            mPinEntry.setText("");
-                        }
-                        mCallback.userActivity(0);
-                    }
-                });
-            }
-        }.start();
+                    });
+                }
+            }.start();
+        }
     }
 
     public void setLockPatternUtils(LockPatternUtils utils) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
index 801dfc3..e04bff9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
@@ -27,6 +27,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
@@ -63,6 +64,8 @@
 
     private LockPatternUtils mLockPatternUtils;
 
+    private volatile boolean mCheckInProgress;
+
     public KeyguardSimPukView(Context context) {
         this(context, null);
     }
@@ -233,48 +236,54 @@
 
         getSimUnlockProgressDialog().show();
 
-        new CheckSimPuk(mPukText.getText().toString(),
-                mPinText.getText().toString()) {
-            void onSimLockChangedResponse(final boolean success) {
-                mPinText.post(new Runnable() {
-                    public void run() {
-                        if (mSimUnlockProgressDialog != null) {
-                            mSimUnlockProgressDialog.hide();
+        if (!mCheckInProgress) {
+            mCheckInProgress = true;
+            new CheckSimPuk(mPukText.getText().toString(),
+                    mPinText.getText().toString()) {
+                void onSimLockChangedResponse(final boolean success) {
+                    mPinText.post(new Runnable() {
+                        public void run() {
+                            if (mSimUnlockProgressDialog != null) {
+                                mSimUnlockProgressDialog.hide();
+                            }
+                            if (success) {
+                                mCallback.dismiss(true);
+                            } else {
+                                mNavigationManager.setMessage(R.string.kg_invalid_puk);
+                                mPukText.setText("");
+                                mPinText.setText("");
+                            }
+                            mCheckInProgress = false;
                         }
-                        if (success) {
-                            mCallback.dismiss(true);
-                        } else {
-                            mNavigationManager.setMessage(R.string.kg_invalid_puk);
-                            mPukText.setText("");
-                            mPinText.setText("");
-                        }
-                    }
-                });
-            }
-        }.start();
+                    });
+                }
+            }.start();
+        }
     }
 
     @Override
     public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
         // Check if this was the result of hitting the enter key
         mCallback.userActivity(DIGIT_PRESS_WAKE_MILLIS);
-        if (actionId == EditorInfo.IME_NULL
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            if (actionId == EditorInfo.IME_NULL
                 || actionId == EditorInfo.IME_ACTION_DONE
                 || actionId == EditorInfo.IME_ACTION_NEXT) {
-            if (view == mPukText && mPukText.getText().length() < 8) {
-                mNavigationManager.setMessage(R.string.kg_invalid_sim_puk_hint);
-                mPukText.setText("");
-                mPukText.requestFocus();
-                return true;
-            } else if (view == mPinText) {
-                if (mPinText.getText().length() < 4 || mPinText.getText().length() > 8) {
-                    mNavigationManager.setMessage(R.string.kg_invalid_sim_pin_hint);
-                    mPinText.setText("");
-                    mPinText.requestFocus();
-                } else {
-                    checkPuk();
+                if (view == mPukText && mPukText.getText().length() < 8) {
+                    mNavigationManager.setMessage(R.string.kg_invalid_sim_puk_hint);
+                    mPukText.setText("");
+                    mPukText.requestFocus();
+                    return true;
+                } else if (view == mPinText) {
+                    if (mPinText.getText().length() < 4 || mPinText.getText().length() > 8) {
+                        mNavigationManager.setMessage(R.string.kg_invalid_sim_pin_hint);
+                        mPinText.setText("");
+                        mPinText.requestFocus();
+                    } else {
+                        checkPuk();
+                    }
+                    return true;
                 }
-                return true;
             }
         }
         return false;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
index d6ce967..481e9ad 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
@@ -21,6 +21,8 @@
 import android.widget.GridLayout;
 
 public class KeyguardStatusView extends GridLayout {
+    private KeyguardStatusViewManager mStatusViewManager;
+
     public KeyguardStatusView(Context context) {
         this(context, null, 0);
     }
@@ -38,7 +40,7 @@
         super.onFinishInflate();
 
         // StatusView manages all of the widgets in this view.
-        new KeyguardStatusViewManager(this);
+        mStatusViewManager = new KeyguardStatusViewManager(this);
     }
 
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 39df5a2..281ed19 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -100,7 +100,7 @@
 
     private boolean mClockVisible;
 
-    private ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
+    private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
             mCallbacks = Lists.newArrayList();
     private ContentObserver mContentObserver;
 
@@ -586,39 +586,46 @@
     /**
      * Remove the given observer's callback.
      *
-     * @param observer The observer to remove
+     * @param callback The callback to remove
      */
-    public void removeCallback(Object observer) {
-        mCallbacks.remove(observer);
+    public void removeCallback(KeyguardUpdateMonitorCallback callback) {
+        if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            if (mCallbacks.get(i).get() == callback) {
+                mCallbacks.remove(i);
+            }
+        }
     }
 
     /**
      * Register to receive notifications about general keyguard information
      * (see {@link InfoCallback}.
-     * @param callback The callback.
+     * @param callback The callback to register
      */
     public void registerCallback(KeyguardUpdateMonitorCallback callback) {
-        if (!mCallbacks.contains(callback)) {
-            mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
-            // Notify listener of the current state
-            callback.onRefreshBatteryInfo(mBatteryStatus);
-            callback.onTimeChanged();
-            callback.onRingerModeChanged(mRingMode);
-            callback.onPhoneStateChanged(mPhoneState);
-            callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
-            callback.onClockVisibilityChanged();
-            callback.onSimStateChanged(mSimState);
-        } else {
-            if (DEBUG) Log.e(TAG, "Object tried to add another callback",
-                    new Exception("Called by"));
-        }
-
-        // Clean up any unused references
-        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
-            if (mCallbacks.get(i).get() == null) {
-                mCallbacks.remove(i);
+        if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
+        // Prevent adding duplicate callbacks
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            if (mCallbacks.get(i).get() == callback) {
+                if (DEBUG) Log.e(TAG, "Object tried to add another callback",
+                        new Exception("Called by"));
+                return;
             }
         }
+        mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
+        removeCallback(null); // remove unused references
+        sendUpdates(callback);
+    }
+
+    private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
+        // Notify listener of the current state
+        callback.onRefreshBatteryInfo(mBatteryStatus);
+        callback.onTimeChanged();
+        callback.onRingerModeChanged(mRingMode);
+        callback.onPhoneStateChanged(mPhoneState);
+        callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
+        callback.onClockVisibilityChanged();
+        callback.onSimStateChanged(mSimState);
     }
 
     public void reportClockVisible(boolean visible) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/LockPatternKeyguardView.java
index 0ce87b1..4dc83b6 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/LockPatternKeyguardView.java
@@ -1013,7 +1013,7 @@
             // TODO: make faceLockAreaView a more general biometricUnlockView
             // We will need to add our Face Unlock specific child views programmatically in
             // initializeView rather than having them in the XML files.
-            View biometricUnlockView = view.findViewById(R.id.faceLockAreaView);
+            View biometricUnlockView = view.findViewById(R.id.face_unlock_area_view);
             if (biometricUnlockView != null) {
                 mBiometricUnlock = new FaceUnlock(mContext, mUpdateMonitor, mLockPatternUtils,
                         mKeyguardScreenCallback);
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 40f6ecf..3caba1f 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -151,8 +151,6 @@
     private AtomicFile mPolicyFile;
     private HashSet<String> mBlockedPackages = new HashSet<String>();
 
-    private IDreamManager mSandman;
-
     private static final int DB_VERSION = 1;
 
     private static final String TAG_BODY = "notification-policy";
@@ -658,8 +656,6 @@
     void systemReady() {
         mAudioService = IAudioService.Stub.asInterface(
                 ServiceManager.getService(Context.AUDIO_SERVICE));
-        mSandman = IDreamManager.Stub.asInterface(
-                ServiceManager.getService("dreams"));
 
         // no beeping until we're basically done booting
         mSystemReady = true;
@@ -995,16 +991,6 @@
                         | Notification.FLAG_NO_CLEAR;
             }
 
-            // Stop screensaver if the notification has a full-screen intent.
-            // (like an incoming phone call)
-            if (notification.fullScreenIntent != null && mSandman != null) {
-                try {
-                    mSandman.awaken();
-                } catch (RemoteException e) {
-                    // noop
-                }
-            }
-
             if (notification.icon != 0) {
                 StatusBarNotification n = new StatusBarNotification(pkg, id, tag,
                         r.uid, r.initialPid, score, notification);
@@ -1047,6 +1033,7 @@
             if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
                     && (!(old != null
                         && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
+                    && (r.userId == UserHandle.USER_ALL || r.userId == userId)
                     && mSystemReady) {
 
                 final AudioManager audioManager = (AudioManager) mContext
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index 2c5038e..9edfad6 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -26,7 +26,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.os.Build;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.Message;
@@ -40,8 +39,6 @@
 import android.util.Slog;
 
 import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Calendar;
 
@@ -432,10 +429,11 @@
             }
 
             // If we got here, that means that the system is most likely hung.
+            // First collect stack traces from all threads of the system process.
+            // Then kill this process so that the system will restart.
 
             final String name = (mCurrentMonitor != null) ?
                     mCurrentMonitor.getClass().getName() : "null";
-            Slog.w(TAG, "WATCHDOG PROBLEM IN SYSTEM SERVER: " + name);
             EventLog.writeEvent(EventLogTags.WATCHDOG, name);
 
             ArrayList<Integer> pids = new ArrayList<Integer>();
@@ -470,15 +468,11 @@
                 dropboxThread.join(2000);  // wait up to 2 seconds for it to return.
             } catch (InterruptedException ignored) {}
 
-            // Only kill/crash the process if the debugger is not attached.
+            // Only kill the process if the debugger is not attached.
             if (!Debug.isDebuggerConnected()) {
                 Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
-                if (!Build.TYPE.equals("user")) {
-                    forceCrashDump();
-                } else {
-                    Process.killProcess(Process.myPid());
-                    System.exit(10);
-                }
+                Process.killProcess(Process.myPid());
+                System.exit(10);
             } else {
                 Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
             }
@@ -487,50 +481,6 @@
         }
     }
 
-    private void forceCrashDump() {
-        /* Sync file system to flash the data which is written just before the
-         * crash.
-         */
-        java.lang.Process p = null;
-        try {
-            p = Runtime.getRuntime().exec("sync");
-            if (p != null) {
-                // It is not necessary to check the exit code, here.
-                // 'sync' command always succeeds, and this function returns 0.
-                p.waitFor();
-            } else {
-                Slog.e(TAG, "Failed to execute 'sync' command. (no process handle)");
-            }
-        } catch (Exception e) {
-            // This code is an emergency path to crash MUT. The system already
-            // caused fatal error, and then calls this function to create a
-            // crash dump. This function must run the code below to force a
-            // crash, even if the sync command failed.
-            // Therefore, ignore all exceptions, here.
-            Slog.e(TAG, "Failed to execute 'sync' command prior to forcing crash: " + e);
-        } finally {
-            if (p != null) {
-                p.destroy();
-            }
-        }
-
-        FileWriter out = null;
-        try {
-            out = new FileWriter("/proc/sysrq-trigger");
-            out.write("c");
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to write to sysrq-trigger while triggering crash: " + e);
-        } finally {
-            if (out != null) {
-                try {
-                    out.close();
-                } catch (IOException e) {
-                    Slog.e(TAG, "Failed to close sysrq-trigger while triggering crash: " + e);
-                }
-            }
-        }
-    }
-
     private File dumpKernelStackTraces() {
         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
         if (tracesPath == null || tracesPath.length() == 0) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e670da0..614b93a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -10621,7 +10621,9 @@
                     restart = true;
                 } else {
                     removeDyingProviderLocked(app, cpr, true);
+                    // cpr should have been removed from mLaunchingProviders
                     NL = mLaunchingProviders.size();
+                    i--;
                 }
             }
         }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java
index e8cdbc3..7ea2a62d 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java
@@ -113,6 +113,12 @@
                 canvas.rotate(45);
                 canvas.drawRect(0, 0, 20, 10, p);
                 canvas.restore();
+                canvas.save();
+                canvas.translate(mOffset + 280, yOffset);
+                canvas.scale(0.5f, 8);
+                canvas.rotate(0.5f);
+                canvas.drawRect(0, 0, 80, 5, p);
+                canvas.restore();
                 canvas.restore();
 
                 yOffset += 100;
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java
new file mode 100644
index 0000000..87a2de1
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ColorMatrix.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.ScriptGroup;
+import android.renderscript.ScriptIntrinsicColorMatrix;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class ColorMatrix extends TestBase {
+    private ScriptC_colormatrix mScript;
+    private ScriptIntrinsicColorMatrix mIntrinsic;
+    private boolean mUseIntrinsic;
+
+    public ColorMatrix(boolean useIntrinsic) {
+        mUseIntrinsic = useIntrinsic;
+    }
+
+    public void createTest(android.content.res.Resources res) {
+        Matrix4f m = new Matrix4f();
+        m.set(1, 0, 0.2f);
+        m.set(1, 1, 0.9f);
+        m.set(1, 2, 0.2f);
+
+        if (mUseIntrinsic) {
+            mIntrinsic = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
+            mIntrinsic.setColorMatrix(m);
+        } else {
+            mScript = new ScriptC_colormatrix(mRS, res, R.raw.colormatrix);
+            mScript.invoke_setMatrix(m);
+        }
+    }
+
+    public void runTest() {
+        if (mUseIntrinsic) {
+            mIntrinsic.forEach(mInPixelsAllocation, mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+        }
+    }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Convolve3x3.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Convolve3x3.java
new file mode 100644
index 0000000..51794db
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Convolve3x3.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.ScriptGroup;
+import android.renderscript.ScriptIntrinsicConvolve3x3;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class Convolve3x3 extends TestBase {
+    private ScriptC_convolve3x3 mScript;
+    private ScriptIntrinsicConvolve3x3 mIntrinsic;
+
+    private int mWidth;
+    private int mHeight;
+    private boolean mUseIntrinsic;
+
+    public Convolve3x3(boolean useIntrinsic) {
+        mUseIntrinsic = useIntrinsic;
+    }
+
+    public void createTest(android.content.res.Resources res) {
+        mWidth = mInPixelsAllocation.getType().getX();
+        mHeight = mInPixelsAllocation.getType().getY();
+
+        float f[] = new float[9];
+        f[0] =  0.f;    f[1] = -1.f;    f[2] =  0.f;
+        f[3] = -1.f;    f[4] =  5.f;    f[5] = -1.f;
+        f[6] =  0.f;    f[7] = -1.f;    f[8] =  0.f;
+
+        if (mUseIntrinsic) {
+            mIntrinsic = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS));
+            mIntrinsic.setColorMatrix(f);
+            mIntrinsic.setInput(mInPixelsAllocation);
+        } else {
+            mScript = new ScriptC_convolve3x3(mRS, res, R.raw.convolve3x3);
+            mScript.set_gCoeffs(f);
+            mScript.set_gIn(mInPixelsAllocation);
+            mScript.set_gWidth(mWidth);
+            mScript.set_gHeight(mHeight);
+        }
+    }
+
+    public void runTest() {
+        if (mUseIntrinsic) {
+            mIntrinsic.forEach(mOutPixelsAllocation);
+        } else {
+            mScript.forEach_root(mOutPixelsAllocation);
+        }
+    }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Copy.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Copy.java
new file mode 100644
index 0000000..efca0b5
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Copy.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image;
+
+import java.lang.Math;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class Copy extends TestBase {
+    private ScriptC_copy mScript;
+
+    public void createTest(android.content.res.Resources res) {
+        mScript = new ScriptC_copy(mRS, res, R.raw.copy);
+    }
+
+    public void runTest() {
+        mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
+    }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 327ff06..001dea8 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -174,7 +174,19 @@
             mTest = new GroupTest(true);
             break;
         case 17:
-            mTest = new Intrinsics(0);
+            mTest = new Convolve3x3(false);
+            break;
+        case 18:
+            mTest = new Convolve3x3(true);
+            break;
+        case 19:
+            mTest = new ColorMatrix(false);
+            break;
+        case 20:
+            mTest = new ColorMatrix(true);
+            break;
+        case 21:
+            mTest = new Copy();
             break;
         }
 
@@ -188,7 +200,7 @@
     }
 
     void setupTests() {
-        mTestNames = new String[18];
+        mTestNames = new String[22];
         mTestNames[0] = "Levels Vec3 Relaxed";
         mTestNames[1] = "Levels Vec4 Relaxed";
         mTestNames[2] = "Levels Vec3 Full";
@@ -206,7 +218,11 @@
         mTestNames[14] = "Vignette Approximate Relaxed";
         mTestNames[15] = "Group Test (emulated)";
         mTestNames[16] = "Group Test (native)";
-        mTestNames[17] = "Intrinsics Convolve 3x3";
+        mTestNames[17] = "Convolve 3x3";
+        mTestNames[18] = "Intrinsics Convolve 3x3";
+        mTestNames[19] = "ColorMatrix";
+        mTestNames[20] = "Intrinsics ColorMatrix";
+        mTestNames[21] = "Copy";
         mTestSpinner.setAdapter(new ArrayAdapter<String>(
             this, R.layout.spinner_layout, mTestNames));
     }
@@ -280,14 +296,14 @@
 
     // button hook
     public void benchmark(View v) {
-        long t = getBenchmark();
+        float t = getBenchmark();
         //long javaTime = javaFilter();
         //mBenchmarkResult.setText("RS: " + t + " ms  Java: " + javaTime + " ms");
         mBenchmarkResult.setText("Result: " + t + " ms");
     }
 
     // For benchmark test
-    public long getBenchmark() {
+    public float getBenchmark() {
         mDoingBenchmark = true;
 
         mTest.setupBenchmark();
@@ -303,14 +319,18 @@
 
         Log.v(TAG, "Benchmarking");
         t = java.lang.System.currentTimeMillis();
-        mTest.runTest();
+        for (int i=0; i<10; i++) {
+            mTest.runTest();
+        }
         mTest.finish();
         t = java.lang.System.currentTimeMillis() - t;
+        float ft = (float)t;
+        ft /= 10;
 
-        Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t);
+        Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + ft);
         mTest.exitBenchmark();
         mDoingBenchmark = false;
 
-        return t;
+        return ft;
     }
 }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
index 912d863..f995437 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
@@ -78,7 +78,7 @@
             BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
             Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
             for (int i = 0; i < ITERATION; i++ ) {
-                t = mAct.getBenchmark();
+                t = (long)mAct.getBenchmark();
                 sum += t;
                 rsWriter.write("Renderscript frame time core: " + t + " ms\n");
                 Log.v(TAG, "RenderScript framew time core: " + t + " ms");
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Intrinsics.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Intrinsics.java
deleted file mode 100644
index dab8111..0000000
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Intrinsics.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.rs.image;
-
-import java.lang.Math;
-
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RenderScript;
-import android.renderscript.Script;
-import android.renderscript.ScriptIntrinsicConvolve3x3;
-import android.renderscript.Type;
-import android.util.Log;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-public class Intrinsics extends TestBase {
-    private ScriptIntrinsicConvolve3x3 mScript;
-
-    Intrinsics(int id) {
-    }
-
-    public boolean onBar1Setup(SeekBar b, TextView t) {
-        t.setText("Strength");
-        b.setProgress(50);
-        return true;
-    }
-
-    public void onBar1Changed(int progress) {
-        float s = progress / 100.0f;
-        float v[] = new float[9];
-        v[0] = 0.f;     v[1] = -s;      v[2] = 0.f;
-        v[3] = -s;      v[4] = s*4+1;   v[5] = -s;
-        v[6] = 0.f;     v[7] = -s;      v[8] = 0.f;
-        mScript.setColorMatrix(v);
-    }
-
-
-    public void createTest(android.content.res.Resources res) {
-        mScript = ScriptIntrinsicConvolve3x3.create(mRS, Element.RGBA_8888(mRS));
-    }
-
-    public void runTest() {
-        mScript.setInput(mInPixelsAllocation);
-        mScript.forEach(mOutPixelsAllocation);
-    }
-
-}
-
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
index b6b4a0f..455fcc2 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
@@ -25,9 +25,9 @@
 float gCoeffs[9];
 
 void root(uchar4 *out, uint32_t x, uint32_t y) {
-    uint32_t x1 = min((int32_t)x+1, gWidth);
+    uint32_t x1 = min((int32_t)x+1, gWidth-1);
     uint32_t x2 = max((int32_t)x-1, 0);
-    uint32_t y1 = min((int32_t)y+1, gHeight);
+    uint32_t y1 = min((int32_t)y+1, gHeight-1);
     uint32_t y2 = max((int32_t)y-1, 0);
 
     float4 p00 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y1))[0]);
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs
new file mode 100644
index 0000000..9eb5d43
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image)
+
+void root(const uchar4 *v_in, uchar4 *v_out) {
+    *v_out = *v_in;
+}
+
+
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index b9feb34..805faa6 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -500,6 +500,14 @@
         }
     }
 
+    public boolean setWfdEnable(boolean enable) {
+        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
+    }
+
+    public boolean setWfdDeviceInfo(String hex) {
+        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
+    }
+
     /**
      * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
      * P2P connection over STA
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index c86ec8b..117af82 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -107,12 +107,14 @@
     /** Device connection status */
     public int status = UNAVAILABLE;
 
-    /** Detailed device string pattern
+    /** @hide */
+    public WifiP2pWfdInfo wfdInfo;
+
+    /** Detailed device string pattern with WFD info
      * Example:
-     *  P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13
-     *  pri_dev_type=1-0050F204-1 name='p2p-TEST1' config_methods=0x188 dev_capab=0x27
-     *  group_capab=0x0
-     *
+     *  P2P-DEVICE-FOUND 00:18:6b:de:a3:6e p2p_dev_addr=00:18:6b:de:a3:6e
+     *  pri_dev_type=1-0050F204-1 name='DWD-300-DEA36E' config_methods=0x188
+     *  dev_capab=0x21 group_capab=0x9
      */
     private static final Pattern detailedDevicePattern = Pattern.compile(
         "((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
@@ -273,6 +275,7 @@
         sbuf.append("\n grpcapab: ").append(groupCapability);
         sbuf.append("\n devcapab: ").append(deviceCapability);
         sbuf.append("\n status: ").append(status);
+        sbuf.append("\n wfdInfo: ").append(wfdInfo);
         return sbuf.toString();
     }
 
@@ -292,6 +295,7 @@
             deviceCapability = source.deviceCapability;
             groupCapability = source.groupCapability;
             status = source.status;
+            wfdInfo = source.wfdInfo;
         }
     }
 
@@ -305,6 +309,12 @@
         dest.writeInt(deviceCapability);
         dest.writeInt(groupCapability);
         dest.writeInt(status);
+        if (wfdInfo != null) {
+            dest.writeInt(1);
+            wfdInfo.writeToParcel(dest, flags);
+        } else {
+            dest.writeInt(0);
+        }
     }
 
     /** Implement the Parcelable interface */
@@ -320,6 +330,9 @@
                 device.deviceCapability = in.readInt();
                 device.groupCapability = in.readInt();
                 device.status = in.readInt();
+                if (in.readInt() == 1) {
+                    device.wfdInfo = WifiP2pWfdInfo.CREATOR.createFromParcel(in);
+                }
                 return device;
             }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
index dce315a..8972b7e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
@@ -44,8 +44,8 @@
     public String toString() {
         StringBuffer sbuf = new StringBuffer();
         sbuf.append("groupFormed: ").append(groupFormed)
-            .append("isGroupOwner: ").append(isGroupOwner)
-            .append("groupOwnerAddress: ").append(groupOwnerAddress);
+            .append(" isGroupOwner: ").append(isGroupOwner)
+            .append(" groupOwnerAddress: ").append(groupOwnerAddress);
         return sbuf.toString();
     }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 96d3a7f..6edc232 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -455,6 +455,13 @@
     /** @hide */
     public static final int RESPONSE_PERSISTENT_GROUP_INFO          = BASE + 63;
 
+    /** @hide */
+    public static final int SET_WFD_INFO                            = BASE + 64;
+    /** @hide */
+    public static final int SET_WFD_INFO_FAILED                     = BASE + 65;
+    /** @hide */
+    public static final int SET_WFD_INFO_SUCCEEDED                  = BASE + 66;
+
     /**
      * Create a new WifiP2pManager instance. Applications use
      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -742,6 +749,7 @@
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED:
                     case WifiP2pManager.SET_DEVICE_NAME_FAILED:
                     case WifiP2pManager.DELETE_PERSISTENT_GROUP_FAILED:
+                    case WifiP2pManager.SET_WFD_INFO_FAILED:
                         if (listener != null) {
                             ((ActionListener) listener).onFailure(message.arg1);
                         }
@@ -762,6 +770,7 @@
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED:
                     case WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED:
                     case WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED:
+                    case WifiP2pManager.SET_WFD_INFO_SUCCEEDED:
                         if (listener != null) {
                             ((ActionListener) listener).onSuccess();
                         }
@@ -1297,6 +1306,13 @@
         c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
     }
 
+    /** @hide */
+    public void setWFDInfo(
+            Channel c, WifiP2pWfdInfo wfdInfo,
+            ActionListener listener) {
+        checkChannel(c);
+        c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo);
+    }
 
     /**
      * Set dialog listener to over-ride system dialogs on p2p events. This function
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index c34d70e..acb7e52 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -496,6 +496,10 @@
                     replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
                             WifiP2pManager.BUSY);
                     break;
+                case WifiP2pManager.SET_WFD_INFO:
+                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
+                            WifiP2pManager.BUSY);
+                    break;
                 case WifiP2pManager.REQUEST_PEERS:
                     replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
                     break;
@@ -629,6 +633,10 @@
                     replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
+                case WifiP2pManager.SET_WFD_INFO:
+                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
                default:
                     return NOT_HANDLED;
             }
@@ -741,6 +749,7 @@
                     transitionTo(mP2pDisablingState);
                     break;
                 case WifiP2pManager.SET_DEVICE_NAME:
+                {
                     WifiP2pDevice d = (WifiP2pDevice) message.obj;
                     if (d != null && setAndPersistDeviceName(d.deviceName)) {
                         if (DBG) logd("set device name " + d.deviceName);
@@ -750,6 +759,18 @@
                                 WifiP2pManager.ERROR);
                     }
                     break;
+                }
+                case WifiP2pManager.SET_WFD_INFO:
+                {
+                    WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
+                    if (d != null && setWfdInfo(d)) {
+                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
+                                WifiP2pManager.ERROR);
+                    }
+                    break;
+                }
                 case WifiP2pManager.DISCOVER_PEERS:
                     // do not send service discovery request while normal find operation.
                     clearSupplicantServiceRequest();
@@ -2018,6 +2039,27 @@
         return true;
     }
 
+    private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
+        boolean success;
+
+        if (!wfdInfo.isWfdEnabled()) {
+            success = mWifiNative.setWfdEnable(false);
+        } else {
+            success =
+                mWifiNative.setWfdEnable(true)
+                && mWifiNative.setWfdDeviceInfo(wfdInfo.getDeviceInfoHex());
+        }
+
+        if (!success) {
+            loge("Failed to set wfd properties");
+            return false;
+        }
+
+        mThisDevice.wfdInfo = wfdInfo;
+        sendThisDeviceChangedBroadcast();
+        return true;
+    }
+
     private void initializeP2pSettings() {
         mWifiNative.setPersistentReconnect(true);
         mThisDevice.deviceName = getPersistedDeviceName();
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
new file mode 100644
index 0000000..9dd3e4a
--- /dev/null
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.p2p;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+/**
+ * A class representing Wifi Display information for a device
+ * @hide
+ */
+public class WifiP2pWfdInfo implements Parcelable {
+
+    private static final String TAG = "WifiP2pWfdInfo";
+
+    private boolean mWfdEnabled;
+
+    private int mDeviceInfo;
+
+    public static final int WFD_SOURCE              = 0;
+    public static final int PRIMARY_SINK            = 1;
+    public static final int SECONDARY_SINK          = 2;
+    public static final int SOURCE_OR_PRIMARY_SINK  = 3;
+
+    /* Device information bitmap */
+    /** One of {@link #WFD_SOURCE}, {@link #PRIMARY_SINK}, {@link #SECONDARY_SINK}
+     * or {@link #SOURCE_OR_PRIMARY_SINK}
+     */
+    private static final int DEVICE_TYPE                            = 0x3;
+    private static final int COUPLED_SINK_SUPPORT_AT_SOURCE         = 0x4;
+    private static final int COUPLED_SINK_SUPPORT_AT_SINK           = 0x8;
+    private static final int SESSION_AVAILABLE                      = 0x30;
+    private static final int SESSION_AVAILABLE_BIT1                 = 0x10;
+    private static final int SESSION_AVAILABLE_BIT2                 = 0x20;
+
+    private int mCtrlPort;
+
+    private int mMaxThroughput;
+
+    public WifiP2pWfdInfo() {
+    }
+
+    public boolean isWfdEnabled() {
+        return mWfdEnabled;
+    }
+
+    public void setWfdEnabled(boolean enabled) {
+        mWfdEnabled = enabled;
+    }
+
+    public int getDeviceType() {
+        return (mDeviceInfo & DEVICE_TYPE);
+    }
+
+    public boolean setDeviceType(int deviceType) {
+        if (deviceType >= WFD_SOURCE && deviceType <= SOURCE_OR_PRIMARY_SINK) {
+            mDeviceInfo |= deviceType;
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isCoupledSinkSupportedAtSource() {
+        return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0;
+    }
+
+    public void setCoupledSinkSupportAtSource(boolean enabled) {
+        if (enabled ) {
+            mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK;
+        } else {
+            mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK;
+        }
+    }
+
+    public boolean isCoupledSinkSupportedAtSink() {
+        return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0;
+    }
+
+    public void setCoupledSinkSupportAtSink(boolean enabled) {
+        if (enabled ) {
+            mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK;
+        } else {
+            mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK;
+        }
+    }
+
+    public boolean isSessionAvailable() {
+        return (mDeviceInfo & SESSION_AVAILABLE) != 0;
+    }
+
+    public void setSessionAvailable(boolean enabled) {
+        if (enabled) {
+            mDeviceInfo |= SESSION_AVAILABLE_BIT1;
+            mDeviceInfo &= ~SESSION_AVAILABLE_BIT2;
+        } else {
+            mDeviceInfo &= ~SESSION_AVAILABLE;
+        }
+    }
+
+    public int getControlPort() {
+        return mCtrlPort;
+    }
+
+    public void setControlPort(int port) {
+        mCtrlPort = port;
+    }
+
+    public void setMaxThroughput(int maxThroughput) {
+        mMaxThroughput = maxThroughput;
+    }
+
+    public int getMaxThroughput() {
+        return mMaxThroughput;
+    }
+
+    public String getDeviceInfoHex() {
+        return String.format("%04x%04x%04x%04x", 6, mDeviceInfo, mCtrlPort, mMaxThroughput);
+    }
+
+    public String toString() {
+        StringBuffer sbuf = new StringBuffer();
+        sbuf.append("WFD enabled: ").append(mWfdEnabled);
+        sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo);
+        sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort);
+        sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput);
+        return sbuf.toString();
+    }
+
+    /** Implement the Parcelable interface */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** copy constructor */
+    public WifiP2pWfdInfo(WifiP2pWfdInfo source) {
+        if (source != null) {
+            mDeviceInfo = source.mDeviceInfo;
+            mCtrlPort = source.mCtrlPort;
+            mMaxThroughput = source.mMaxThroughput;
+        }
+    }
+
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mWfdEnabled ? 1 : 0);
+        dest.writeInt(mDeviceInfo);
+        dest.writeInt(mCtrlPort);
+        dest.writeInt(mMaxThroughput);
+    }
+
+    public void readFromParcel(Parcel in) {
+        mWfdEnabled = (in.readInt() == 1);
+        mDeviceInfo = in.readInt();
+        mCtrlPort = in.readInt();
+        mMaxThroughput = in.readInt();
+    }
+
+    /** Implement the Parcelable interface */
+    public static final Creator<WifiP2pWfdInfo> CREATOR =
+        new Creator<WifiP2pWfdInfo>() {
+            public WifiP2pWfdInfo createFromParcel(Parcel in) {
+                WifiP2pWfdInfo device = new WifiP2pWfdInfo();
+                device.readFromParcel(in);
+                return device;
+            }
+
+            public WifiP2pWfdInfo[] newArray(int size) {
+                return new WifiP2pWfdInfo[size];
+            }
+        };
+}