Merge "Surface: fix a protected buffer test" into ics-mr0
diff --git a/Android.mk b/Android.mk
index a38723a..32dee5f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -402,8 +402,8 @@
 		            resources/samples/AccelerometerPlay "Accelerometer Play" \
 		-samplecode $(sample_dir)/ActionBarCompat \
 		            resources/samples/ActionBarCompat "Action Bar Compatibility" \
-                -samplecode $(sample_dir)/AndroidBeam \
-		            resources/samples/AndroidBeam "Android Beam" \
+                -samplecode $(sample_dir)/AndroidBeamDemo \
+		            resources/samples/AndroidBeam "Android Beam Demo" \
 		-samplecode $(sample_dir)/ApiDemos \
 		            resources/samples/ApiDemos "API Demos" \
 		-samplecode $(sample_dir)/Support4Demos \
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index 448b2c0..acc8549 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -43,7 +43,7 @@
  * @hide
  */
 public class ChooseAccountTypeActivity extends Activity {
-    private static final String TAG = "AccountManager";
+    private static final String TAG = "AccountChooser";
 
     private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>();
     private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay;
@@ -52,6 +52,11 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState="
+                    + savedInstanceState + ")");
+        }
+
         // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes
         Set<String> setOfAllowableAccountTypes = null;
         String[] validAccountTypes = getIntent().getStringArrayExtra(
@@ -111,8 +116,10 @@
         Bundle bundle = new Bundle();
         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
         setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
-        Log.d(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
-                + "selected account type " + type);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
+                    + "selected account type " + type);
+        }
         finish();
     }
 
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 8cc2002..5f38eb4 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -47,7 +47,7 @@
  */
 public class ChooseTypeAndAccountActivity extends Activity
         implements AccountManagerCallback<Bundle> {
-    private static final String TAG = "AccountManager";
+    private static final String TAG = "AccountChooser";
 
     /**
      * A Parcelable ArrayList of Account objects that limits the choosable accounts to those
@@ -100,13 +100,39 @@
     public static final String EXTRA_DESCRIPTION_TEXT_OVERRIDE =
             "descriptionTextOverride";
 
+    public static final int REQUEST_NULL = 0;
+    public static final int REQUEST_CHOOSE_TYPE = 1;
+    public static final int REQUEST_ADD_ACCOUNT = 2;
+
+    private static final String KEY_INSTANCE_STATE_PENDING_REQUEST = "pendingRequest";
+    private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
+
     private ArrayList<AccountInfo> mAccountInfos;
+    private int mPendingRequest = REQUEST_NULL;
+    private Parcelable[] mExistingAccounts = null;
+    private Parcelable[] mSavedAccounts = null;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onCreate(savedInstanceState="
+                    + savedInstanceState + ")");
+        }
+
         setContentView(R.layout.choose_type_and_account);
 
+        if (savedInstanceState != null) {
+            mPendingRequest = savedInstanceState.getInt(KEY_INSTANCE_STATE_PENDING_REQUEST);
+            mSavedAccounts =
+                    savedInstanceState.getParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS);
+            mExistingAccounts = null;
+        } else {
+            mPendingRequest = REQUEST_NULL;
+            mSavedAccounts = null;
+            mExistingAccounts = null;
+        }
+
         // save some items we use frequently
         final AccountManager accountManager = AccountManager.get(this);
         final Intent intent = getIntent();
@@ -171,20 +197,6 @@
                     account.equals(selectedAccount)));
         }
 
-        // If there are no allowable accounts go directly to add account
-        if (mAccountInfos.isEmpty()) {
-            startChooseAccountTypeActivity();
-            return;
-        }
-
-        // if there is only one allowable account return it
-        if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
-                && mAccountInfos.size() == 1) {
-            Account account = mAccountInfos.get(0).account;
-            setResultAndFinish(account.name, account.type);
-            return;
-        }
-
         // there is more than one allowable account. initialize the list adapter to allow
         // the user to select an account.
         ListView list = (ListView) findViewById(android.R.id.list);
@@ -204,6 +216,37 @@
                 startChooseAccountTypeActivity();
             }
         });
+
+        if (mPendingRequest == REQUEST_NULL) {
+            // If there are no allowable accounts go directly to add account
+            if (mAccountInfos.isEmpty()) {
+                startChooseAccountTypeActivity();
+                return;
+            }
+
+            // if there is only one allowable account return it
+            if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
+                    && mAccountInfos.size() == 1) {
+                Account account = mAccountInfos.get(0).account;
+                setResultAndFinish(account.name, account.type);
+                return;
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onDestroy()");
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    protected void onSaveInstanceState(final Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(KEY_INSTANCE_STATE_PENDING_REQUEST, mPendingRequest);
+        outState.putParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS, mExistingAccounts);
     }
 
     // Called when the choose account type activity (for adding an account) returns.
@@ -212,20 +255,75 @@
     @Override
     protected void onActivityResult(final int requestCode, final int resultCode,
             final Intent data) {
-        if (resultCode == RESULT_OK && data != null) {
-            String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
-            if (accountType != null) {
-                runAddAccountForAuthenticator(accountType);
-                return;
-            }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            if (data != null && data.getExtras() != null) data.getExtras().keySet();
+            Bundle extras = data != null ? data.getExtras() : null;
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onActivityResult(reqCode=" + requestCode
+                    + ", resCode=" + resultCode + ", extras=" + extras + ")");
         }
-        Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: canceled");
+
+        // we got our result, so clear the fact that we had a pending request
+        mPendingRequest = REQUEST_NULL;
+        mExistingAccounts = null;
+
+        if (resultCode == RESULT_CANCELED) {
+            return;
+        }
+
+        if (resultCode == RESULT_OK) {
+            if (requestCode == REQUEST_CHOOSE_TYPE) {
+                if (data != null) {
+                    String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
+                    if (accountType != null) {
+                        runAddAccountForAuthenticator(accountType);
+                        return;
+                    }
+                }
+                Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: unable to find account "
+                        + "type, pretending the request was canceled");
+            } else if (requestCode == REQUEST_ADD_ACCOUNT) {
+                String accountName = null;
+                String accountType = null;
+
+                if (data != null) {
+                    accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
+                    accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
+                }
+
+                if (accountName == null || accountType == null) {
+                    Account[] currentAccounts = AccountManager.get(this).getAccounts();
+                    Set<Account> preExistingAccounts = new HashSet<Account>();
+                    for (Parcelable accountParcel : mSavedAccounts) {
+                        preExistingAccounts.add((Account) accountParcel);
+                    }
+                    for (Account account : currentAccounts) {
+                        if (!preExistingAccounts.contains(account)) {
+                            accountName = account.name;
+                            accountType = account.type;
+                            break;
+                        }
+                    }
+                }
+
+                if (accountName != null || accountType != null) {
+                    setResultAndFinish(accountName, accountType);
+                    return;
+                }
+            }
+            Log.d(TAG, "ChooseTypeAndAccountActivity.onActivityResult: unable to find added "
+                    + "account, pretending the request was canceled");
+        }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.onActivityResult: canceled");
+        }
         setResult(Activity.RESULT_CANCELED);
         finish();
     }
 
     protected void runAddAccountForAuthenticator(String type) {
-        Log.d(TAG, "selected account type " + type);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "runAddAccountForAuthenticator: " + type);
+        }
         final Bundle options = getIntent().getBundleExtra(
                 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE);
         final String[] requiredFeatures = getIntent().getStringArrayExtra(
@@ -233,20 +331,19 @@
         final String authTokenType = getIntent().getStringExtra(
                 ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING);
         AccountManager.get(this).addAccount(type, authTokenType, requiredFeatures,
-                options, this, this, null /* Handler */);
+                options, null /* activity */, this /* callback */, null /* Handler */);
     }
 
     public void run(final AccountManagerFuture<Bundle> accountManagerFuture) {
         try {
             final Bundle accountManagerResult = accountManagerFuture.getResult();
-            final String name = accountManagerResult.getString(AccountManager.KEY_ACCOUNT_NAME);
-            final String type = accountManagerResult.getString(AccountManager.KEY_ACCOUNT_TYPE);
-            if (name != null && type != null) {
-                final Bundle bundle = new Bundle();
-                bundle.putString(AccountManager.KEY_ACCOUNT_NAME, name);
-                bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
-                setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
-                finish();
+            final Intent intent = (Intent)accountManagerResult.getParcelable(
+                    AccountManager.KEY_INTENT);
+            if (intent != null) {
+                mPendingRequest = REQUEST_ADD_ACCOUNT;
+                mExistingAccounts = AccountManager.get(this).getAccounts();
+                intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivityForResult(intent, REQUEST_ADD_ACCOUNT);
                 return;
             }
         } catch (OperationCanceledException e) {
@@ -297,12 +394,17 @@
         bundle.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
         setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
-        Log.d(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
-                + "selected account " + accountName + ", " + accountType);
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: "
+                    + "selected account " + accountName + ", " + accountType);
+        }
         finish();
     }
 
     private void startChooseAccountTypeActivity() {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "ChooseAccountTypeActivity.startChooseAccountTypeActivity()");
+        }
         final Intent intent = new Intent(this, ChooseAccountTypeActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
         intent.putExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY,
@@ -313,7 +415,8 @@
                 getIntent().getStringArrayExtra(EXTRA_ADD_ACCOUNT_REQUIRED_FEATURES_STRING_ARRAY));
         intent.putExtra(EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING,
                 getIntent().getStringExtra(EXTRA_ADD_ACCOUNT_AUTH_TOKEN_TYPE_STRING));
-        startActivityForResult(intent, 0);
+        startActivityForResult(intent, REQUEST_CHOOSE_TYPE);
+        mPendingRequest = REQUEST_CHOOSE_TYPE;
     }
 
     private static class AccountInfo {
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index c09e87f..e37b3fa 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -54,6 +54,12 @@
  * without text editors, so that it will be placed on top of the current
  * input method UI.  You can modify this behavior by forcing the flag to your
  * desired mode after calling {@link #onCreate}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating dialogs, read the
+ * <a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a> developer guide.</p>
+ * </div>
  */
 public class AlertDialog extends Dialog implements DialogInterface {
     private AlertController mAlert;
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 82186dd..7a69419 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -66,9 +66,14 @@
  * your Dialog takes input focus, as it the default) with the following code:
  * 
  * <pre>
- *     getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
- *             WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- * </pre>
+ * getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ *         WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);</pre>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating dialogs, read the
+ * <a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a> developer guide.</p>
+ * </div>
  */
 public class Dialog implements DialogInterface, Window.Callback,
         KeyEvent.Callback, OnCreateContextMenuListener {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9490b96..f5add25 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -38,9 +38,12 @@
  * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
  * easier to construct Notifications.</p>
  *
- * <p>For a guide to creating notifications, see the
- * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status 
- * Bar Notifications</a> document in the Dev Guide.</p>
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to creating notifications, read the
+ * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
+ * developer guide.</p>
+ * </div>
  */
 public class Notification implements Parcelable
 {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 4913e78..bf83f5e 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -55,6 +55,13 @@
  * You do not instantiate this class directly; instead, retrieve it through
  * {@link android.content.Context#getSystemService}.
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to creating notifications, read the
+ * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
+ * developer guide.</p>
+ * </div>
+ *
  * @see android.app.Notification
  * @see android.content.Context#getSystemService
  */
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index ca64c88..c5ee48d 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -40,15 +40,20 @@
     public static final int DISABLE_NOTIFICATION_TICKER
             = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
     public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
-    public static final int DISABLE_NAVIGATION = View.STATUS_BAR_DISABLE_NAVIGATION;
+    public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
+    public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
     public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
     public static final int DISABLE_CLOCK = View.STATUS_BAR_DISABLE_CLOCK;
 
+    @Deprecated
+    public static final int DISABLE_NAVIGATION = 
+            View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT;
+
     public static final int DISABLE_NONE = 0x00000000;
 
     public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS
             | DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
-            | DISABLE_SYSTEM_INFO| DISABLE_NAVIGATION | DISABLE_BACK | DISABLE_CLOCK;
+            | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK;
 
     private Context mContext;
     private IStatusBarService mService;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index e452f1f..092a0c8 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -45,9 +45,6 @@
  * multiple applications you can use a database directly via
  * {@link android.database.sqlite.SQLiteDatabase}.
  *
- * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
- * Providers</a>.</p>
- *
  * <p>When a request is made via
  * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
  * request to the content provider registered with the authority. The content provider can interpret
@@ -73,6 +70,12 @@
  * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
  * ContentProvider instance, so subclasses don't have to worry about the details of
  * cross-process calls.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using content providers, read the
+ * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ * developer guide.</p>
  */
 public abstract class ContentProvider implements ComponentCallbacks2 {
     private static final String TAG = "ContentProvider";
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0d25926..e923349 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -54,6 +54,12 @@
 
 /**
  * This class provides applications access to the content model.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using a ContentResolver with content providers, read the
+ * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
+ * developer guide.</p>
  */
 public abstract class ContentResolver {
     /**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2be5153..45a42e4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -57,8 +57,8 @@
  *
  * <p>An Intent provides a facility for performing late runtime binding between the code in
  * different applications. Its most significant use is in the launching of activities, where it
- * can be thought of as the glue between activities. It is basically a passive data structure 
- * holding an abstract description of an action to be performed.</p> 
+ * can be thought of as the glue between activities. It is basically a passive data structure
+ * holding an abstract description of an action to be performed.</p>
  *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
@@ -2566,7 +2566,7 @@
      */
     public static final String EXTRA_LOCAL_ONLY =
         "android.intent.extra.LOCAL_ONLY";
-    
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
@@ -5291,7 +5291,7 @@
         if (r != null) {
             mSourceBounds = new Rect(r);
         } else {
-            r = null;
+            mSourceBounds = null;
         }
     }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7a7e4f4..3eb7647 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2124,6 +2124,9 @@
         if (pkg == null) {
             return null;
         }
+        if ((flags & GET_SIGNATURES) != 0) {
+            packageParser.collectCertificates(pkg, 0);
+        }
         return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0);
     }
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 9bd4a3b..d338764 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -337,7 +337,7 @@
      * Camera objects are locked by default unless {@link #unlock()} is
      * called.  Normally {@link #reconnect()} is used instead.
      *
-     * <p>Since API level 13, camera is automatically locked for applications in
+     * <p>Since API level 14, camera is automatically locked for applications in
      * {@link android.media.MediaRecorder#start()}. Applications can use the
      * camera (ex: zoom) after recording starts. There is no need to call this
      * after recording starts or stops.
@@ -356,7 +356,7 @@
      * which will re-acquire the lock and allow you to continue using the
      * camera.
      *
-     * <p>Since API level 13, camera is automatically locked for applications in
+     * <p>Since API level 14, camera is automatically locked for applications in
      * {@link android.media.MediaRecorder#start()}. Applications can use the
      * camera (ex: zoom) after recording starts. There is no need to call this
      * after recording starts or stops.
@@ -781,7 +781,7 @@
          * @see android.hardware.Camera.Parameters#setAutoWhiteBalanceLock(boolean)
          */
         void onAutoFocus(boolean success, Camera camera);
-    };
+    }
 
     /**
      * Starts camera auto-focus and registers a callback function to run when
@@ -804,11 +804,17 @@
      * {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}, flash may be
      * fired during auto-focus, depending on the driver and camera hardware.<p>
      *
-     * Auto-exposure lock {@link android.hardware.Camera.Parameters#getAutoExposureLock()}
+     * <p>Auto-exposure lock {@link android.hardware.Camera.Parameters#getAutoExposureLock()}
      * and auto-white balance locks {@link android.hardware.Camera.Parameters#getAutoWhiteBalanceLock()}
      * do not change during and after autofocus. But auto-focus routine may stop
      * auto-exposure and auto-white balance transiently during focusing.
      *
+     * <p>Stopping preview with {@link #stopPreview()}, or triggering still
+     * image capture with {@link #takePicture(Camera.ShutterCallback,
+     * Camera.PictureCallback, Camera.PictureCallback)}, will not change the
+     * the focus position. Applications must call cancelAutoFocus to reset the
+     * focus.</p>
+     *
      * @param cb the callback to run
      * @see #cancelAutoFocus()
      * @see android.hardware.Camera.Parameters#setAutoExposureLock(boolean)
@@ -1059,8 +1065,7 @@
         /**
          * Notify the listener of the detected faces in the preview frame.
          *
-         * @param faces The detected faces in a list sorted by the confidence score.
-         *              The highest scored face is the first element.
+         * @param faces The detected faces in a list
          * @param camera  The {@link Camera} service object
          */
         void onFaceDetection(Face[] faces, Camera camera);
@@ -1121,7 +1126,7 @@
 
     /**
      * Information about a face identified through camera face detection.
-     * 
+     *
      * <p>When face detection is used with a camera, the {@link FaceDetectionListener} returns a
      * list of face objects for use in focusing and metering.</p>
      *
@@ -1140,7 +1145,9 @@
          * the field of view. For example, suppose the size of the viewfinder UI
          * is 800x480. The rect passed from the driver is (-1000, -1000, 0, 0).
          * The corresponding viewfinder rect should be (0, 0, 400, 240). The
-         * width and height of the rect will not be 0 or negative.
+         * width and height of the rect will not be 0 or negative. The
+         * coordinates can be smaller than -1000 or bigger than 1000. But at
+         * least one vertex will be within (-1000, -1000) and (1000, 1000).
          *
          * <p>The direction is relative to the sensor orientation, that is, what
          * the sensor sees. The direction is not affected by the rotation or
@@ -1653,9 +1660,18 @@
          * call {@link #takePicture(Camera.ShutterCallback,
          * Camera.PictureCallback, Camera.PictureCallback)} in this mode but the
          * subject may not be in focus. Auto focus starts when the parameter is
-         * set. Applications should not call {@link
-         * #autoFocus(AutoFocusCallback)} in this mode. To stop continuous
-         * focus, applications should change the focus mode to other modes.
+         * set.
+         *
+         * <p>Since API level 14, applications can call {@link
+         * #autoFocus(AutoFocusCallback)} in this mode. The focus callback will
+         * immediately return with a boolean that indicates whether the focus is
+         * sharp or not. The focus position is locked after autoFocus call. If
+         * applications want to resume the continuous focus, cancelAutoFocus
+         * must be called. Restarting the preview will not resume the continuous
+         * autofocus. To stop continuous focus, applications should change the
+         * focus mode to other modes.
+         *
+         * @see #FOCUS_MODE_CONTINUOUS_PICTURE
          */
         public static final String FOCUS_MODE_CONTINUOUS_VIDEO = "continuous-video";
 
@@ -1663,13 +1679,17 @@
          * Continuous auto focus mode intended for taking pictures. The camera
          * continuously tries to focus. The speed of focus change is more
          * aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus
-         * starts when the parameter is set. If applications call {@link
-         * #autoFocus(AutoFocusCallback)} in this mode, the focus callback will
-         * immediately return with a boolean that indicates whether the focus is
-         * sharp or not. The apps can then decide if they want to take a picture
-         * immediately or to change the focus mode to auto, and run a full
-         * autofocus cycle. To stop continuous focus, applications should change
-         * the focus mode to other modes.
+         * starts when the parameter is set.
+         *
+         * <p>If applications call {@link #autoFocus(AutoFocusCallback)} in this
+         * mode, the focus callback will immediately return with a boolean that
+         * indicates whether the focus is sharp or not. The apps can then decide
+         * if they want to take a picture immediately or to change the focus
+         * mode to auto, and run a full autofocus cycle. The focus position is
+         * locked after autoFocus call. If applications want to resume the
+         * continuous focus, cancelAutoFocus must be called. Restarting the
+         * preview will not resume the continuous autofocus. To stop continuous
+         * focus, applications should change the focus mode to other modes.
          *
          * @see #FOCUS_MODE_CONTINUOUS_VIDEO
          */
@@ -3061,8 +3081,9 @@
          * when using zoom.</p>
          *
          * <p>Focus area only has effect if the current focus mode is
-         * {@link #FOCUS_MODE_AUTO}, {@link #FOCUS_MODE_MACRO}, or
-         * {@link #FOCUS_MODE_CONTINUOUS_VIDEO}.</p>
+         * {@link #FOCUS_MODE_AUTO}, {@link #FOCUS_MODE_MACRO},
+         * {@link #FOCUS_MODE_CONTINUOUS_VIDEO}, or
+         * {@link #FOCUS_MODE_CONTINUOUS_PICTURE}.</p>
          *
          * @return a list of current focus areas
          */
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index d1dc6e5..0640d7e 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -658,6 +658,24 @@
                 return _result;
             }
 
+            @Override
+            public int verifyEncryptionPassword(String password) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(password);
+                    mRemote.transact(Stub.TRANSACTION_verifyEncryptionPassword, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
             public Parcelable[] getVolumeList() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -761,6 +779,8 @@
 
         static final int TRANSACTION_getEncryptionState = IBinder.FIRST_CALL_TRANSACTION + 31;
 
+        static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1286,6 +1306,12 @@
     public int changeEncryptionPassword(String password) throws RemoteException;
 
     /**
+     * Verify the encryption password against the stored volume.  This method
+     * may only be called by the system process.
+     */
+    public int verifyEncryptionPassword(String password) throws RemoteException;
+
+    /**
      * Returns list of all mountable volumes.
      */
     public Parcelable[] getVolumeList() throws RemoteException;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 8483b4f..4bc0892 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -187,6 +187,59 @@
     public static final String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query";
 
     /**
+     * <p>
+     * API for obtaining a pre-authorized version of a URI that normally requires special
+     * permission (beyond READ_CONTACTS) to read.  The caller obtaining the pre-authorized URI
+     * must already have the necessary permissions to access the URI; otherwise a
+     * {@link SecurityException} will be thrown.
+     * </p>
+     * <p>
+     * The authorized URI returned in the bundle contains an expiring token that allows the
+     * caller to execute the query without having the special permissions that would normally
+     * be required.
+     * </p>
+     * <p>
+     * This API does not access disk, and should be safe to invoke from the UI thread.
+     * </p>
+     * <p>
+     * Example usage:
+     * <pre>
+     * Uri profileUri = ContactsContract.Profile.CONTENT_VCARD_URI;
+     * Bundle uriBundle = new Bundle();
+     * uriBundle.putParcelable(ContactsContract.Authorization.KEY_URI_TO_AUTHORIZE, uri);
+     * Bundle authResponse = getContext().getContentResolver().call(
+     *         ContactsContract.AUTHORITY_URI,
+     *         ContactsContract.Authorization.AUTHORIZATION_METHOD,
+     *         null, // String arg, not used.
+     *         uriBundle);
+     * if (authResponse != null) {
+     *     Uri preauthorizedProfileUri = (Uri) authResponse.getParcelable(
+     *             ContactsContract.Authorization.KEY_AUTHORIZED_URI);
+     *     // This pre-authorized URI can be queried by a caller without READ_PROFILE
+     *     // permission.
+     * }
+     * </pre>
+     * </p>
+     * @hide
+     */
+    public static final class Authorization {
+        /**
+         * The method to invoke to create a pre-authorized URI out of the input argument.
+         */
+        public static final String AUTHORIZATION_METHOD = "authorize";
+
+        /**
+         * The key to set in the outbound Bundle with the URI that should be authorized.
+         */
+        public static final String KEY_URI_TO_AUTHORIZE = "uri_to_authorize";
+
+        /**
+         * The key to retrieve from the returned Bundle to obtain the pre-authorized URI.
+         */
+        public static final String KEY_AUTHORIZED_URI = "authorized_uri";
+    }
+
+    /**
      * @hide
      */
     public static final class Preferences {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3d2a3ce..5754e60 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4053,6 +4053,14 @@
         public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
 
         /**
+         * Duration in milliseconds before pre-authorized URIs for the contacts
+         * provider should expire.
+         * @hide
+         */
+        public static final String CONTACTS_PREAUTH_URI_EXPIRATION =
+                "contacts_preauth_uri_expiration";
+
+        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
diff --git a/core/java/android/view/ContextMenu.java b/core/java/android/view/ContextMenu.java
index dd1d7db..decabcb 100644
--- a/core/java/android/view/ContextMenu.java
+++ b/core/java/android/view/ContextMenu.java
@@ -29,6 +29,12 @@
  * To show a context menu on long click, most clients will want to call
  * {@link Activity#registerForContextMenu} and override
  * {@link Activity#onCreateContextMenu}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
  */
 public interface ContextMenu extends Menu {
     /**
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 8f491ef..f559e21 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -114,6 +114,12 @@
  *  {@link android.view.DragEvent#writeToParcel(Parcel,int)}, and
  *  {@link android.view.DragEvent#toString()} methods always return valid data.
  * </p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to implementing drag and drop features, read the
+ * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+ * </div>
  */
 public class DragEvent implements Parcelable {
     private static final boolean TRACK_RECYCLED_LOCATION = false;
diff --git a/core/java/android/view/Menu.java b/core/java/android/view/Menu.java
index 97825e6..7157bc5 100644
--- a/core/java/android/view/Menu.java
+++ b/core/java/android/view/Menu.java
@@ -41,6 +41,12 @@
  * item check marks are discouraged.
  * <li><b>Sub menus</b>: Do not support item icons, or nested sub menus.
  * </ol>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
  */
 public interface Menu {
 
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index ccd8353..2dfbcb5 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -29,6 +29,12 @@
  * methods.
  * <p>
  * For a feature set of specific menu types, see {@link Menu}.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
  */
 public interface MenuItem {
     /*
diff --git a/core/java/android/view/SubMenu.java b/core/java/android/view/SubMenu.java
index e981486..196a183 100644
--- a/core/java/android/view/SubMenu.java
+++ b/core/java/android/view/SubMenu.java
@@ -22,6 +22,12 @@
  * Subclass of {@link Menu} for sub menus.
  * <p>
  * Sub menus do not support item icons, or nested sub menus.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating menus, read the
+ * <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.</p>
+ * </div>
  */
 
 public interface SubMenu extends Menu {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 86be28a..d5f18cc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -418,7 +418,7 @@
  * <h3>Drawing</h3>
  * <p>
  * Drawing is handled by walking the tree and rendering each view that
- * intersects the the invalid region. Because the tree is traversed in-order,
+ * intersects the invalid region. Because the tree is traversed in-order,
  * this means that parents will draw before (i.e., behind) their children, with
  * siblings drawn in the order they appear in the tree.
  * If you set a background drawable for a View, then the View will draw it for you
@@ -1891,12 +1891,10 @@
      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
      * out of the public fields to keep the undefined bits out of the developer's way.
      *
-     * Flag to hide only the navigation buttons.  Don't use this
+     * Flag to hide only the home button.  Don't use this
      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
-     *
-     * THIS DOES NOT DISABLE THE BACK BUTTON
      */
-    public static final int STATUS_BAR_DISABLE_NAVIGATION = 0x00200000;
+    public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
 
     /**
      * @hide
@@ -1904,7 +1902,7 @@
      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
      * out of the public fields to keep the undefined bits out of the developer's way.
      *
-     * Flag to hide only the back button.  Don't use this
+     * Flag to hide only the back button. Don't use this
      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
      */
     public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
@@ -1922,6 +1920,28 @@
 
     /**
      * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide only the recent apps button. Don't use this
+     * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
+     */
+    public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility, etc. etc.
+     *
+     * This hides HOME and RECENT and is provided for compatibility with interim implementations.
+     */
+    @Deprecated
+    public static final int STATUS_BAR_DISABLE_NAVIGATION = 
+            STATUS_BAR_DISABLE_HOME | STATUS_BAR_DISABLE_RECENT;
+
+    /**
+     * @hide
      */
     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
 
@@ -8344,7 +8364,7 @@
                         !((ViewGroup) mParent).isViewTransitioning(this));
     }
     /**
-     * Mark the the area defined by dirty as needing to be drawn. If the view is
+     * Mark the area defined by dirty as needing to be drawn. If the view is
      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some point
      * in the future. This must be called from a UI thread. To call from a non-UI
      * thread, call {@link #postInvalidate()}.
@@ -8389,7 +8409,7 @@
     }
 
     /**
-     * Mark the the area defined by the rect (l,t,r,b) as needing to be drawn.
+     * Mark the area defined by the rect (l,t,r,b) as needing to be drawn.
      * The coordinates of the dirty rect are relative to the view.
      * If the view is visible, {@link #onDraw(android.graphics.Canvas)}
      * will be called at some point in the future. This must be called from
@@ -13075,6 +13095,12 @@
      *  {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()}
      *  so that your application can draw the shadow image in the Canvas.
      * </p>
+     *
+     * <div class="special reference">
+     * <h3>Developer Guides</h3>
+     * <p>For a guide to implementing drag and drop features, read the
+     * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+     * </div>
      */
     public static class DragShadowBuilder {
         private final WeakReference<View> mView;
@@ -14066,6 +14092,12 @@
      * to this view.  The callback will be invoked before the hosting view's own
      * onDrag(event) method.  If the listener wants to fall back to the hosting view's
      * onDrag(event) behavior, it should return 'false' from this callback.
+     *
+     * <div class="special reference">
+     * <h3>Developer Guides</h3>
+     * <p>For a guide to implementing drag and drop features, read the
+     * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+     * </div>
      */
     public interface OnDragListener {
         /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9266ae2..62b20b3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -60,6 +60,12 @@
  * Also see {@link LayoutParams} for layout attributes.
  * </p>
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating user interface layouts, read the
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> developer
+ * guide.</p></div>
+ *
  * @attr ref android.R.styleable#ViewGroup_clipChildren
  * @attr ref android.R.styleable#ViewGroup_clipToPadding
  * @attr ref android.R.styleable#ViewGroup_layoutAnimation
@@ -5158,7 +5164,13 @@
      * </ul>
      * There are subclasses of LayoutParams for different subclasses of
      * ViewGroup. For example, AbsoluteLayout has its own subclass of
-     * LayoutParams which adds an X and Y value.
+     * LayoutParams which adds an X and Y value.</p>
+     *
+     * <div class="special reference">
+     * <h3>Developer Guides</h3>
+     * <p>For more information about creating user interface layouts, read the
+     * <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> developer
+     * guide.</p></div>
      *
      * @attr ref android.R.styleable#ViewGroup_Layout_layout_height
      * @attr ref android.R.styleable#ViewGroup_Layout_layout_width
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 122865e..cdf1f8d 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -97,6 +97,7 @@
     protected AudioService mAudioService;
     private boolean mRingIsSilent;
     private boolean mShowCombinedVolumes;
+    private boolean mVoiceCapable;
 
     /** Dialog containing all the sliders */
     private final Dialog mDialog;
@@ -117,40 +118,56 @@
     /** All the slider controls mapped by stream type */
     private HashMap<Integer,StreamControl> mStreamControls;
 
+    private enum StreamResources {
+        BluetoothSCOStream(AudioManager.STREAM_BLUETOOTH_SCO,
+                R.string.volume_icon_description_bluetooth,
+                R.drawable.ic_audio_bt,
+                R.drawable.ic_audio_bt,
+                false),
+        RingerStream(AudioManager.STREAM_RING,
+                R.string.volume_icon_description_ringer,
+                R.drawable.ic_audio_ring_notif,
+                R.drawable.ic_audio_ring_notif_mute,
+                false),
+        VoiceStream(AudioManager.STREAM_VOICE_CALL,
+                R.string.volume_icon_description_incall,
+                R.drawable.ic_audio_phone,
+                R.drawable.ic_audio_phone,
+                false),
+        MediaStream(AudioManager.STREAM_MUSIC,
+                R.string.volume_icon_description_media,
+                R.drawable.ic_audio_vol,
+                R.drawable.ic_audio_vol_mute,
+                true),
+        NotificationStream(AudioManager.STREAM_NOTIFICATION,
+                R.string.volume_icon_description_notification,
+                R.drawable.ic_audio_notification,
+                R.drawable.ic_audio_notification_mute,
+                true);
+
+        int streamType;
+        int descRes;
+        int iconRes;
+        int iconMuteRes;
+        // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
+        boolean show;
+
+        StreamResources(int streamType, int descRes, int iconRes, int iconMuteRes, boolean show) {
+            this.streamType = streamType;
+            this.descRes = descRes;
+            this.iconRes = iconRes;
+            this.iconMuteRes = iconMuteRes;
+            this.show = show;
+        }
+    };
+
     // List of stream types and their order
-    // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly requested
-    private static final int [] STREAM_TYPES = {
-        AudioManager.STREAM_BLUETOOTH_SCO,
-        AudioManager.STREAM_RING,
-        AudioManager.STREAM_VOICE_CALL,
-        AudioManager.STREAM_MUSIC,
-        AudioManager.STREAM_NOTIFICATION
-    };
-
-    private static final int [] CONTENT_DESCRIPTIONS = {
-        R.string.volume_icon_description_bluetooth,
-        R.string.volume_icon_description_ringer,
-        R.string.volume_icon_description_incall,
-        R.string.volume_icon_description_media,
-        R.string.volume_icon_description_notification
-    };
-
-    // These icons need to correspond to the ones above.
-    private static final int [] STREAM_ICONS_NORMAL = {
-        R.drawable.ic_audio_bt,
-        R.drawable.ic_audio_ring_notif,
-        R.drawable.ic_audio_phone,
-        R.drawable.ic_audio_vol,
-        R.drawable.ic_audio_notification,
-    };
-
-    // These icons need to correspond to the ones above.
-    private static final int [] STREAM_ICONS_MUTED = {
-        R.drawable.ic_audio_bt,
-        R.drawable.ic_audio_ring_notif_mute,
-        R.drawable.ic_audio_phone,
-        R.drawable.ic_audio_vol_mute,
-        R.drawable.ic_audio_notification_mute,
+    private static final StreamResources[] STREAMS = {
+        StreamResources.BluetoothSCOStream,
+        StreamResources.RingerStream,
+        StreamResources.VoiceStream,
+        StreamResources.MediaStream,
+        StreamResources.NotificationStream
     };
 
     /** Object that contains data for each slider */
@@ -221,7 +238,8 @@
         mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
         mVibrator = new Vibrator();
 
-        mShowCombinedVolumes = !context.getResources().getBoolean(R.bool.config_voice_capable);
+        mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
+        mShowCombinedVolumes = !mVoiceCapable;
         // If we don't want to show multiple volumes, hide the settings button and divider
         if (!mShowCombinedVolumes) {
             mMoreButton.setVisibility(View.GONE);
@@ -260,10 +278,14 @@
 
         LayoutInflater inflater = (LayoutInflater) mContext
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        mStreamControls = new HashMap<Integer,StreamControl>(STREAM_TYPES.length);
+        mStreamControls = new HashMap<Integer, StreamControl>(STREAMS.length);
         Resources res = mContext.getResources();
-        for (int i = 0; i < STREAM_TYPES.length; i++) {
-            final int streamType = STREAM_TYPES[i];
+        for (int i = 0; i < STREAMS.length; i++) {
+            StreamResources streamRes = STREAMS[i];
+            int streamType = streamRes.streamType;
+            if (mVoiceCapable && streamRes == StreamResources.NotificationStream) {
+                streamRes = StreamResources.RingerStream;
+            }
             StreamControl sc = new StreamControl();
             sc.streamType = streamType;
             sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);
@@ -273,9 +295,9 @@
                 sc.icon.setOnClickListener(this);
             }
             sc.icon.setTag(sc);
-            sc.icon.setContentDescription(res.getString(CONTENT_DESCRIPTIONS[i]));
-            sc.iconRes = STREAM_ICONS_NORMAL[i];
-            sc.iconMuteRes = STREAM_ICONS_MUTED[i];
+            sc.icon.setContentDescription(res.getString(streamRes.descRes));
+            sc.iconRes = streamRes.iconRes;
+            sc.iconMuteRes = streamRes.iconMuteRes;
             sc.icon.setImageResource(sc.iconRes);
             sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
             int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
@@ -307,13 +329,10 @@
     private void addOtherVolumes() {
         if (!mShowCombinedVolumes) return;
 
-        for (int i = 0; i < STREAM_TYPES.length; i++) {
+        for (int i = 0; i < STREAMS.length; i++) {
             // Skip the phone specific ones and the active one
-            final int streamType = STREAM_TYPES[i];
-            if (streamType == AudioManager.STREAM_RING
-                    || streamType == AudioManager.STREAM_VOICE_CALL
-                    || streamType == AudioManager.STREAM_BLUETOOTH_SCO
-                    || streamType == mActiveStreamType) {
+            final int streamType = STREAMS[i].streamType;
+            if (!STREAMS[i].show || streamType == mActiveStreamType) {
                 continue;
             }
             StreamControl sc = mStreamControls.get(streamType);
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 9c44138..f1c2bde 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -211,6 +211,7 @@
     private ZoomDensity     mDefaultZoom = ZoomDensity.MEDIUM;
     private RenderPriority  mRenderPriority = RenderPriority.NORMAL;
     private int             mOverrideCacheMode = LOAD_DEFAULT;
+    private int             mDoubleTapZoom = 100;
     private boolean         mSaveFormData = true;
     private boolean         mAutoFillEnabled = false;
     private boolean         mSavePassword = true;
@@ -769,6 +770,27 @@
     }
 
     /**
+     * Set the double-tap zoom of the page in percent. Default is 100.
+     * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
+     * @hide
+     */
+    public void setDoubleTapZoom(int doubleTapZoom) {
+        if (mDoubleTapZoom != doubleTapZoom) {
+            mDoubleTapZoom = doubleTapZoom;
+            mWebView.updateDoubleTapZoom();
+        }
+    }
+
+    /**
+     * Get the double-tap zoom of the page in percent.
+     * @return A percent value describing the double-tap zoom.
+     * @hide
+     */
+    public int getDoubleTapZoom() {
+        return mDoubleTapZoom;
+    }
+
+    /**
      * Set the default zoom density of the page. This should be called from UI
      * thread.
      * @param zoom A ZoomDensity value
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9648cd0..48615bd 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2079,10 +2079,12 @@
      * <p>
      * The 'data' scheme URL formed by this method uses the default US-ASCII
      * charset. If you need need to set a different charset, you should form a
-     * 'data' scheme URL which specifies a charset parameter and call
-     * {@link #loadUrl(String)} instead.
+     * 'data' scheme URL which explicitly specifies a charset parameter in the
+     * mediatype portion of the URL and call {@link #loadUrl(String)} instead.
+     * Note that the charset obtained from the mediatype portion of a data URL
+     * always overrides that specified in the HTML or XML document itself.
      * @param data A String of data in the given encoding.
-     * @param mimeType The MIMEType of the data, e.g. 'text/html'.
+     * @param mimeType The MIME type of the data, e.g. 'text/html'.
      * @param encoding The encoding of the data.
      */
     public void loadData(String data, String mimeType, String encoding) {
@@ -2986,6 +2988,13 @@
         return false;
     }
 
+    /**
+     * Update the double-tap zoom.
+     */
+    /* package */ void updateDoubleTapZoom() {
+        mZoomManager.updateDoubleTapZoom();
+    }
+
     private int computeRealHorizontalScrollRange() {
         if (mDrawHistory) {
             return mHistoryWidth;
@@ -4505,7 +4514,7 @@
         boolean UIAnimationsRunning = false;
         // Currently for each draw we compute the animation values;
         // We may in the future decide to do that independently.
-        if (mNativeClass != 0 && nativeEvaluateLayersAnimations()) {
+        if (mNativeClass != 0 && nativeEvaluateLayersAnimations(mNativeClass)) {
             UIAnimationsRunning = true;
             // If we have unfinished (or unstarted) animations,
             // we ask for a repaint. We only need to do this in software
@@ -4521,9 +4530,9 @@
             extras = DRAW_EXTRAS_FIND;
         } else if (mSelectingText && !USE_JAVA_TEXT_SELECTION) {
             extras = DRAW_EXTRAS_SELECTION;
-            nativeSetSelectionPointer(mDrawSelectionPointer,
-                    mZoomManager.getInvScale(),
-                    mSelectX, mSelectY - getTitleHeight());
+            nativeSetSelectionPointer(mNativeClass,
+                    mDrawSelectionPointer,
+                    mZoomManager.getInvScale(), mSelectX, mSelectY - getTitleHeight());
         } else if (drawCursorRing) {
             extras = DRAW_EXTRAS_CURSOR_RING;
         }
@@ -4537,8 +4546,8 @@
         }
 
         if (canvas.isHardwareAccelerated()) {
-            int functor = nativeGetDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
-                    mGLViewportEmpty ? null : mViewRectViewport, getScale(), extras);
+            int functor = nativeGetDrawGLFunction(mNativeClass,
+                    mGLViewportEmpty ? null : mGLRectViewport, mGLViewportEmpty ? null : mViewRectViewport, getScale(), extras);
             ((HardwareCanvas) canvas).callDrawGLFunction(functor);
 
             if (mHardwareAccelSkia != getSettings().getHardwareAccelSkiaEnabled()) {
@@ -9407,9 +9416,9 @@
             // We never want to change button state if we are hardware accelerated,
             // but we DO want to invalidate as necessary so that the GL ring
             // can be drawn
-            nativeRecordButtons(false, false, inval);
+            nativeRecordButtons(mNativeClass, false, false, inval);
         } else {
-            nativeRecordButtons(focus, pressed, inval);
+            nativeRecordButtons(mNativeClass, focus, pressed, inval);
         }
     }
 
@@ -9444,9 +9453,9 @@
     private native int nativeDraw(Canvas canvas, int color, int extra,
             boolean splitIfNeeded);
     private native void     nativeDumpDisplayTree(String urlOrNull);
-    private native boolean  nativeEvaluateLayersAnimations();
-    private native int      nativeGetDrawGLFunction(Rect rect, Rect viewRect,
-            float scale, int extras);
+    private native boolean  nativeEvaluateLayersAnimations(int nativeInstance);
+    private native int      nativeGetDrawGLFunction(int nativeInstance, Rect rect,
+            Rect viewRect, float scale, int extras);
     private native void     nativeUpdateDrawGLFunction(Rect rect, Rect viewRect);
     private native void     nativeExtendSelection(int x, int y);
     private native int      nativeFindAll(String findLower, String findUpper,
@@ -9509,8 +9518,8 @@
     private native boolean  nativePointInNavCache(int x, int y, int slop);
     // Like many other of our native methods, you must make sure that
     // mNativeClass is not null before calling this method.
-    private native void     nativeRecordButtons(boolean focused,
-            boolean pressed, boolean invalidate);
+    private native void     nativeRecordButtons(int nativeInstance,
+            boolean focused, boolean pressed, boolean invalidate);
     private native void     nativeResetSelection();
     private native Point    nativeSelectableText();
     private native void     nativeSelectAll();
@@ -9531,8 +9540,8 @@
     private native void     nativeReplaceBaseContent(int content);
     private native void     nativeCopyBaseContentToPicture(Picture pict);
     private native boolean  nativeHasContent();
-    private native void     nativeSetSelectionPointer(boolean set,
-            float scale, int x, int y);
+    private native void     nativeSetSelectionPointer(int nativeInstance,
+            boolean set, float scale, int x, int y);
     private native boolean  nativeStartSelection(int x, int y);
     private native void     nativeStopGL();
     private native Rect     nativeSubtractLayers(Rect content);
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7f526e7..206142a 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -145,11 +145,11 @@
     private float mInvDefaultScale;
 
     /*
-     * The scale factor that is used to determine the zoom level for reading text.
-     * The value is initially set to equal the display density.
-     * TODO: Support changing this in WebSettings
+     * The logical density of the display. This is a scaling factor for the
+     * Density Independent Pixel unit, where one DIP is one pixel on an
+     * approximately 160 dpi screen (see android.util.DisplayMetrics.density)
      */
-    private float mReadingLevelScale;
+    private float mDisplayDensity;
 
     /*
      * The scale factor that is used as the minimum increment when going from
@@ -233,11 +233,11 @@
     public void init(float density) {
         assert density > 0;
 
+        mDisplayDensity = density;
         setDefaultZoomScale(density);
         mActualScale = density;
         mInvActualScale = 1 / density;
-        mReadingLevelScale = density;
-        mTextWrapScale = density;
+        mTextWrapScale = getReadingLevelScale();
     }
 
     /**
@@ -310,8 +310,11 @@
         return mInitialScale > 0 ? mInitialScale : mDefaultScale;
     }
 
+    /**
+     * Returns the zoom scale used for reading text on a double-tap.
+     */
     public final float getReadingLevelScale() {
-        return mReadingLevelScale;
+        return mDisplayDensity * mWebView.getSettings().getDoubleTapZoom() / 100.0f;
     }
 
     public final float getInvDefaultScale() {
@@ -510,6 +513,13 @@
         return mZoomScale != 0 || mInHWAcceleratedZoom;
     }
 
+    public void updateDoubleTapZoom() {
+        if (mInZoomOverview) {
+            mTextWrapScale = getReadingLevelScale();
+            refreshZoomScale(true);
+        }
+    }
+
     public void refreshZoomScale(boolean reflowText) {
         setZoomScale(mActualScale, reflowText, true);
     }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 475b8ee..bdaf89e 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -335,7 +335,9 @@
                     mTouchDownX = event.getX();
                 } else {
                     setPressed(true);
-                    invalidate(mThumb.getBounds()); // This may be within the padding region
+                    if (mThumb != null) {
+                        invalidate(mThumb.getBounds()); // This may be within the padding region
+                    }
                     onStartTrackingTouch();
                     trackTouchEvent(event);
                     attemptClaimDrag();
@@ -349,7 +351,9 @@
                     final float x = event.getX();
                     if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
                         setPressed(true);
-                        invalidate(mThumb.getBounds()); // This may be within the padding region
+                        if (mThumb != null) {
+                            invalidate(mThumb.getBounds()); // This may be within the padding region
+                        }
                         onStartTrackingTouch();
                         trackTouchEvent(event);
                         attemptClaimDrag();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 041e8a4..a21a087 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7683,8 +7683,9 @@
             }
         }
         
-        if (what instanceof UpdateAppearance ||
-            what instanceof ParagraphStyle) {
+        if (what instanceof UpdateAppearance || what instanceof ParagraphStyle
+                || (what instanceof SuggestionSpan && (((SuggestionSpan)what).getFlags()
+                        & SuggestionSpan.FLAG_AUTO_CORRECTION) != 0)) {
             if (ims == null || ims.mBatchEditNesting == 0) {
                 invalidate();
                 mHighlightPathBogus = true;
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index bb23173..88d7e05 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -48,6 +48,13 @@
  * <p>
  * The easiest way to use this class is to call one of the static methods that constructs
  * everything you need and returns a new Toast object.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about creating Toast notifications, read the
+ * <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> developer
+ * guide.</p>
+ * </div>
  */ 
 public class Toast {
     static final String TAG = "Toast";
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 5b49bff..a2fc6e2 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -32,9 +32,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
-import android.os.Vibrator;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
@@ -59,9 +59,6 @@
     private static final int ASPECT_LOCK_WIDTH = 1; // Fixed width; height will be minimum of (w,h)
     private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h)
 
-    // Vibrator pattern for creating a tactile bump
-    private static final long[] DEFAULT_VIBE_PATTERN = {0, 1, 40, 41};
-
     private static final boolean PROFILE_DRAWING = false;
     private boolean mDrawingProfilingStarted = false;
 
@@ -102,7 +99,7 @@
     private DisplayMode mPatternDisplayMode = DisplayMode.Correct;
     private boolean mInputEnabled = true;
     private boolean mInStealthMode = false;
-    private boolean mTactileFeedbackEnabled = true;
+    private boolean mEnableHapticFeedback = true;
     private boolean mPatternInProgress = false;
 
     private float mDiameterFactor = 0.10f; // TODO: move to attrs
@@ -127,11 +124,6 @@
     private int mBitmapWidth;
     private int mBitmapHeight;
 
-
-    private Vibrator vibe; // Vibrator for creating tactile feedback
-
-    private long[] mVibePattern;
-
     private int mAspect;
     private final Matrix mArrowMatrix = new Matrix();
     private final Matrix mCircleMatrix = new Matrix();
@@ -250,7 +242,6 @@
 
     public LockPatternView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        vibe = new Vibrator();
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LockPatternView);
 
@@ -295,26 +286,6 @@
             mBitmapHeight = Math.max(mBitmapHeight, bitmap.getHeight());
         }
 
-        // allow vibration pattern to be customized
-        mVibePattern = loadVibratePattern(com.android.internal.R.array.config_virtualKeyVibePattern);
-    }
-
-    private long[] loadVibratePattern(int id) {
-        int[] pattern = null;
-        try {
-            pattern = getResources().getIntArray(id);
-        } catch (Resources.NotFoundException e) {
-            Log.e(TAG, "Vibrate pattern missing, using default", e);
-        }
-        if (pattern == null) {
-            return DEFAULT_VIBE_PATTERN;
-        }
-
-        long[] tmpPattern = new long[pattern.length];
-        for (int i = 0; i < pattern.length; i++) {
-            tmpPattern[i] = pattern[i];
-        }
-        return tmpPattern;
     }
 
     private Bitmap getBitmapFor(int resId) {
@@ -332,7 +303,7 @@
      * @return Whether the view has tactile feedback enabled.
      */
     public boolean isTactileFeedbackEnabled() {
-        return mTactileFeedbackEnabled;
+        return mEnableHapticFeedback;
     }
 
     /**
@@ -352,7 +323,7 @@
      * @param tactileFeedbackEnabled Whether tactile feedback is enabled
      */
     public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) {
-        mTactileFeedbackEnabled = tactileFeedbackEnabled;
+        mEnableHapticFeedback = tactileFeedbackEnabled;
     }
 
     /**
@@ -573,8 +544,10 @@
                 addCellToPattern(fillInGapCell);
             }
             addCellToPattern(cell);
-            if (mTactileFeedbackEnabled){
-                vibe.vibrate(mVibePattern, -1); // Generate tactile feedback
+            if (mEnableHapticFeedback) {
+                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+                        | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
             }
             return cell;
         }
@@ -1114,7 +1087,7 @@
         return new SavedState(superState,
                 LockPatternUtils.patternToString(mPattern),
                 mPatternDisplayMode.ordinal(),
-                mInputEnabled, mInStealthMode, mTactileFeedbackEnabled);
+                mInputEnabled, mInStealthMode, mEnableHapticFeedback);
     }
 
     @Override
@@ -1127,7 +1100,7 @@
         mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()];
         mInputEnabled = ss.isInputEnabled();
         mInStealthMode = ss.isInStealthMode();
-        mTactileFeedbackEnabled = ss.isTactileFeedbackEnabled();
+        mEnableHapticFeedback = ss.isTactileFeedbackEnabled();
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/LockScreenWidgetCallback.java b/core/java/com/android/internal/widget/LockScreenWidgetCallback.java
index d6403e9f..d7ad6c0 100644
--- a/core/java/com/android/internal/widget/LockScreenWidgetCallback.java
+++ b/core/java/com/android/internal/widget/LockScreenWidgetCallback.java
@@ -29,6 +29,9 @@
     // Sends a message to lock screen requesting the view to be hidden.
     public void requestHide(View self);
 
+    // Whether or not this view is currently visible on LockScreen
+    public boolean isVisible(View self);
+
     // Sends a message to lock screen that user has interacted with widget. This should be used
     // exclusively in response to user activity, i.e. user hits a button in the view.
     public void userActivity(View self);
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 01df48a..2e7810f 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -26,6 +26,7 @@
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.util.Log;
+import android.view.HapticFeedbackConstants;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
@@ -52,7 +53,7 @@
     private final View mTargetView;
     private final KeyboardView mKeyboardView;
     private long[] mVibratePattern;
-    private final Vibrator mVibrator;
+    private boolean mEnableHaptics = false;
 
     public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
         this(context, keyboardView, targetView, true);
@@ -71,7 +72,10 @@
                     mKeyboardView.getLayoutParams().height);
         }
         mKeyboardView.setOnKeyboardActionListener(this);
-        mVibrator = new Vibrator();
+    }
+
+    public void setEnableHaptics(boolean enabled) {
+        mEnableHaptics = enabled;
     }
 
     public boolean isAlpha() {
@@ -230,6 +234,7 @@
 
     public void handleBackspace() {
         sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+        performHapticFeedback();
     }
 
     private void handleShift() {
@@ -272,8 +277,14 @@
     }
 
     public void onPress(int primaryCode) {
-        if (mVibratePattern != null) {
-            mVibrator.vibrate(mVibratePattern, -1);
+        performHapticFeedback();
+    }
+
+    private void performHapticFeedback() {
+        if (mEnableHaptics) {
+            mKeyboardView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
index 73d9f10..63a3aa5 100644
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ b/core/java/com/android/internal/widget/TransportControlView.java
@@ -34,6 +34,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.text.Spannable;
@@ -61,7 +63,7 @@
     private static final int MSG_SET_GENERATION_ID = 104;
     private static final int MAXDIM = 512;
     private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s
-    protected static final boolean DEBUG = true;
+    protected static final boolean DEBUG = false;
     protected static final String TAG = "TransportControlView";
 
     private ImageView mAlbumArt;
@@ -74,7 +76,7 @@
     private boolean mAttached;
     private PendingIntent mClientIntent;
     private int mTransportControlFlags;
-    private int mPlayState;
+    private int mCurrentPlayState;
     private AudioManager mAudioManager;
     private LockScreenWidgetCallback mWidgetCallbacks;
     private IRemoteControlDisplayWeak mIRCD;
@@ -84,6 +86,11 @@
      */
     private Bundle mPopulateMetadataWhenAttached = null;
 
+    /**
+     * Whether to clear the interface next time it is shown (i.e. the generation id changed)
+     */
+    private boolean mClearOnNextShow;
+
     // This handler is required to ensure messages from IRCD are handled in sequence and on
     // the UI thread.
     private Handler mHandler = new Handler() {
@@ -113,15 +120,10 @@
                 break;
 
             case MSG_SET_GENERATION_ID:
-                if (mWidgetCallbacks != null) {
-                    boolean clearing = msg.arg2 != 0;
-                    if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + clearing);
-                    if (!clearing) {
-                        mWidgetCallbacks.requestShow(TransportControlView.this);
-                    } else {
-                        mWidgetCallbacks.requestHide(TransportControlView.this);
-                    }
+                if (msg.arg2 != 0) {
+                    mClearOnNextShow = true; // TODO: handle this
                 }
+                if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
                 mClientGeneration = msg.arg1;
                 mClientIntent = (PendingIntent) msg.obj;
                 break;
@@ -195,6 +197,7 @@
         super(context, attrs);
         Log.v(TAG, "Create TCV " + this);
         mAudioManager = new AudioManager(mContext);
+        mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
         mIRCD = new IRemoteControlDisplayWeak(mHandler);
     }
 
@@ -319,7 +322,7 @@
                 | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
                 | RemoteControlClient.FLAG_KEY_MEDIA_STOP);
 
-        updatePlayPauseState(mPlayState);
+        updatePlayPauseState(mCurrentPlayState);
     }
 
     private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
@@ -332,32 +335,99 @@
 
     private void updatePlayPauseState(int state) {
         if (DEBUG) Log.v(TAG,
-                "updatePlayPauseState(), old=" + mPlayState + ", state=" + state);
-        if (state == mPlayState) {
+                "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
+        if (state == mCurrentPlayState) {
             return;
         }
         final int imageResId;
         final int imageDescId;
+        boolean showIfHidden = false;
         switch (state) {
+            case RemoteControlClient.PLAYSTATE_ERROR:
+                imageResId = com.android.internal.R.drawable.stat_sys_warning;
+                // TODO use more specific image description string for warning, but here the "play"
+                //      message is still valid because this button triggers a play command.
+                imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
+                break;
+
             case RemoteControlClient.PLAYSTATE_PLAYING:
                 imageResId = com.android.internal.R.drawable.ic_media_pause;
                 imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description;
+                showIfHidden = true;
                 break;
 
             case RemoteControlClient.PLAYSTATE_BUFFERING:
                 imageResId = com.android.internal.R.drawable.ic_media_stop;
                 imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description;
+                showIfHidden = true;
                 break;
 
             case RemoteControlClient.PLAYSTATE_PAUSED:
             default:
                 imageResId = com.android.internal.R.drawable.ic_media_play;
                 imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
+                showIfHidden = false;
                 break;
         }
         mBtnPlay.setImageResource(imageResId);
         mBtnPlay.setContentDescription(getResources().getString(imageDescId));
-        mPlayState = state;
+        if (showIfHidden && mWidgetCallbacks != null && !mWidgetCallbacks.isVisible(this)) {
+            mWidgetCallbacks.requestShow(this);
+        }
+        mCurrentPlayState = state;
+    }
+
+    static class SavedState extends BaseSavedState {
+        boolean wasShowing;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            this.wasShowing = in.readInt() != 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeInt(this.wasShowing ? 1 : 0);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        if (DEBUG) Log.v(TAG, "onSaveInstanceState()");
+        Parcelable superState = super.onSaveInstanceState();
+        SavedState ss = new SavedState(superState);
+        ss.wasShowing = mWidgetCallbacks.isVisible(this);
+        return ss;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        if (DEBUG) Log.v(TAG, "onRestoreInstanceState()");
+        if (!(state instanceof SavedState)) {
+            super.onRestoreInstanceState(state);
+            return;
+        }
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        if (ss.wasShowing) {
+            mWidgetCallbacks.requestShow(this);
+        }
     }
 
     public void onClick(View v) {
diff --git a/core/res/res/drawable-hdpi/ic_media_next.png b/core/res/res/drawable-hdpi/ic_media_next.png
index c74703e..f5ba824 100644
--- a/core/res/res/drawable-hdpi/ic_media_next.png
+++ b/core/res/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_previous.png b/core/res/res/drawable-hdpi/ic_media_previous.png
index 15dc390..40ecb00 100644
--- a/core/res/res/drawable-hdpi/ic_media_previous.png
+++ b/core/res/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
index 81c52b0..3e00747 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
index 15500c3..c760936 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
index 1446fa7..7f87ee7 100644
--- a/core/res/res/drawable-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
index f3aaa27..8148ab8 100644
--- a/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-hdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index a9af4a8..765be61 100644
--- a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_next.png b/core/res/res/drawable-mdpi/ic_media_next.png
index a6feed0..acef506 100644
--- a/core/res/res/drawable-mdpi/ic_media_next.png
+++ b/core/res/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_previous.png b/core/res/res/drawable-mdpi/ic_media_previous.png
index 0163d09..940d6a4 100644
--- a/core/res/res/drawable-mdpi/ic_media_previous.png
+++ b/core/res/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
index 85f3cb2..baa5427 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
index 77f92fb..8e6a93f 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
index 8797a09..58e0cbc 100644
--- a/core/res/res/drawable-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
index 747cb97..b7e2a6a 100644
--- a/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-mdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index e8c6374..d82704e 100644
--- a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..b753764
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..b47a9f6
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..951197c
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..5893db9
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..1d72243
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..76dee9e
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_next.png b/core/res/res/drawable-xhdpi/ic_media_next.png
index 9835c63..726fee7 100644
--- a/core/res/res/drawable-xhdpi/ic_media_next.png
+++ b/core/res/res/drawable-xhdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_previous.png b/core/res/res/drawable-xhdpi/ic_media_previous.png
index 5df5987..59f994d 100644
--- a/core/res/res/drawable-xhdpi/ic_media_previous.png
+++ b/core/res/res/drawable-xhdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
index 16632b1..7aa8750 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
index 6e007c7..d4e4d81 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
index 4135fea..adbd7b1 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
index 6bb7512..0dbae57 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
index 3ac1b88..51e648c 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/layout/keyguard_transport_control.xml b/core/res/res/layout/keyguard_transport_control.xml
index 6e24ce2..c951c45 100644
--- a/core/res/res/layout/keyguard_transport_control.xml
+++ b/core/res/res/layout/keyguard_transport_control.xml
@@ -63,7 +63,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="center"
-                    android:src="@drawable/ic_media_rew"
+                    android:src="@drawable/ic_media_previous"
                     android:clickable="true"
                     android:background="?android:attr/selectableItemBackground"
                     android:padding="10dip"
@@ -94,7 +94,7 @@
                     android:layout_height="wrap_content"
                     android:layout_gravity="center"
                     android:clickable="true"
-                    android:src="@drawable/ic_media_ff"
+                    android:src="@drawable/ic_media_next"
                     android:background="?android:attr/selectableItemBackground"
                     android:padding="10dip"
                     android:contentDescription="@string/lockscreen_transport_next_description"/>
diff --git a/core/res/res/layout/volume_adjust_item.xml b/core/res/res/layout/volume_adjust_item.xml
index fb900f7..d3fa7e9 100644
--- a/core/res/res/layout/volume_adjust_item.xml
+++ b/core/res/res/layout/volume_adjust_item.xml
@@ -27,7 +27,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:padding="16dip"
-        android:layout_marginLeft="8dip"
         android:background="?attr/selectableItemBackground"
         />
 
@@ -38,8 +37,6 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:padding="16dip"
-        android:layout_marginRight="8dip" />
+        android:layout_marginRight="16dip" />
 
 </LinearLayout>
-
-
diff --git a/docs/html/guide/developing/devices/emulator.jd b/docs/html/guide/developing/devices/emulator.jd
index fe00531..8211275 100644
--- a/docs/html/guide/developing/devices/emulator.jd
+++ b/docs/html/guide/developing/devices/emulator.jd
@@ -32,6 +32,12 @@
         </ol>
       </li>
     </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a></li>
+    <li><a href="{@docRoot}guide/developing/devices/managing-avds.html">Managing AVDs with AVD Manager</a></li>
+  </ol>
 </div>
 </div>
 
@@ -63,8 +69,6 @@
 
 
 
-
-
 <h2  id="overview">Overview</h2>
 
 <p>The Android emulator is a QEMU-based application that provides a virtual ARM
@@ -166,7 +170,8 @@
 
 <p>To stop an emulator instance, just close the emulator's window.</p>
 
-
+<p>For a reference of the emulator's startup commands and keyboard mapping, see
+the <a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> document.</p>
 
 
 
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index ff667f2..5151ec1 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -3,6 +3,25 @@
 parent.link=index.html
 @jd:body
 
+<div id="qv-wrapper">
+<div id="qv">
+
+  <h2>In this document</h2>
+  <ol>
+    <li><a href="#startup-options">Emulator Startup Options</a></li>
+    <li><a href="#KeyMapping">Emulator Keyboard Mapping</a></li>
+  </ol>
+
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}guide/developing/devices/emulator.html">Using the Android Emulator</a></li>
+    <li><a href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a></li>
+  </ol>
+
+</div>
+</div>
+
+
 <p>The Android SDK includes a mobile device emulator &mdash; a virtual mobile device 
 that runs on your computer. The emulator lets you develop and test
 Android applications without using a physical device.</p>
@@ -451,7 +470,10 @@
   <td>See comments for <code>-skin</code>, above.</td></tr>
 </table>
 
-<h2>Emulator Keyboard Mapping</h2>
+
+
+<h2 id="KeyMapping">Emulator Keyboard Mapping</h2>
+
 <p>The table below summarizes the mappings between the emulator keys and and 
 the keys of your keyboard. </p>
 <p class="table-caption"><strong>Table 2.</strong> Emulator keyboard mapping</p>
diff --git a/docs/html/guide/practices/screen-compat-mode.jd b/docs/html/guide/practices/screen-compat-mode.jd
index a792386..6a77d60 100644
--- a/docs/html/guide/practices/screen-compat-mode.jd
+++ b/docs/html/guide/practices/screen-compat-mode.jd
@@ -48,7 +48,7 @@
 to resize for larger screens such as tablets. Since Android 1.6, Android has supported a
 variety of screen sizes and does most of the work to resize application layouts so that they
 properly fit each screen. However, if your application does not successfully follow the guide to
-<a href="{@docRoot}guide/topics/practices/screens_support.html">Supporting Multiple Screens</a>,
+<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>,
 then it might encounter some rendering issues on larger screens. For applications with this
 problem, screen compatibility mode can make the application a little more usable on larger
 screens.</p>
@@ -83,7 +83,7 @@
   <p>This was introduced with Android 3.2 to further
 assist applications on the latest tablet devices when the applications have not yet
 implemented techniques for <a
-href="{@docRoot}guide/topics/practices/screens_support.html">Supporting Multiple
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
 Screens</a>.</p>
   <p>In general, large screen devices running Android 3.2 or higher allow users to enable
 screen compatibility mode when the application does not <strong>explicitly declare that it supports
@@ -211,7 +211,7 @@
 which you should want your application to run&mdash;it causes pixelation and blurring in your UI,
 due to zooming. The proper way to make your application work well on large screens is to follow the
 guide to <a
-href="{@docRoot}guide/topics/practices/screens_support.html">Supporting Multiple Screens</a> and
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a> and
 provide alternative layouts for different screen sizes.</p>
 
 <p>By default, when you've set either <a
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index 5a9313e..02a8a8e 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -10,8 +10,8 @@
           android:<a href="#clear">clearTaskOnLaunch</a>=["true" | "false"]
           android:<a href="#config">configChanges</a>=["mcc", "mnc", "locale",
                                  "touchscreen", "keyboard", "keyboardHidden",
-                                 "navigation", "orientation", "screenLayout",
-                                 "fontScale", "uiMode"]
+                                 "navigation", "screenLayout", "fontScale", "uiMode",
+                                 "orientation", "screenSize", "smallestScreenSize"]
           android:<a href="#enabled">enabled</a>=["true" | "false"]
           android:<a href="#exclude">excludeFromRecents</a>=["true" | "false"]
           android:<a href="#exported">exported</a>=["true" | "false"]
@@ -205,10 +205,6 @@
    <td>"{@code navigation}"</td>
    <td>The navigation type (trackball/dpad) has changed.  (This should never normally happen.)</td>
 </tr><tr>
-   <td>"{@code orientation}"</td>
-   <td>The screen orientation has changed &mdash; the user has rotated
-       the device.</td>
- </tr><tr>
    <td>"{@code screenLayout}"</td>
    <td>The screen layout has changed &mdash; this might be caused by a
              different display being activated.</td>
@@ -221,7 +217,34 @@
    <td>The user interface mode has changed &mdash; this can be caused when the user places the
 device into a desk/car dock or when the the night mode changes. See {@link
 android.app.UiModeManager}. <em>Introduced in API Level 8</em>.</td>
-  </tr>
+  </tr><tr>
+   <td>"{@code orientation}"</td>
+   <td>The screen orientation has changed &mdash; the user has rotated the device. 
+       <p class="note"><strong>Note:</strong> If your application targets API level 13 or higher (as
+declared by the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> and <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+targetSdkVersion}</a> attributes), then you should also declare the {@code "screenSize"}
+configuration, because it also changes when a device switches between portrait and landscape
+orientations.</p></td>
+ </tr><tr>
+   <td>"{@code screenSize}"</td>
+   <td>The current available screen size has changed. This represents a change in the currently
+available size, relative to the current aspect ratio, so will change when the user switches between
+landscape and portrait. However, if your application targets API level 12 or lower, then your
+activity always handles this configuration change itself (this configuration change does not restart
+your activity, even when running on an Android 3.2 or higher device).
+  <p><em>Added in API level 13.</em></p></td>
+ </tr><tr>
+   <td>"{@code smallestScreenSize}"</td>
+   <td>The physical screen size has changed. This represents a change in size regardless of
+orientation, so will only change when the actual physical screen size has changed such as switching
+to an external display. A change to this configuration corresponds to a change in the <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">
+smallestWidth configuration</a>. However, if your application targets API level 12 or lower, then
+your activity always handles this configuration change itself (this configuration change does not
+restart your activity, even when running on an Android 3.2 or higher device).
+  <p><em>Added in API level 13.</em></p></td>
+ </tr>
 </table>
 
 <p>
diff --git a/docs/html/guide/topics/resources/runtime-changes.jd b/docs/html/guide/topics/resources/runtime-changes.jd
index 74a9073..871b063 100644
--- a/docs/html/guide/topics/resources/runtime-changes.jd
+++ b/docs/html/guide/topics/resources/runtime-changes.jd
@@ -25,80 +25,78 @@
 <p>Some device configurations can change during runtime
 (such as screen orientation, keyboard availability, and language). When such a change occurs,
 Android restarts the running
-Activity ({@link android.app.Activity#onDestroy()} is called, followed by {@link
+{@link android.app.Activity} ({@link android.app.Activity#onDestroy()} is called, followed by {@link
 android.app.Activity#onCreate(Bundle) onCreate()}). The restart behavior is designed to help your
 application adapt to new configurations by automatically reloading your application with
-alternative resources.</p>
+alternative resources that match the new device configuration.</p>
 
-<p>To properly handle a restart, it is important that your Activity restores its previous
+<p>To properly handle a restart, it is important that your activity restores its previous
 state through the normal <a
 href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity
 lifecycle</a>, in which Android calls
 {@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} before it destroys
-your Activity so that you can save data about the application state. You can then restore the state
+your activity so that you can save data about the application state. You can then restore the state
 during {@link android.app.Activity#onCreate(Bundle) onCreate()} or {@link
-android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}. To test
-that your application restarts itself with the application state intact, you should
-invoke configuration changes (such as changing the screen orientation) while performing various
-tasks in your application.</p>
+android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}.</p>
 
-<p>Your application should be able to restart at any time without loss of user data or
-state in order to handle events such as when the user receives an incoming phone call and then
-returns to your application (read about the
-<a href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity lifecycle</a>).</p>
+<p>To test that your application restarts itself with the application state intact, you should
+invoke configuration changes (such as changing the screen orientation) while performing various
+tasks in your application. Your application should be able to restart at any time without loss of
+user data or state in order to handle events such as configuration changes or when the user receives
+an incoming phone call and then returns to your application much later after your application
+process may have been destroyed. To learn how you can restore your activity state, read about the <a
+href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity lifecycle</a>.</p>
 
 <p>However, you might encounter a situation in which restarting your application and
 restoring significant amounts of data can be costly and create a poor user experience. In such a
-situation, you have two options:</p>
+situation, you have two other options:</p>
 
 <ol type="a">
   <li><a href="#RetainingAnObject">Retain an object during a configuration change</a>
-  <p>Allow your Activity to restart when a configuration changes, but carry a stateful
-{@link java.lang.Object} to the new instance of your Activity.</p>
+  <p>Allow your activity to restart when a configuration changes, but carry a stateful
+{@link java.lang.Object} to the new instance of your activity.</p>
 
   </li>
   <li><a href="#HandlingTheChange">Handle the configuration change yourself</a>
-  <p>Prevent the system from restarting your Activity during certain configuration
-changes and receive a callback when the configurations do change, so that you can manually update
-your Activity as necessary.</p>
+  <p>Prevent the system from restarting your activity during certain configuration
+changes, but receive a callback when the configurations do change, so that you can manually update
+your activity as necessary.</p>
   </li>
 </ol>
 
 
 <h2 id="RetainingAnObject">Retaining an Object During a Configuration Change</h2>
 
-<p>If restarting your Activity requires that you recover large sets of data, re-establish a
-network connection, or perform other intensive operations, then a full restart due to a
-configuration change might
-be an unpleasant user experience. Also, it may not be possible for you to completely
-maintain your Activity state with the {@link android.os.Bundle} that the system saves for you during
-the Activity lifecycle&mdash;it is not designed to carry large objects (such as bitmaps) and the
-data within it must be serialized then deserialized, which can consume a lot of memory and make the
-configuration change slow. In such a situation, you can alleviate the burden of reinitializing
-your Activity by retaining a stateful Object when your Activity is restarted due to a configuration
-change.</p>
+<p>If restarting your activity requires that you recover large sets of data, re-establish a network
+connection, or perform other intensive operations, then a full restart due to a configuration change
+might be a slow user experience. Also, it might not be possible for you to completely restore your
+activity state with the {@link android.os.Bundle} that the system saves for you with the {@link
+android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} callback&mdash;it is not
+designed to carry large objects (such as bitmaps) and the data within it must be serialized then
+deserialized, which can consume a lot of memory and make the configuration change slow. In such a
+situation, you can alleviate the burden of reinitializing your activity by retaining a stateful
+{@link java.lang.Object} when your activity is restarted due to a configuration change.</p>
 
-<p>To retain an Object during a runtime configuration change:</p>
+<p>To retain an object during a runtime configuration change:</p>
 <ol>
   <li>Override the {@link android.app.Activity#onRetainNonConfigurationInstance()} method to return
-the Object you would like to retain.</li>
-  <li>When your Activity is created again, call {@link
-android.app.Activity#getLastNonConfigurationInstance()} to recover your Object.</li>
+the object you would like to retain.</li>
+  <li>When your activity is created again, call {@link
+android.app.Activity#getLastNonConfigurationInstance()} to recover your object.</li>
 </ol>
 
-<p>Android calls {@link android.app.Activity#onRetainNonConfigurationInstance()} between {@link
-android.app.Activity#onStop()} and {@link
-android.app.Activity#onDestroy()} when it shuts down your Activity due to a configuration
-change. In your implementation of {@link
-android.app.Activity#onRetainNonConfigurationInstance()}, you can return any {@link
-java.lang.Object} that you need in order to efficiently restore your state after the configuration
-change.</p>
+<p>When the Android system shuts down your activity due to a configuration change, it calls {@link
+android.app.Activity#onRetainNonConfigurationInstance()} between the {@link
+android.app.Activity#onStop()} and {@link android.app.Activity#onDestroy()} callbacks. In your
+implementation of {@link android.app.Activity#onRetainNonConfigurationInstance()}, you can return
+any {@link java.lang.Object} that you need in order to efficiently restore your state after the
+configuration change.</p>
 
 <p>A scenario in which this can be valuable is if your application loads a lot of data from the
-web. If the user changes the orientation of the device and the Activity restarts, your application
+web. If the user changes the orientation of the device and the activity restarts, your application
 must re-fetch the data, which could be slow. What you can do instead is implement
 {@link android.app.Activity#onRetainNonConfigurationInstance()} to return an object carrying your
-data and then retrieve the data when your Activity starts again with {@link
+data and then retrieve the data when your activity starts again with {@link
 android.app.Activity#getLastNonConfigurationInstance()}. For example:</p>
 
 <pre>
@@ -113,11 +111,11 @@
 should never pass an object that is tied to the {@link android.app.Activity}, such as a {@link
 android.graphics.drawable.Drawable}, an {@link android.widget.Adapter}, a {@link android.view.View}
 or any other object that's associated with a {@link android.content.Context}. If you do, it will
-leak all the Views and resources of the original Activity instance. (To leak the resources
+leak all the views and resources of the original activity instance. (Leaking resources
 means that your application maintains a hold on them and they cannot be garbage-collected, so
 lots of memory can be lost.)</p>
 
-<p>Then retrieve the {@code data} when your Activity starts again:</p>
+<p>Then retrieve the data when your activity starts again:</p>
 
 <pre>
 &#64;Override
@@ -133,11 +131,10 @@
 }
 </pre>
 
-<p>In this case, {@link android.app.Activity#getLastNonConfigurationInstance()} retrieves
-the data saved by {@link android.app.Activity#onRetainNonConfigurationInstance()}. If {@code data}
-is null (which happens when the
-Activity starts due to any reason other than a configuration change) then the data object is loaded
-from the original source.</p>
+<p>In this case, {@link android.app.Activity#getLastNonConfigurationInstance()} returns the data
+saved by {@link android.app.Activity#onRetainNonConfigurationInstance()}. If {@code data} is null
+(which happens when the activity starts due to any reason other than a configuration change) then
+this code loads the data object from the original source.</p>
 
 
 
@@ -147,27 +144,27 @@
 
 <p>If your application doesn't need to update resources during a specific configuration
 change <em>and</em> you have a performance limitation that requires you to
-avoid the Activity restart, then you can declare that your Activity handles the configuration change
-itself, which prevents the system from restarting your Activity.</p>
+avoid the activity restart, then you can declare that your activity handles the configuration change
+itself, which prevents the system from restarting your activity.</p>
 
 <p class="note"><strong>Note:</strong> Handling the configuration change yourself can make it much
 more difficult to use alternative resources, because the system does not automatically apply them
-for you. This technique should be considered a last resort and is not recommended for most
-applications.</p>
+for you. This technique should be considered a last resort when you must avoid restarts due to a
+configuration change and is not recommended for most applications.</p>
 
-<p>To declare that your Activity handles a configuration change, edit the appropriate <a
-href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element
-in your manifest file to include the <a
+<p>To declare that your activity handles a configuration change, edit the appropriate <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element in
+your manifest file to include the <a
 href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
-android:configChanges}</a> attribute with a string value that represents the configuration that you
-want to handle. Possible values are listed in the documentation for
-the <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
-android:configChanges}</a> attribute (the most commonly used values are {@code orientation} to
-handle when the screen orientation changes and {@code keyboardHidden} to handle when the
-keyboard availability changes).  You can declare multiple configuration values in the attribute
-by separating them with a pipe character ("|").</p>
+android:configChanges}</a> attribute with a value that represents the configuration you want to
+handle. Possible values are listed in the documentation for the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> attribute (the most commonly used values are {@code "orientation"} to
+prevent restarts when the screen orientation changes and {@code "keyboardHidden"} to prevent
+restarts when the keyboard availability changes).  You can declare multiple configuration values in
+the attribute by separating them with a pipe {@code |} character.</p>
 
-<p>For example, the following manifest snippet declares an Activity that handles both the
+<p>For example, the following manifest code declares an activity that handles both the
 screen orientation change and keyboard availability change:</p>
 
 <pre>
@@ -176,20 +173,32 @@
           android:label="@string/app_name">
 </pre>
 
-<p>Now when one of these configurations change, {@code MyActivity} is not restarted.
-Instead, the Activity receives a call to {@link
+<p>Now, when one of these configurations change, {@code MyActivity} does not restart.
+Instead, the {@code MyActivity} receives a call to {@link
 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. This method
 is passed a {@link android.content.res.Configuration} object that specifies
 the new device configuration. By reading fields in the {@link android.content.res.Configuration},
 you can determine the new configuration and make appropriate changes by updating
 the resources used in your interface. At the
-time this method is called, your Activity's {@link android.content.res.Resources} object is updated
+time this method is called, your activity's {@link android.content.res.Resources} object is updated
 to return resources based on the new configuration, so you can easily
-reset elements of your UI without the system restarting your Activity.</p>
+reset elements of your UI without the system restarting your activity.</p>
+
+<p class="caution"><strong>Caution:</strong> Beginning with Android 3.2 (API level 13), <strong>the
+"screen size" also changes</strong> when the device switches between portrait and landscape
+orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing
+for API level 13 or higher (as declared by the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> and <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>
+attributes), you must include the {@code "screenSize"} value in addition to the {@code
+"orientation"} value. That is, you must decalare {@code
+android:configChanges="orientation|screenSize"}. However, if your application targets API level
+12 or lower, then your activity always handles this configuration change itself (this configuration
+change does not restart your activity, even when running on an Android 3.2 or higher device).</p>
 
 <p>For example, the following {@link
 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} implementation
-checks the availability of a hardware keyboard and the current device orientation:</p>
+checks the current device orientation:</p>
 
 <pre>
 &#64;Override
@@ -202,12 +211,6 @@
     } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
         Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
     }
-    // Checks whether a hardware keyboard is available
-    if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
-        Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
-    } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
-        Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
-    }
 }
 </pre>
 
@@ -216,7 +219,8 @@
 the configuration has changed and can simply re-assign all your resources that provide alternatives
 to the configuration that you're handling. For example, because the {@link
 android.content.res.Resources} object is now updated, you can reset
-any {@link android.widget.ImageView}s with {@link android.widget.ImageView#setImageResource(int)}
+any {@link android.widget.ImageView}s with {@link android.widget.ImageView#setImageResource(int)
+setImageResource()}
 and the appropriate resource for the new configuration is used (as described in <a
 href="providing-resources.html#AlternateResources">Providing Resources</a>).</p>
 
@@ -226,9 +230,9 @@
 to use with each field, refer to the appropriate field in the {@link
 android.content.res.Configuration} reference.</p>
 
-<p class="note"><strong>Remember:</strong> When you declare your Activity to handle a configuration
+<p class="note"><strong>Remember:</strong> When you declare your activity to handle a configuration
 change, you are responsible for resetting any elements for which you provide alternatives. If you
-declare your Activity to handle the orientation change and have images that should change
+declare your activity to handle the orientation change and have images that should change
 between landscape and portrait, you must re-assign each resource to each element during {@link
 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}.</p>
 
@@ -236,13 +240,14 @@
 changes, you can instead <em>not</em> implement {@link
 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. In
 which case, all of the resources used before the configuration change are still used
-and you've only avoided the restart of your Activity. However, your application should always be
-able to shutdown and restart with its previous state intact. Not only because
-there are other configuration changes that you cannot prevent from restarting your application but
-also in order to handle events such as when the user receives an incoming phone call and then
-returns to your application.</p>
+and you've only avoided the restart of your activity. However, your application should always be
+able to shutdown and restart with its previous state intact, so you should not consider this
+technique an escape from retaining your state during normal activity lifecycle. Not only because
+there are other configuration changes that you cannot prevent from restarting your application, but
+also because you should handle events such as when the user leaves your application and it gets
+destroyed before the user returns to it.</p>
 
-<p>For more about which configuration changes you can handle in your Activity, see the <a
+<p>For more about which configuration changes you can handle in your activity, see the <a
 href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
 android:configChanges}</a> documentation and the {@link android.content.res.Configuration}
 class.</p>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index a8b61bf..d412993 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -129,15 +129,14 @@
     'sdk': {
       'layout':"imgLeft",
       'icon':"sdk-small.png",
-      'name':"Android 3.2",
-      'img':"honeycomb-android.png",
-      'title':"Android 3.2 is here!",
-      'desc': "<p>Android 3.2 is a minor feature update that includes new APIs that allow you to "
-+ "better target your layouts for specific screen sizes and other miscellaneous new APIs.</p>"
+      'name':"Android 4.0",
+      'img':"ics-android.png",
+      'title':"Ice Cream Sandwich!",
+      'desc': "<br/><br/><br/><p>Oh my goodness, that looks tasty!</p>"
+/*
 + "<p>For more information about all the changes in Android 3.2, read the "
 + "<a href='{@docRoot}sdk/android-3.2.html'>version notes</a> and <a "
 + "href='{@docRoot}sdk/api_diff/13/changes.html'>diff report</a>.</p>"
-/*
 + "<p>If you have an existing SDK, add Android 3.0 as an "
 + "<a href='{@docRoot}sdk/adding-components.html'>SDK "
 + "component</a>. If you're new to Android, install the "
diff --git a/docs/html/offline.jd b/docs/html/offline.jd
index 1064a99..5f8e37ce 100644
--- a/docs/html/offline.jd
+++ b/docs/html/offline.jd
@@ -29,7 +29,7 @@
 especially <a href="{@docRoot}resources/samples/ApiDemos/index.html">API Demos</a></li>
     <li>Read the <a href="{@docRoot}guide/topics/fundamentals/index.html">Application
 Fundamentals</a></li>
-    <li>Read the <a href="{@docRoot}guide/developing/index.html">Overview</a> for using the SDK
+    <li>Read the <a href="{@docRoot}guide/developing/index.html">Introduction</a> for using the SDK
 tools</li>
   </ul>
 </div>
@@ -44,9 +44,6 @@
 
 <p>There's no additional setup.</p>
 
-<p>New Android platforms are saved in the <code>&lt;sdk>/platforms/</code> directory of
-your existing SDK and new add-ons are saved in the <code>&lt;sdk>/add-ons/</code> directory.</p>
-
 
 <div class="note">
 <p><strong>Note:</strong> You are currently viewing the offline version of the Android developer
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 3e673a5..310310e 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -419,16 +419,16 @@
   },
   {
     tags: ['sample', 'new'],
-    path: 'samples/AndroidBeam/index.html',
+    path: 'samples/AndroidBeamDemo/index.html',
     title: {
-      en: 'Android Beam'
+      en: 'Android Beam Demo'
     },
     description: {
       en: 'An example of how to use the Android Beam feature to send messages between two Android-powered devices (API level 14 or later) that support NFC.'
     }
   },
   {
-    tags: ['sample', 'layout', 'ui'],
+    tags: ['sample', 'layout', 'ui', 'updated'],
     path: 'samples/ApiDemos/index.html',
     title: {
       en: 'API Demos'
@@ -608,7 +608,7 @@
     }
   },
   {
-    tags: ['sample', 'accountsync'],
+    tags: ['sample', 'accountsync', 'updated'],
     path: 'samples/SampleSyncAdapter/index.html',
     title: {
       en: 'SampleSyncAdapter'
diff --git a/docs/html/resources/samples/images/hcgallery-phone1.png b/docs/html/resources/samples/images/hcgallery-phone1.png
new file mode 100644
index 0000000..9f0c280
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery-phone1.png
Binary files differ
diff --git a/docs/html/resources/samples/images/hcgallery-phone2.png b/docs/html/resources/samples/images/hcgallery-phone2.png
new file mode 100644
index 0000000..b049a65
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery-phone2.png
Binary files differ
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index 8f7ac55..b8cd947 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -10,6 +10,7 @@
 <ol>
   <li><a href="#relnotes">Revisions</a></li>
   <li><a href="#api">API Overview</a></li>
+  <li><a href="#Honeycomb">Previous APIs</a></li>
   <li><a href="#api-diff">API Differences Report</a></li>
   <li><a href="#api-level">API Level</a></li>
   <li><a href="#apps">Built-in Applications</a></li>
@@ -45,14 +46,14 @@
 Components</a>. If you are new to Android, <a
 href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
 
-<p>For a high-level introduction to the new user and developer features in Android 4.0, see the
-<a href="http://developer.android.com/sdk/android-4.0-highlights.html">Platform Highlights</a>.</p>
-
 <p class="note"><strong>Reminder:</strong> If you've already published an
 Android application, please test your application on Android {@sdkPlatformVersion} as
 soon as possible to be sure your application provides the best
 experience possible on the latest Android-powered devices.</p>
 
+<p>For a high-level introduction to the new user and developer features in Android 4.0, see the
+<a href="http://developer.android.com/sdk/android-4.0-highlights.html">Platform Highlights</a>.</p>
+
 
 <h2 id="relnotes">Revisions</h2>
 
@@ -92,21 +93,21 @@
 
   <div class="toggle-content-toggleme" style="padding-left:2em;">
     <ol class="toc" style="margin-left:-1em">
-      <li><a href="#Contacts">Contacts</a></li>
-      <li><a href="#Calendar">Calendar</a></li>
+      <li><a href="#Contacts">Contact Provider</a></li>
+      <li><a href="#Calendar">Calendar Provider</a></li>
+      <li><a href="#Voicemail">Voicemail Provider</a></li>
       <li><a href="#Camera">Camera</a></li>
       <li><a href="#Multimedia">Multimedia</a></li>
       <li><a href="#Bluetooth">Bluetooth</a></li>
       <li><a href="#AndroidBeam">Android Beam (NDEF Push with NFC)</a></li>
-      <li><a href="#P2pWiFi">Peer-to-peer Wi-Fi</a></li>
-      <li><a href="#NetworkData">Network Data</a></li>
-      <li><a href="#Sensors">Device Sensors</a></li>
-      <li><a href="#Renderscript">Renderscript</a></li>
+      <li><a href="#WiFiDirect">Wi-Fi Direct</a></li>
+      <li><a href="#NetworkUsage">Network Usage</a></li>
+      <li><a href="#RenderScript">RenderScript</a></li>
       <li><a href="#A11y">Accessibility</a></li>
       <li><a href="#Enterprise">Enterprise</a></li>
-      <li><a href="#Voicemail">Voicemail</a></li>
-      <li><a href="#SpellChecker">Spell Checker Services</a></li>
+      <li><a href="#Sensors">Device Sensors</a></li>
       <li><a href="#TTS">Text-to-speech Engines</a></li>
+      <li><a href="#SpellChecker">Spell Checker Services</a></li>
       <li><a href="#ActionBar">Action Bar</a></li>
       <li><a href="#UI">User Interface and Views</a></li>
       <li><a href="#Properties">Properties</a></li>
@@ -123,86 +124,96 @@
 
 
 
-<h3 id="Contacts">Contacts</h3>
+<h3 id="Contacts">Contact Provider</h3>
 
-<p>The Contact APIs that are defined by the {@link android.provider.ContactsContract} provider have
-been extended to support new features such as a personal profile for the device owner, large contact
-photos, and the ability for users to invite individual contacts to social networks that are
-installed on the device.</p>
+<p>The contact APIs that are defined by the {@link android.provider.ContactsContract} provider have
+been extended to support new features such as a personal profile for the device owner, high
+resolution contact photos, and the ability for users to invite individual contacts to social
+networks that are installed on the device.</p>
 
 
 <h4>User Profile</h4>
 
 <p>Android now includes a personal profile that represents the device owner, as defined by the
-{@link
-android.provider.ContactsContract.Profile} table.  Social apps that maintain a user identity     can
-contribute to the user's profile data by creating a new {@link
+{@link android.provider.ContactsContract.Profile} table.  Social apps that maintain a user identity 
+can contribute to the user's profile data by creating a new {@link
 android.provider.ContactsContract.RawContacts} entry within the {@link
 android.provider.ContactsContract.Profile}. That is, raw contacts that represent the device user do
 not belong in the traditional raw contacts table defined by the {@link
 android.provider.ContactsContract.RawContacts} Uri; instead, you must add a profile raw contact in
 the table at {@link android.provider.ContactsContract.Profile#CONTENT_RAW_CONTACTS_URI}. Raw
-contacts in this table are then aggregated into the single user-visible profile information.</p>
+contacts in this table are then aggregated into the single user-visible profile labeled "Me".</p>
 
 <p>Adding a new raw contact for the profile requires the {@link
 android.Manifest.permission#WRITE_PROFILE} permission. Likewise, in order to read from the profile
 table, you must request the {@link android.Manifest.permission#READ_PROFILE} permission. However,
-reading the user profile should not be required by most apps, even when contributing data to the
-profile. Reading the user profile is a sensitive permission and users will be very skeptical of apps
-that request reading their profile information.</p>
+most apps should need to read the user profile, even when contributing data to the
+profile. Reading the user profile is a sensitive permission and you should expect users to be
+skeptical of apps that request it.</p>
+
 
 <h4>Large photos</h4>
 
 <p>Android now supports high resolution photos for contacts. Now, when you push a photo into a
-contact
-record, the system processes it into both a 96x96 thumbnail (as it has previously) and a 256x256
-"display photo" stored in a new file-based photo store (the exact dimensions that the system chooses
-may vary in the future). You can add a large photo to a contact by putting a large photo in the
-usual {@link android.provider.ContactsContract.CommonDataKinds.Photo#PHOTO} column of a data row,
-which the system will then process into the appropriate thumbnail and display photo records.</p>
+contact record, the system processes it into both a 96x96 thumbnail (as it has previously) and a
+256x256 "display photo" that's stored in a new file-based photo store (the exact dimensions that the
+system chooses may vary in the future). You can add a large photo to a contact by putting a large
+photo in the usual {@link android.provider.ContactsContract.CommonDataKinds.Photo#PHOTO} column of a
+data row, which the system will then process into the appropriate thumbnail and display photo
+records.</p>
+
 
 <h4>Invite Intent</h4>
 
-<p>The {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent action allows you to
-invoke an action that indicates the user wants to add a contact to a social network that understand
-this intent and use it to invite the contact specified in the contact to that social network.</p> 
+<p>The {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent action allows an app
+to invoke an action that indicates the user wants to add a contact to a social network. The app
+receiving the app uses it to invite the specified contact to that
+social network. Most apps will be on the receiving-end of this operation. For example, the
+built-in People app invokes the invite intent when the user selects "Add connection" for a specific
+social app that's listed in a person's contact details.</p> 
 
-<p>Apps that use a sync adapter to provide information about contacts can register with the system
-to
-receive the invite intent when there’s an opportunity for the user to “invite” a contact to the
-app’s social network (such as from a contact card in the People app). To receive the invite intent,
-you simply need to add the {@code inviteContactActivity} attribute to your app’s XML sync
-configuration file, providing a fully-qualified name of the activity that the system should start
-when the user wants to “invite” a contact in your social network. The activity that starts can then
-retrieve the URI for the contact in question from the intent’s data and perform the necessary work
-to
-invite that contact to the network or add the person to the user’s connections.</p>
+<p>To make your app visible as in the "Add connection" list, your app must provide a sync adapter to
+sync contact information from your social network. You must then indicate to the system that your
+app responds to the {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent by
+adding the {@code inviteContactActivity} attribute to your app’s sync configuration file, with a
+fully-qualified name of the activity that the system should start when sending the invite intent.
+The activity that starts can then retrieve the URI for the contact in question from the intent’s
+data and perform the necessary work to invite that contact to the network or add the person to the
+user’s connections.</p>
+
+<p>See the <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Sample Sync
+Adapter</a> app for an example (specifically, see the <a
+href="{@docRoot}resources/samples/SampleSyncAdapter/res/xml-v14/contacts.html">contacts.xml</a>
+file).</p>
+
 
 <h4>Contact Usage Feedback</h4>
 
 <p>The new {@link android.provider.ContactsContract.DataUsageFeedback} APIs allow you to  help track
 how often the user uses particular methods of contacting people, such as how often the user uses
 each phone number or e-mail address. This information helps improve the ranking for each contact
-method associated with each person and provide such contact methods as suggestions.</p>
+method associated with each person and provide better suggestions for contacting each person.</p>
 
 
 
 
 
-<h3 id="Calendar">Calendar</h3>
+<h3 id="Calendar">Calendar Provider</h3>
 
-<p>The new calendar API allows you to access and modify the user’s calendars and events. The
-calendar
-APIs are provided with the {@link android.provider.CalendarContract} provider. Using the calendar
-provider, you can:</p>
-<ul>
-<li>Read, write, and modify calendars.</li>
-<li>Add and modify events, attendees, reminders, and alarms.</li>
-</ul>
+<p>The new calendar APIs allow you to access and modify the user’s calendars and events using the
+Calendar Provider. You can read, add, modify and delete calendars, events, attendees, reminders and
+alerts.</p>
 
-<p>{@link android.provider.CalendarContract} defines the data model of calendar and event-related
-information. All of the user’s calendar data is stored in a number of tables defined by subclasses
-of {@link android.provider.CalendarContract}:</p>
+<p>A variety of apps and widgets can use these APIs to read and modify calendar events. However,
+some of the most compelling use cases are sync adapters that synchronize the user's calendar from
+other calendar services with the Calendar Provider, in order to offer a unified location for
+all the user's events. Google Calendar, for example, uses a sync adapter to synchronize Google
+Calendar events with the Calendar Provider, which can then be viewed with Android's built-in
+Calendar app.</p>
+
+<p>The data model for calendars and event-related information in the Calendar Provider is
+defined by {@link android.provider.CalendarContract}. All the user’s calendar data is stored in a
+number of tables defined by various subclasses of {@link android.provider.CalendarContract}:</p>
 
 <ul>
 <li>The {@link android.provider.CalendarContract.Calendars} table holds the calendar-specific
@@ -210,11 +221,10 @@
 color, sync information, and so on.</li>
 
 <li>The {@link android.provider.CalendarContract.Events} table holds event-specific information.
-Each
-row in this table has the information for a single event. It contains information such as event
-title, location, start time, end time, and so on. The event can occur one-time or can recur multiple
-times. Attendees, reminders, and extended properties are stored in separate tables and reference the
-event’s _ID to link them with the event.</li>
+Each row in this table contains the information for a single event, such as the
+event title, location, start time, end time, and so on. The event can occur one time or recur
+multiple times. Attendees, reminders, and extended properties are stored in separate tables and
+use the event’s {@code _ID} to link them with the event.</li>
 
 <li>The {@link android.provider.CalendarContract.Instances} table holds the start and end time for
 occurrences of an event. Each row in this table represents a single occurrence. For one-time events
@@ -223,47 +233,93 @@
 
 <li>The {@link android.provider.CalendarContract.Attendees} table holds the event attendee or guest
 information. Each row represents a single guest of an event. It specifies the type of guest the
-person is and the person’s attendance response for the event.</li>
+person is and the person’s response for the event.</li>
 
 <li>The {@link android.provider.CalendarContract.Reminders} table holds the alert/notification data.
 Each row represents a single alert for an event. An event can have multiple reminders. The number of
-reminders per event is specified in MAX_REMINDERS, which is set by the Sync Adapter that owns the
-given calendar. Reminders are specified in minutes before the event and have a type.</li>
+reminders per event is specified in {@code MAX_REMINDERS}, which is set by the sync adapter that
+owns the given calendar. Reminders are specified in number-of-minutes before the event is
+scheduled and specify an alarm method such as to use an alert, email, or SMS to remind
+the user.</li>
 
 <li>The {@link android.provider.CalendarContract.ExtendedProperties} table hold opaque data fields
-used
-by the sync adapter. The provider takes no action with items in this table except to delete them
-when their related events are deleted.</li>
+used by the sync adapter. The provider takes no action with items in this table except to delete
+them when their related events are deleted.</li>
 </ul>
 
-<p>To access a user’s calendar data with the calendar provider, your application must request
-permission from the user by declaring <uses-permission
-android:name="android.permission.READ_CALENDAR" /> (for read access) and <uses-permission
-android:name="android.permission.WRITE_CALENDAR" /> (for write access) in their manifest files.</p>
+<p>To access a user’s calendar data with the Calendar Provider, your application must request 
+the {@link android.Manifest.permission#READ_CALENDAR} permission (for read access) and
+{@link android.Manifest.permission#WRITE_CALENDAR} (for write access).</p>
 
-<p>However, if all you want to do is add an event to the user’s calendar, you can instead use an
-INSERT
-{@link android.content.Intent} to start an activity in the Calendar app that creates new events.
-Using the intent does not require the WRITE_CALENDAR permission and you can specify the {@link
-android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME} and {@link
-android.provider.CalendarContract#EXTRA_EVENT_END_TIME} extra fields to pre-populate the form with
-the time of the event. The values for these times must be in milliseconds from the epoch. You must
-also specify {@code “vnd.android.cursor.item/event”} as the intent type.</p>
 
+<h4>Event intent</h4>
+
+<p>If all you want to do is add an event to the user’s calendar, you can use an
+{@link android.content.Intent#ACTION_INSERT} intent with a {@code "vnd.android.cursor.item/event"}
+MIME type to start an activity in the Calendar app that creates new events. Using the intent does
+not require any permission and you can specify event details with the following extras:</p>
+
+<ul>
+  <li>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}: Name for the
+event</li>
+  <li>{@link
+android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}:
+Event begin time in milliseconds from the
+epoch</li>
+  <li>{@link
+android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}: Event
+end time in milliseconds from the epoch</li>
+  <li>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION Events.EVENT_LOCATION}:
+Location of the event</li>
+  <li>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION Events.DESCRIPTION}: Event
+description</li>
+  <li>{@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}: Email addresses of those to
+invite</li>
+  <li>{@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}: The recurrence
+rule for the event</li>
+  <li>{@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL Events.ACCESS_LEVEL}:
+Whether the event is private or public</li>
+  <li>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY Events.AVAILABILITY}:
+Whether the time period of this event allows for other events to be scheduled at the same time</li>
+</ul>
+
+
+
+
+<h3 id="Voicemail">Voicemail Provider</h3>
+
+<p>The new voicemail APIs allows applications to add voicemails to a content provider on the device.
+Because the APIs currently do not allow third party apps to read all the voicemails from the system,
+the only third-party apps that should use the voicemail APIs are those that have voicemail to
+deliver to the user. For instance, it’s possible that a user has multiple voicemail sources, such as
+one provided by the phone’s service provider and others from VoIP or other alternative voice
+services. These apps can use the APIs to add their voicemails to the system for quick playback. The
+built-in Phone application presents all voicemails from the Voicemail Provider with a single list.
+Although the system’s Phone application is the only application that can read all the voicemails,
+each application that provides voicemails can read those that it has added to the system (but cannot
+read voicemails from other services).</p>
+
+<p>The {@link android.provider.VoicemailContract} class defines the content provider for the
+voicemail APIs. The subclasses {@link android.provider.VoicemailContract.Voicemails} and {@link
+android.provider.VoicemailContract.Status} provide tables in which the Voicemail Providers can
+insert voicemail data for storage on the device. For an example of a voicemail provider app, see the
+<a href=”{@docRoot}resources/samples/VoicemailProviderDemo/index.html”>Voicemail Provider
+Demo</a>.</p>
 
 
 
 
 <h3 id="Camera">Camera</h3>
 
-<p>The {@link android.hardware.Camera} APIs now support face detection and control for metering and
-focus areas.</p>
+<p>The {@link android.hardware.Camera} class now includes APIs for detecting faces and controlling
+focus and metering areas.</p>
 
-<h4>Face Detection</h4>
 
-<p>Camera apps can now enhance their abilities with Android’s face detection software, which not
-only
-detects the face of a subject, but also specific facial features, such as the eyes and mouth. </p>
+<h4>Face detection</h4>
+
+<p>Camera apps can now enhance their abilities with Android’s face detection APIs, which not
+only detect the face of a subject, but also specific facial features, such as the eyes and mouth.
+</p>
 
 <p>To detect faces in your camera application, you must register a {@link
 android.hardware.Camera.FaceDetectionListener} by calling {@link
@@ -271,41 +327,38 @@
 your camera surface and start  detecting faces by calling {@link
 android.hardware.Camera#startFaceDetection}.</p>
 
-<p>When the system detects a face, it calls the {@link
+<p>When the system detects one or more faces in the camera scene, it calls the {@link
 android.hardware.Camera.FaceDetectionListener#onFaceDetection onFaceDetection()} callback in your
 implementation of {@link android.hardware.Camera.FaceDetectionListener}, including an array of
 {@link android.hardware.Camera.Face} objects.</p>
 
 <p>An instance of the {@link android.hardware.Camera.Face} class provides various information about
-the
-face detected by the camera, including:</p>
+the face detected, including:</p>
 <ul>
 <li>A {@link android.graphics.Rect} that specifies the bounds of the face, relative to the camera's
 current field of view</li>
 <li>An integer betwen 0 and 100 that indicates how confident the system is that the object is a
-human
-face</li>
+human face</li>
 <li>A unique ID so you can track multiple faces</li>
 <li>Several {@link android.graphics.Point} objects that indicate where the eyes and mouth are
 located</li>
 </ul>
 
   
-<h4>Focus and Metering Areas</h4>
+<h4>Focus and metering areas</h4>
 
-<p>Camera apps can now control the areas that the camera uses for focus and when metering white
+<p>Camera apps can now control the areas that the camera uses for focus and for metering white
 balance
-and auto-exposure (when supported by the hardware). Both features use the new {@link
-android.hardware.Camera.Area} class to specify the region of the camera’s current view that should
-be focused or metered. An instance of the {@link android.hardware.Camera.Area} class defines the
-bounds of the area with a {@link android.graphics.Rect} and the weight of the
-area&mdash;representing the level of importance of that area, relative to other areas in
-consideration&mdash;with an integer.</p>
+and auto-exposure. Both features use the new {@link android.hardware.Camera.Area} class to specify
+the region of the camera’s current view that should be focused or metered. An instance of the {@link
+android.hardware.Camera.Area} class defines the bounds of the area with a {@link
+android.graphics.Rect} and the area's weight&mdash;representing the level of importance of that
+area, relative to other areas in consideration&mdash;with an integer.</p>
 
 <p>Before setting either a focus area or metering area, you should first call {@link
 android.hardware.Camera.Parameters#getMaxNumFocusAreas} or {@link
 android.hardware.Camera.Parameters#getMaxNumMeteringAreas}, respectively. If these return zero, then
-the device does not support the respective feature. </p>
+the device does not support the corresponding feature.</p>
 
 <p>To specify the focus or metering areas to use, simply call {@link
 android.hardware.Camera.Parameters#setFocusAreas setFocusAreas()} or {@link
@@ -313,17 +366,17 @@
 java.util.List} of {@link android.hardware.Camera.Area} objects that indicate the areas to consider
 for focus or metering. For example, you might implement a feature that allows the user to set the
 focus area by touching an area of the preview, which you then translate to an {@link
-android.hardware.Camera.Area} object and set the focus to that spot. The focus or exposure in that
-area will continually update as the scene in the area changes.</p>
+android.hardware.Camera.Area} object and request that the camera focus on that area of the scene.
+The focus or exposure in that area will continually update as the scene in the area changes.</p>
 
 
-<h4>Other Camera Features</h4>
+<h4>Other camera features</h4>
+
 <ul>
-<li>Capture photos during video recording
-While recording video, you can now call {@link android.hardware.Camera#takePicture takePicture()} to
-save a photo without interrupting the video session. Before doing so, you should call {@link
-android.hardware.Camera.Parameters#isVideoSnapshotSupported} to be sure the hardware supports
-it.</li>
+<li>While recording video, you can now call {@link android.hardware.Camera#takePicture
+takePicture()} to save a photo without interrupting the video session. Before doing so, you should
+call {@link android.hardware.Camera.Parameters#isVideoSnapshotSupported} to be sure the hardware
+supports it.</li>
 
 <li>Lock auto exposure and white balance with {@link
 android.hardware.Camera.Parameters#setAutoExposureLock setAutoExposureLock()} and {@link
@@ -331,45 +384,50 @@
 these properties from changing.</li>
 </ul>
 
-<h4>Camera Broadcast Intents</h4>
+
+<h4>Camera broadcast intents</h4>
 
 <ul>
-<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE} 
-This indicates that the user has captured a new photo. The built-in camera app invokes this
+<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE}:
+This indicates that the user has captured a new photo. The built-in Camera app invokes this
 broadcast after a photo is captured and third-party camera apps should also broadcast this intent
 after capturing a photo.</li>
-<li>{@link android.hardware.Camera#ACTION_NEW_VIDEO Camera.ACTION_NEW_VIDEO}
-This indicates that the user has captured a new video. The built-in camera app invokes this
+<li>{@link android.hardware.Camera#ACTION_NEW_VIDEO Camera.ACTION_NEW_VIDEO}:
+This indicates that the user has captured a new video. The built-in Camera app invokes this
 broadcast after a video is recorded and third-party camera apps should also broadcast this intent
 after capturing a video.</li>
 </ul>
 
-  
-  
 
-  
+
+
+
 <h3 id="Multimedia">Multimedia</h3>
 
 <p>Android 4.0 adds several new APIs for applications that interact with media such as photos,
-videos,
-and music.</p>
+videos, and music.</p>
 
 
-<h4>Media Player</h4>
+<h4>Media player</h4>
 
 <ul>
-<li>Streaming online media from {@link android.media.MediaPlayer} now requires {@link
+<li>Streaming online media from {@link android.media.MediaPlayer} now requires the {@link
 android.Manifest.permission#INTERNET} permission. If you use {@link android.media.MediaPlayer} to
-play content from the internet, be sure to add the {@link android.Manifest.permission#INTERNET}
-permission or else your media playback will not work beginning with Android 4.0.</li>
+play content from the Internet, be sure to add the {@link android.Manifest.permission#INTERNET}
+permission to your manifest or else your media playback will not work beginning with Android
+4.0.</li>
+
 <li>{@link android.media.MediaPlayer#setSurface(Surface) setSurface()} allows you define a {@link
 android.view.Surface} to behave as the video sink.</li>
+
 <li>{@link android.media.MediaPlayer#setDataSource(Context,Uri,Map) setDataSource()} allows you to
 send additional HTTP headers with your request, which can be useful for HTTP(S) live streaming</li>
+
 <li>HTTP(S) live streaming now respects HTTP cookies across requests</li>
 </ul>
 
-<h4>Media Type Support</h4>
+
+<h4>Media types</h4>
 
 <p>Android 4.0 adds support for:</p>
 <ul>
@@ -382,16 +440,17 @@
 Formats</a>.</p>
 
 
-<h4>Remote Control Client</h4>
+
+<h4>Remote control client</h4>
 
 <p>The new {@link android.media.RemoteControlClient} allows media players to enable playback
-controls
-from remote control clients such as the device lock screen. Media players can also expose
+controls from remote control clients such as the device lock screen. Media players can also expose
 information about the media currently playing for display on the remote control, such as track
 information and album art.</p>
 
 <p>To enable remote control clients for your media player, instantiate a {@link
-android.media.RemoteControlClient} with a {@link android.app.PendingIntent} that broadcasts {@link
+android.media.RemoteControlClient} with its constructor, passing it a {@link
+android.app.PendingIntent} that broadcasts {@link
 android.content.Intent#ACTION_MEDIA_BUTTON}. The intent must also declare the explicit {@link
 android.content.BroadcastReceiver} component in your app that handles the {@link
 android.content.Intent#ACTION_MEDIA_BUTTON} event.</p>
@@ -419,21 +478,19 @@
 
 <p>For a sample implementation, see the <a
 href=”{@docRoot}resources/samples/RandomMusicPlayer/index.html”>Random Music Player</a>, which
-provides compatibility logic such that it enables the remote control client while continuing to
-support Android 2.1 devices.</p>
+provides compatibility logic such that it enables the remote control client on Android 4.0
+devices while continuing to support devices back to Android 2.1.</p>
 
 
 <h4>Media Effects</h4>
 
 <p>A new media effects framework allows you to apply a variety of visual effects to images and
-videos.
-The system performs all effects processing on the GPU to obtain maximum performance. Applications in
-Android 4.0 such as Google Talk or the Gallery editor make use of the effects API to apply real-time
-effects to video and photos.</p>
+videos. The system performs all effects processing on the GPU to obtain maximum performance.
+New applications for Android 4.0 such as Google Talk and the Gallery editor make use of the
+effects API to apply real-time effects to video and photos.</p>
 
 <p>For maximum performance, effects are applied directly to OpenGL textures, so your application
-must
-have a valid OpenGL context before it can use the effects APIs. The textures to which you apply
+must have a valid OpenGL context before it can use the effects APIs. The textures to which you apply
 effects may be from bitmaps, videos or even the camera. However, there are certain restrictions that
 textures must meet:</p>
 <ol>
@@ -442,8 +499,7 @@
 </ol>
 
 <p>An {@link android.media.effect.Effect} object defines a single media effect that you can apply to
-an
-image frame. The basic workflow to create an {@link android.media.effect.Effect} is:</p>
+an image frame. The basic workflow to create an {@link android.media.effect.Effect} is:</p>
 
 <ol>
 <li>Call {@link android.media.effect.EffectContext#createWithCurrentGlContext
@@ -452,17 +508,15 @@
 android.media.effect.EffectContext#getFactory EffectContext.getFactory()}, which returns an instance
 of {@link android.media.effect.EffectFactory}.</li>
 <li>Call {@link android.media.effect.EffectFactory#createEffect createEffect()}, passing it an
-effect
-name from @link android.media.effect.EffectFactory}, such as {@link
+effect name from @link android.media.effect.EffectFactory}, such as {@link
 android.media.effect.EffectFactory#EFFECT_FISHEYE} or {@link
 android.media.effect.EffectFactory#EFFECT_VIGNETTE}.</li>
 </ol>
 
 <p>Not all devices support all effects, so you must first check if the desired effect is supported
-by
-calling {@link android.media.effect.EffectFactory#isEffectSupported isEffectSupported()}.</p>
+by calling {@link android.media.effect.EffectFactory#isEffectSupported isEffectSupported()}.</p>
 
-<p>You can adjust the effect’s parameters by calling {@link android.media.effect.Effect#setParameter
+<p>You can adjust an effect’s parameters by calling {@link android.media.effect.Effect#setParameter
 setParameter()} and passing a parameter name and parameter value. Each type of effect accepts
 different parameters, which are documented with the effect name. For example, {@link
 android.media.effect.EffectFactory#EFFECT_FISHEYE} has one parameter for the {@code scale} of the
@@ -475,7 +529,7 @@
 image (usually done by calling the {@link android.opengl.GLES20#glTexImage2D glTexImage2D()}
 function). You may provide multiple mipmap levels. If the output texture has not been bound to a
 texture image, it will be automatically bound by the effect as a {@link
-android.opengl.GLES20#GL_TEXTURE_2D}. It will contain one mipmap level (0), which will have the same
+android.opengl.GLES20#GL_TEXTURE_2D} and with one mipmap level (0), which will have the same
 size as the input.</p> 
 
 
@@ -496,7 +550,7 @@
 android.bluetooth.BluetoothProfile#HEALTH} profile type to establish a connection with the profile
 proxy object.</p>
 
-<p>Once you’ve acquired the Health profile proxy (the {@link android.bluetooth.BluetoothHealth}
+<p>Once you’ve acquired the Health Profile proxy (the {@link android.bluetooth.BluetoothHealth}
 object), connecting to and communicating with paired health devices involves the following new
 Bluetooth classes:</p>
 <ul>
@@ -510,15 +564,15 @@
 android.bluetooth.BluetoothHealth} APIs.</li>
 </ul>
 
-<p>For more information about using the Bluetooth Health profile, see the documentation for {@link
+<p>For more information about using the Bluetooth Health Profile, see the documentation for {@link
 android.bluetooth.BluetoothHealth}.</p>
 
 
+
 <h3 id="AndroidBeam">Android Beam (NDEF Push with NFC)</h3>
 
-<p>Android Beam allows you to send NDEF messages (an NFC standard for data stored on NFC tags) from
-one
-device to another (a process also known as “NDEF Push”). The data transfer is initiated when two
+<p>Android Beam is a new NFC feature that allows you to send NDEF messages from one device to
+another (a process also known as “NDEF Push”). The data transfer is initiated when two
 Android-powered devices that support Android Beam are in close proximity (about 4 cm), usually with
 their backs touching. The data inside the NDEF message can contain any data that you wish to share
 between devices. For example, the People app shares contacts, YouTube shares videos, and Browser
@@ -526,29 +580,30 @@
 
 <p>To transmit data between devices using Android Beam, you need to create an {@link
 android.nfc.NdefMessage} that contains the information you want to share while your activity is in
-the foreground. You must then pass the
-{@link android.nfc.NdefMessage} to the system in one of two ways:</p>
+the foreground. You must then pass the {@link android.nfc.NdefMessage} to the system in one of two
+ways:</p>
 
 <ul>
-<li>Define a single {@link android.nfc.NdefMessage} to use from the activity:
+<li>Define a single {@link android.nfc.NdefMessage} to push while in the activity:
 <p>Call {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} at any time to set
-the
-message you want to send. For instance, you might call this method and pass it your {@link
+the message you want to send. For instance, you might call this method and pass it your {@link
 android.nfc.NdefMessage} during your activity’s {@link android.app.Activity#onCreate onCreate()}
-method. Then, whenever Android Beam is activated with another device while your activity is in the
-foreground, the system sends that {@link android.nfc.NdefMessage} to the other device.</p></li>
+method. Then, whenever Android Beam is activated with another device while the activity is in the
+foreground, the system sends the {@link android.nfc.NdefMessage} to the other device.</p></li>
 
-<li>Define the {@link android.nfc.NdefMessage} depending on the current context:
-<p>Implement {@link android.nfc.NfcAdapter.CreateNdefMessageCallback}, in which the {@link
-android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()} callback
+<li>Define the {@link android.nfc.NdefMessage} to push at the time that Android Beam is initiated:
+<p>Implement {@link android.nfc.NfcAdapter.CreateNdefMessageCallback}, in which your
+implementation of the {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
 method returns the {@link android.nfc.NdefMessage} you want to send. Then pass the {@link
-android.nfc.NfcAdapter.CreateNdefMessageCallback} to {@link
-android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}. In this case, when
-Android Beam is activated with another device while your activity is in the foreground, the system
-calls {@link android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
-to retrieve the {@link android.nfc.NdefMessage} you want to send. This allows you to create a
-different {@link android.nfc.NdefMessage} for each occurrence, depending on the user context (such
-as which contact in the People app is currently visible).</p></li>
+android.nfc.NfcAdapter.CreateNdefMessageCallback} implementation to {@link
+android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}.</p>
+<p>In this case, when Android Beam is activated with another device while your activity is in the
+foreground, the system calls {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()} to retrieve
+the {@link android.nfc.NdefMessage} you want to send. This allows you to define the {@link
+android.nfc.NdefMessage} to deliver only once Android Beam is initiated, in case the contents
+of the message might vary throughout the life of the activity.</p></li>
 </ul>
 
 <p>In case you want to run some specific code once the system has successfully delivered your NDEF
@@ -562,7 +617,7 @@
 tags. The system invokes an intent with the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
 action to start an activity, with either a URL or a MIME type set according to the first {@link
 android.nfc.NdefRecord} in the {@link android.nfc.NdefMessage}. For the activity you want to
-respond, you can set intent filters for the URLs or MIME types your app cares about. For more
+respond, you can declare intent filters for the URLs or MIME types your app cares about. For more
 information about Tag Dispatch see the <a
 href=”{@docRoot}guide/topics/nfc/index.html#dispatch”>NFC</a> developer guide.</p>
 
@@ -573,46 +628,51 @@
 should create an intent filter for your activity using the same URI scheme in order to receive the
 incoming NDEF message.</p>
 
-<p>You may also want to pass an “Android application record” with your {@link
-android.nfc.NdefMessage}
-in order to guarantee a specific application handles an NDEF message, regardless of whether other
-applications filter for the same intent. You can create an Android application record by calling
-{@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}, passing it the
-application’s package name. When the other device receives the NDEF message with this record, the
-system automatically starts the application matching the package name. If the target device does not
-currently have the application installed, the system uses the Android application record to launch
-Android Market and take the user to the application to install it.</p>
+<p>You should also pass an “Android application record” with your {@link android.nfc.NdefMessage} in
+order to guarantee that your application handles the incoming NDEF message, even if other
+applications filter for the same intent action. You can create an Android application record by
+calling {@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}, passing it
+your application’s package name. When the other device receives the NDEF message with the
+application record and multiple applications contain activities that handle the specified intent,
+the system always delivers the message to the activity in your application (based on the matching
+application record). If the target device does not currently have your application installed, the
+system uses the Android application record to launch Android Market and take the user to the
+application in order to install it.</p>
 
 <p>If your application doesn’t use NFC APIs to perform NDEF Push messaging, then Android provides a
 default behavior: When your application is in the foreground on one device and Android Beam is
 invoked with another Android-powered device, then the other device receives an NDEF message with an
 Android application record that identifies your application. If the receiving device has the
 application installed, the system launches it; if it’s not installed, Android Market opens and takes
-the user to your application so they can install it.</p>
+the user to your application in order to install it.</p>
+
+<p>For some example code, see the <a
+href="{@docRoot}resources/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.html">Android
+Beam Demo</a> sample app.</p>
 
 
 
 
+<h3 id="WiFiDirect">Wi-Fi Direct</h3>
 
-<h3 id="P2pWiFi">Peer-to-peer Wi-Fi</h3>
-
-<p>Android now supports Wi-Fi Direct&trade; for peer-to-peer (P2P) connections between
-Android-powered
+<p>Android now supports Wi-Fi Direct for peer-to-peer (P2P) connections between Android-powered
 devices and other device types without a hotspot or Internet connection. The Android framework
 provides a set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each
-device supports Wi-Fi Direct&trade;, then communicate over a speedy connection across distances much
-longer than a Bluetooth connection.</p>
+device supports Wi-Fi Direct, then communicate over a speedy connection across distances much longer
+than a Bluetooth connection.</p>
 
 <p>A new package, {@link android.net.wifi.p2p}, contains all the APIs for performing peer-to-peer
 connections with Wi-Fi. The primary class you need to work with is {@link
-android.net.wifi.p2p.WifiP2pManager}, for which you can get an instance by calling {@link
+android.net.wifi.p2p.WifiP2pManager}, which you can acquire by calling {@link
 android.app.Activity#getSystemService getSystemService(WIFI_P2P_SERVICE)}. The {@link
-android.net.wifi.p2p.WifiP2pManager} provides methods that allow you to:</p>
+android.net.wifi.p2p.WifiP2pManager} includes APIs that allow you to:</p>
 <ul>
 <li>Initialize your application for P2P connections by calling {@link
 android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</li>
+
 <li>Discover nearby devices by calling {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers
 discoverPeers()}</li>
+
 <li>Start a P2P connection by calling {@link android.net.wifi.p2p.WifiP2pManager#connect
 connect()}</li>
 <li>And more</li>
@@ -622,18 +682,20 @@
 <ul>
 <li>The {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} interface allows you to receive
 callbacks when an operation such as discovering peers or connecting to them succeeds or fails.</li>
+
 <li>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface allows you to receive
 information about discovered peers. The callback provides a {@link
 android.net.wifi.p2p.WifiP2pDeviceList}, from which you can retrieve a {@link
 android.net.wifi.p2p.WifiP2pDevice} object for each device within range and get information such as
 the device name, address, device type, the WPS configurations the device supports, and more.</li>
+
 <li>The {@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener} interface allows you to
-receive
-information about a P2P group. The callback provides a {@link android.net.wifi.p2p.WifiP2pGroup}
-object, which provides group information such as the owner, the network name, and passphrase.</li>
+receive information about a P2P group. The callback provides a {@link
+android.net.wifi.p2p.WifiP2pGroup} object, which provides group information such as the owner, the
+network name, and passphrase.</li>
+
 <li>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener} interface allows you to
-receive
-information about the current connection. The callback provides a {@link
+receive information about the current connection. The callback provides a {@link
 android.net.wifi.p2p.WifiP2pInfo} object, which has information such as whether a group has been
 formed and who is the group owner.</li>
 </ul>
@@ -642,58 +704,57 @@
 <ul>
 <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
 <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-<li>{@link android.Manifest.permission#INTERNET} (even though your app doesn’t technically connect
-to
-the Internet, the WiFi Direct implementation uses traditional sockets that do require Internet
+<li>{@link android.Manifest.permission#INTERNET} (although your app doesn’t technically connect
+to the Internet, the WiFi Direct implementation uses sockets that do require Internet
 permission to work).</li>
 </ul>
 
 <p>The Android system also broadcasts several different actions during certain Wi-Fi P2P events:</p>
 <ul>
 <li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}: The P2P
-connection
-state has changed. This carries {@link android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_P2P_INFO} with
-a {@link android.net.wifi.p2p.WifiP2pInfo} object and {@link
+connection state has changed. This carries {@link
+android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_P2P_INFO} with a {@link
+android.net.wifi.p2p.WifiP2pInfo} object and {@link
 android.net.wifi.p2p.WifiP2pManager#EXTRA_NETWORK_INFO} with a {@link android.net.NetworkInfo}
 object.</li>
+
 <li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}: The P2P state has
-changed
-between enabled and disabled. It carries {@link
+changed between enabled and disabled. It carries {@link
 android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_STATE} with either {@link
 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_DISABLED} or {@link
 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_ENABLED}</li>
+
 <li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}: The list of peer
-devices
-has changed.</li>
+devices has changed.</li>
+
 <li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}: The details for
 this device have changed.</li>
 </ul>
 
 <p>See the  {@link android.net.wifi.p2p.WifiP2pManager} documentation for more information. Also
-look
-at the <a href=”{@docRoot}resources/samples/WiFiDirectDemo/index.html”>Wi-Fi Direct</a> sample
-application for example code.</p>
+look at the <a href=”{@docRoot}resources/samples/WiFiDirectDemo/index.html”>Wi-Fi Direct Demo</a>
+sample application.</p>
 
 
 
 
 
-<h3 id="NetworkData">Network Data</h3>
+<h3 id="NetworkUsage">Network Usage</h3>
 
-<p>Android 4.0 gives users precise visibility of how much network data applications are using. The
-Settings app provides controls that allow users to manage set limits for network data usage and even
-disable the use of background data for individual apps. In order to avoid users disabling your app’s
-access to data from the background, you should develop strategies to use use the data connection
-efficiently and vary your usage depending on the type of connection available.</p>
+<p>Android 4.0 gives users precise visibility of how much network data their applications are using.
+The Settings app provides controls that allow users to manage set limits for network data usage and
+even disable the use of background data for individual apps. In order to avoid users disabling your
+app’s access to data from the background, you should develop strategies to use use the data
+connection efficiently and adjust your usage depending on the type of connection available.</p>
 
 <p>If your application performs a lot of network transactions, you should provide user settings that
 allow users to control your app’s data habits, such as how often your app syncs data, whether to
 perform uploads/downloads only when on Wi-Fi, whether to use data while roaming, etc. With these
 controls available to them, users are much less likely to disable your app’s access to data when
 they approach their limits, because they can instead precisely control how much data your app uses.
-When you provide an activity with these settings, you should include in its manifest declaration an
-intent filter for the {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action. For
-example:</p>
+If you provide a preference activity with these settings, you should include in its manifest
+declaration an intent filter for the {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE}
+action. For example:</p>
 
 <pre>
 &lt;activity android:name="DataPreferences" android:label="@string/title_preferences">
@@ -704,10 +765,10 @@
 &lt;/activity>
 </pre>
 
-<p>This intent filter indicates to the system that this is the application that controls your
+<p>This intent filter indicates to the system that this is the activity that controls your
 application’s data usage. Thus, when the user inspects how much data your app is using from the
-Settings app, a “View application settings” button is available that launches your activity so the
-user can refine how much data your app uses.</p>
+Settings app, a “View application settings” button is available that launches your
+preference activity so the user can refine how much data your app uses.</p>
 
 <p>Also beware that {@link android.net.ConnectivityManager#getBackgroundDataSetting()} is now
 deprecated and always returns true&mdash;use  {@link
@@ -715,7 +776,7 @@
 transactions, you should always call {@link android.net.ConnectivityManager#getActiveNetworkInfo()}
 to get the {@link android.net.NetworkInfo} that represents the current network and query {@link
 android.net.NetworkInfo#isConnected()} to check whether the device has a
-connection. You can then check various other connection properties, such as whether the device is
+connection. You can then check other connection properties, such as whether the device is
 roaming or connected to Wi-Fi.</p>
 
 
@@ -724,43 +785,10 @@
 
 
 
-<h3 id="Sensors">Device Sensors</h3>
 
-<p>Two new sensor types have been added in Android 4.0: {@link
-android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and {@link
-android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}. </p>
+<h3 id="RenderScript">RenderScript</h3>
 
-<p>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} is a temperature sensor that provides
-the ambient (room) temperature near a device. This sensor reports data in degrees Celsius. {@link
-android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} is a humidity sensor that provides the relative
-ambient (room) humidity. The sensor reports data as a percentage. If a device has both {@link
-android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and  {@link
-android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} sensors, you can use them to calculate the dew point
-and the absolute humidity.</p>
-
-<p>The existing temperature sensor ({@link android.hardware.Sensor#TYPE_TEMPERATURE}) has been
-deprecated. You should use the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor
-instead.</p>
-
-<p>Additionally, Android’s three synthetic sensors have been improved so they now have lower latency
-and smoother output. These sensors include the gravity sensor ({@link
-android.hardware.Sensor#TYPE_GRAVITY}), rotation vector sensor ({@link
-android.hardware.Sensor#TYPE_ROTATION_VECTOR}), and linear acceleration sensor ({@link
-android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}). The improved sensors rely on the gyroscope
-sensor to improve their output so the sensors appear only on devices that have a gyroscope. If a
-device already provides one of the sensors, then that sensor appears as a second sensor on the
-device. The three improved sensors have a version number of 2.</p>
-
-
-
-
-
-
-
-
-<h3 id="Renderscript">Renderscript</h3>
-
-<p>Three major features have been added to Renderscript:</p>
+<p>Three major features have been added to RenderScript:</p>
 
 <ul>
   <li>Off-screen rendering to a framebuffer object</li>
@@ -771,24 +799,24 @@
 <p>The {@link android.renderscript.Allocation} class now supports a {@link
 android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} memory space, which allows you to
 render things directly into the {@link android.renderscript.Allocation} and use it as a framebuffer
-object.  </p>
+object.</p>
 
-<p>{@link android.renderscript.RSTextureView} provides a means to display Renderscript graphics
-inside
-of a normal View,  unlike {@link android.renderscript.RSSurfaceView}, which creates a separate
-window. This key difference allows you to do things such as move, transform, or animate an {@link
-android.renderscript.RSTextureView} as well as draw Renderscript graphics inside the View alongside
-other traditional View widgets.</p>
+<p>{@link android.renderscript.RSTextureView} provides a means to display RenderScript graphics
+inside of a {@link android.view.View},  unlike {@link android.renderscript.RSSurfaceView}, which
+creates a separate window. This key difference allows you to do things such as move, transform, or
+animate an {@link android.renderscript.RSTextureView} as well as draw RenderScript graphics inside
+a view that lies within an activity layout.</p>
 
-<p>The {@link android.renderscript.Script#forEach forEach()} method allows you to call Renderscript
-compute scripts from the VM level and have them automatically delegated to available cores on the
-device. You do not use this method directly, but any compute Renderscript that you write will have a
-{@link android.renderscript.Script#forEach forEach()}  method that you can call in the reflected
-Renderscript class. You can call the reflected {@link android.renderscript.Script#forEach forEach()}
-method by passing in an input {@link android.renderscript.Allocation} to process, an output {@link
-android.renderscript.Allocation} to write the result to, and a data structure if the Renderscript
-needs more information in addition to the {@link android.renderscript.Allocation}s to. Only one of
-the {@link android.renderscript.Allocation}s is necessary and the data structure is optional.</p>
+<p>The {@link android.renderscript.Script#forEach Script.forEach()} method allows you to call
+RenderScript compute scripts from the VM level and have them automatically delegated to available
+cores on the device. You do not use this method directly, but any compute RenderScript that you
+write will have a {@link android.renderscript.Script#forEach forEach()}  method that you can call in
+the reflected RenderScript class. You can call the reflected {@link
+android.renderscript.Script#forEach forEach()} method by passing in an input {@link
+android.renderscript.Allocation} to process, an output {@link android.renderscript.Allocation} to
+write the result to, and a {@link android.renderscript.FieldPacker} data structure in case the
+RenderScript needs more information. Only one of the {@link android.renderscript.Allocation}s is
+necessary and the data structure is optional.</p>
 
 
 
@@ -797,118 +825,154 @@
 
 <h3 id="A11y">Accessibility</h3>
 
-<p>Android 4.0 improves accessibility for users with disabilities with the Touch Exploration service
-and provides extended APIs for developers of new accessibility services.</p>
-
-<h4>Touch Exploration</h4>
-
-<p>Users with vision loss can now explore applications by touching areas of the screen and hearing
-voice descriptions of the content. The “Explore by Touch” feature works like a virtual cursor as the
-user drags a finger across the screen.</p>
-
-<p>You don’t have to use any new APIs to enhance touch exploration in your application, because the
-existing {@link android.R.attr#contentDescription android:contentDescription}
-attribute and {@link android.view.View#setContentDescription setContentDescription()} method is all
-you need. Because touch exploration works like a virtual cursor, it allows screen readers to
-identify the descriptive the same way that screen readers can when navigating with a d-pad or
-trackball. So this is a reminder to provide descriptive text for the views in your application,
-especially for {@link android.widget.ImageButton}, {@link android.widget.EditText}, {@link
-android.widget.CheckBox} and other interactive widgets that might not contain text information by
-default.</p>
-
-<h4>Accessibility for Custom Views</h4>
-
-<p>Developers of custom Views, ViewGroups and widgets can make their components compatible with
-accessibility services like Touch Exploration. For custom views and widgets targeted for Android 4.0
-and later, developers should implement the following accessibility API methods in their classes:</p>
-<ul>
-<li>These two methods initiate the accessibility event generation process and must be implemented by
-your custom view class.
-  <ul>
-  <li>{@link android.view.View#sendAccessibilityEvent(int) sendAccessibilityEvent()} If
-accessibility
-  is
-  not enabled, this call has no effect.</li>
-  <li>{@link
-  android.view.View#sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent)
-  sendAccessibilityEventUnchecked()} - This method executes regardless of whether accessibility is
-  enabled or not.</li>
-  </ul>
-</li>
-
-<li>These methods are called in order by the sendAccessibilityEvent methods listed above to collect
-accessibility information about the view, and its child views.
-  <ul>
-  <li>{@link
-  android.view.View#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
-  onInitializeAccessibilityEvent()} - This method collects information about the view. If your
-  application has specific requirements for accessibility, you should extend this method to add that
-  information to the {@link android.view.accessibility.AccessibilityEvent}.</li>
-  
-  <li>{@link
- 
-android.view.View#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
-  dispatchPopulateAccessibilityEvent()} is called by the framework to request text information for
-  this view and its children. This method calls {@link
-  android.view.View#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
-  onPopulateAccessibilityEvent()} first on the current view and then on its children.</li>
-  </ul>
-</li>
-
-<li>The {@link
-android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()} method
-provides additional context information for
-accessibility services. You should implement or override this method to provide improved information
-for accessibility services investigating your custom view.</li>
-
-<li>Custom {@link android.view.ViewGroup} classes should also implement {@link
-android.view.ViewGroup#onRequestSendAccessibilityEvent(android.view.View,
-android.view.accessibility.AccessibilityEvent) onRequestSendAccessibilityEvent()}  </li>
-</ul>
-
-<p>Developers who want to maintain compatibility with Android versions prior to 4.0, while still
-providing support for new the accessibility APIs, can use the {@link
-android.view.View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)
-setAccessibilityDelegate()} method to provide an {@link android.view.View.AccessibilityDelegate}
-containing implementations of the new accessibility API methods while maintaining compatibility with
-prior releases.</p>
+<p>Android 4.0 improves accessibility for sight-impaired users with new explore-by-touch mode
+and extended APIs that allow you to provide more information about view content or
+develop advanced accessibility services.</p>
 
 
+<h4>Explore-by-touch mode</h4>
 
-<h4>Accessibility Service APIs</h4>
+<p>Users with vision loss can now explore the screen by touching and dragging a finger across the
+screen to hear voice descriptions of the content. Because the explore-by-touch mode works like a
+virtual cursor, it allows screen readers to identify the descriptive text the same way that screen
+readers can when the user navigates with a d-pad or trackball&mdash;by reading information provided
+by {@link android.R.attr#contentDescription android:contentDescription} and {@link
+android.view.View#setContentDescription setContentDescription()} upon a simulated "hover" event. So,
+consider this is a reminder that you should provide descriptive text for the views in your
+application, especially for {@link android.widget.ImageButton}, {@link android.widget.EditText},
+{@link android.widget.ImageView} and other widgets that might not naturally contain descriptive
+text.</p>
 
-<p>Accessibility events have been significantly improved to provide better information for
-accessibility services. In particular, events are generated based on view composition, providing
-better context information and allowing accessibility service developers to traverse view
-hierarchies to get additional view information and deal with special cases.</p>
 
-<p>To access additional content information and traverse view hierarchies, accessibility service
-application developers should use the following procedure.</p>
+<h4>Accessibility for views</h4>
+
+<p>To enhance the information available to accessibility services such as screen readers, you can
+implement new callback methods for accessibility events in your custom {@link
+android.view.View} components.</p>
+
+<p>It's important to first note that the behavior of the {@link
+android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} method has changed in Android
+4.0. As with previous version of Android, when the user enables accessibility services on the device
+and an input event such as a click or hover occurs, the respective view is notified with a call to
+{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}. Previously, the
+implementation of {@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} would
+initialize an {@link android.view.accessibility.AccessibilityEvent} and send it to {@link
+android.view.accessibility.AccessibilityManager}. The new behavior involves some additional callback
+methods that allow the view and its parents to add more contextual information to the event:
 <ol>
-<li>Upon receiving an {@link android.view.accessibility.AccessibilityEvent} from an application,
-call
-the {@link android.view.accessibility.AccessibilityEvent#getRecord(int)
-AccessibilityEvent.getRecord()} to retrieve new accessibility information about the state of the
-view.</li>
-<li>From the {@link android.view.accessibility.AccessibilityRecord}, call {@link 
-android.view.accessibility.AccessibilityRecord#getSource() getSource()} to retrieve a {@link
-android.view.accessibility.AccessibilityNodeInfo} object.</li>
-<li>With the {@link android.view.accessibility.AccessibilityNodeInfo}, call {@link
-android.view.accessibility.AccessibilityNodeInfo#getParent getParent()} or {@link
-android.view.accessibility.AccessibilityNodeInfo#getChild getChild()} to traverse the view
-hierarchy and get additional context information.</li>
+  <li>When invoked, the {@link
+android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} and {@link
+android.view.View#sendAccessibilityEventUnchecked sendAccessibilityEventUnchecked()} methods defer
+to {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}. 
+  <p>Custom implementations of {@link android.view.View} might want to implement {@link
+android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} to
+attach additional accessibility information to the {@link
+android.view.accessibility.AccessibilityEvent}, but should also call the super implementation to
+provide default information such as the standard content description, item index, and more.
+However, you should not add additional text content in this callback&mdash;that happens
+next.</p></li>
+  <li>Once initialized, if the event is one of several types that should be populated with text
+information, the view then receives a call to {@link
+android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}, which
+defers to the {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}
+callback.
+  <p>Custom implementations of {@link android.view.View} should usually implement {@link
+android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} to add additional
+text content to the {@link android.view.accessibility.AccessibilityEvent} if the {@link
+android.R.attr#contentDescription android:contentDescription} text is missing or
+insufficient. To add more text description to the
+{@link android.view.accessibility.AccessibilityEvent}, call {@link
+android.view.accessibility.AccessibilityEvent#getText()}.{@link java.util.List#add add()}.</p>
+</li>
+  <li>At this point, the {@link android.view.View} passes the event up the view hierarchy by calling
+{@link android.view.ViewGroup#requestSendAccessibilityEvent requestSendAccessibilityEvent()} on the
+parent view. Each parent view then has the chance to augment the accessibility information by
+adding an {@link android.view.accessibility.AccessibilityRecord}, until it
+ultimately reaches the root view, which sends the event to the {@link
+android.view.accessibility.AccessibilityManager} with {@link
+android.view.accessibility.AccessibilityManager#sendAccessibilityEvent
+sendAccessibilityEvent()}.</li>
 </ol>
 
-<p>In order to retrieve {@link android.view.accessibility.AccessibilityNodeInfo} information, your
-application must request permission to retrieve application window content through a manifest
-declaration that includes a new, separate xml configuration file, which supercedes {@link
-android.accessibilityservice.AccessibilityServiceInfo}. For more information, see {@link
+<p>In addition to the new methods above, which are useful when extending the {@link
+android.view.View} class, you can also intercept these event callbacks on any {@link
+android.view.View} by extending {@link
+android.view.View.AccessibilityDelegate AccessibilityDelegate} and setting it on the view with
+{@link android.view.View#setAccessibilityDelegate setAccessibilityDelegate()}.
+When you do, each accessibility method in the view defers the call to the corresponding method in
+the delegate. For example, when the view receives a call to {@link
+android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}, it passes it to the
+same method in the {@link android.view.View.AccessibilityDelegate}. Any methods not handled by
+the delegate are given right back to the view for default behavior. This allows you to override only
+the methods necessary for any given view without extending the {@link android.view.View} class.</p>
+
+
+<p>If you want to maintain compatibility with Android versions prior to 4.0, while also supporting
+the new the accessibility APIs, you can do so with the latest version of the <em>v4 support
+library</em> (in <a href="{@docRoot}sdk/compatibility-library.html">Compatibility Package, r4</a>)
+using a set of utility classes that provide the new accessibility APIs in a backward-compatible
+design.</p>
+
+
+
+<h4>Accessibility services</h4>
+
+<p>If you're developing an accessibility service, the information about various accessibility events
+has been significantly expanded to enable more advanced accessibility feedback for users. In
+particular, events are generated based on view composition, providing better context information and
+allowing accessibility services to traverse view hierarchies to get additional view information and
+deal with special cases.</p>
+
+<p>If you're developing an accessibility service (such as a screen reader), you can access
+additional content information and traverse view hierarchies with the following procedure:</p>
+<ol>
+<li>Upon receiving an {@link android.view.accessibility.AccessibilityEvent} from an application,
+call the {@link android.view.accessibility.AccessibilityEvent#getRecord(int)
+AccessibilityEvent.getRecord()} to retrieve a specific {@link
+android.view.accessibility.AccessibilityRecord} (there may be several records attached to the
+event).</li>
+
+<li>From either {@link android.view.accessibility.AccessibilityEvent} or an individual {@link
+android.view.accessibility.AccessibilityRecord}, you can call {@link 
+android.view.accessibility.AccessibilityRecord#getSource() getSource()} to retrieve a {@link
+android.view.accessibility.AccessibilityNodeInfo} object.
+  <p>An {@link android.view.accessibility.AccessibilityNodeInfo} represents a single node
+of the window content in a format that allows you to query accessibility information about that
+node. The {@link android.view.accessibility.AccessibilityNodeInfo} object returned from {@link
+android.view.accessibility.AccessibilityEvent} describes the event source, whereas the source from
+an {@link android.view.accessibility.AccessibilityRecord} describes the predecessor of the event
+source.</p></li>
+
+<li>With the {@link android.view.accessibility.AccessibilityNodeInfo}, you can query information
+about it, call {@link
+android.view.accessibility.AccessibilityNodeInfo#getParent getParent()} or {@link
+android.view.accessibility.AccessibilityNodeInfo#getChild getChild()} to traverse the view
+hierarchy, and even add child views to the node.</li>
+</ol>
+
+<p>In order for your application to publish itself to the system as an accessibility service, it
+must declare an XML configuration file that corresponds to {@link
+android.accessibilityservice.AccessibilityServiceInfo}. For more information about creating an
+accessibility service, see {@link
 android.accessibilityservice.AccessibilityService} and {@link
 android.accessibilityservice.AccessibilityService#SERVICE_META_DATA
-AccessibilityService.SERVICE_META_DATA}.</p>
+SERVICE_META_DATA} for information about the XML configuration.</p>
 
 
+<h4>Other accessibility APIs</h4>
 
+<p>If you're interested in the device's accessibility state, the {@link
+android.view.accessibility.AccessibilityManager} has some new APIs such as:</p>
+<ul>
+  <li>{@link android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener}
+is an interface that allows you to receive a callback whenever accessibility is enabled or
+disabled.</li>
+  <li>{@link android.view.accessibility.AccessibilityManager#getEnabledAccessibilityServiceList
+    getEnabledAccessibilityServiceList()} provides information about which accessibility services
+    are currently enabled.</li>
+  <li>{@link android.view.accessibility.AccessibilityManager#isTouchExplorationEnabled()} tells
+  you whether the explore-by-touch mode is enabled.</li>
+</ul>
 
 
 
@@ -916,13 +980,12 @@
 
 <p>Android 4.0 expands the capabilities for enterprise application with the following features.</p>
 
-<h4>VPN Services</h4>
+<h4>VPN services</h4>
 
 <p>The new {@link android.net.VpnService} allows applications to build their own VPN (Virtual
-Private
-Network), running as a {@link android.app.Service}. A VPN service creates an interface for a virtual
-network with its own address and routing rules and performs all reading and writing with a file
-descriptor.</p>
+Private Network), running as a {@link android.app.Service}. A VPN service creates an interface for a
+virtual network with its own address and routing rules and performs all reading and writing with a
+file descriptor.</p>
 
 <p>To create a VPN service, use {@link android.net.VpnService.Builder}, which allows you to specify
 the network address, DNS server, network route, and more. When complete, you can establish the
@@ -936,7 +999,7 @@
 users must manually enable it in the system settings.</p>
 
 
-<h4>Device Restrictions</h4>
+<h4>Device restrictions</h4>
 
 <p>Applications that manage the device restrictions can now disable the camera using {@link
 android.app.admin.DevicePolicyManager#setCameraDisabled setCameraDisabled()} and the {@link
@@ -944,54 +1007,46 @@
 &lt;disable-camera /&gt;} element in the policy configuration file).</p>
 
 
-<h4>Certificate Management</h4>
+<h4>Certificate management</h4>
 
 <p>The new {@link android.security.KeyChain} class provides APIs that allow you to import and access
-certificates and key stores in credential storage.  See the {@link android.security.KeyChain}
+certificates in the system key store. Certificates streamline the installation of both client
+certificates (to validate the identity of the user) and certificate authority certificates (to
+verify server identity). Applications such as web browsers or email clients can access the installed
+certificates to authenticate users to servers. See the {@link android.security.KeyChain}
 documentation for more information.</p>
 
 
 
 
-<h3 id="Voicemail">Voicemail</h3>
-
-<p>A new voicemail APIs allows applications to add voicemails to the system. Because the APIs
-currently
-do not allow third party apps to read all the voicemails from the system, the only third-party apps
-that should use the voicemail APIs are those that have voicemail to deliver to the user. For
-instance, it’s possible that a users have multiple voicemail sources, such as one provided by their
-phone’s service provider and others from VoIP or other alternative services. These kinds of apps can
-use the APIs to add voicemail to the system. The built-in Phone application can then present all
-voicemails to the user with a single list. Although the system’s Phone application is the only
-application that can read all the voicemails, each application that provides voicemails can read
-those that it has added to the system.</p>
-
-<p>The {@link android.provider.VoicemailContract} class defines the content provider for the
-voicemail
-APIs. The subclasses {@link android.provider.VoicemailContract.Voicemails} and {@link
-android.provider.VoicemailContract.Status} provide tables in which the voicemail providers can
-insert voicemail data for storage on the device. For an example of a voicemail provider app, see the
-<a href=”{@docRoot}resources/samples/VoicemailProviderDemo/index.html”>Voicemail Provider
-Demo</a>.</p>
 
 
 
+<h3 id="Sensors">Device Sensors</h3>
 
-<h3 id="SpellChecker">Spell Checker Services</h3>
+<p>Two new sensor types have been added in Android 4.0:</p>
 
-<p>The new spell checker framework allows apps to create spell checkers in a manner similar to the
-input method framework. To create a new spell checker, you must override the {@link
-android.service.textservice.SpellCheckerService.Session} class to provide spelling suggestions based
-on text provided by the interface callback methods, returning suggestions as a {@link
-android.view.textservice.SuggestionsInfo} object. </p>
+<ul>
+  <li>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE}: A temperature sensor that provides
+the ambient (room) temperature in degrees Celsius.</li>
+  <li>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}: A humidity sensor that provides the
+relative ambient (room) humidity as a percentage.</li>
+</ul>
 
-<p>Applications with a spell checker service must declare the {@link
-android.Manifest.permission#BIND_TEXT_SERVICE} permission as required by the service, such that
-other services must have this permission in order for them to bind with the spell checker service.
-The service must also declare an intent filter with <action
-android:name="android.service.textservice.SpellCheckerService" /> as the intent’s action and should
-include a {@code &lt;meta-data&gt;} element that declares configuration information for the spell
-checker. </p>
+<p>If a device has both {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and  {@link
+android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} sensors, you can use them to calculate the dew point
+and the absolute humidity.</p>
+
+<p>The previous temperature sensor, {@link android.hardware.Sensor#TYPE_TEMPERATURE}, has been
+deprecated. You should use the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor
+instead.</p>
+
+<p>Additionally, Android’s three synthetic sensors have been improved so they now have lower latency
+and smoother output. These sensors include the gravity sensor ({@link
+android.hardware.Sensor#TYPE_GRAVITY}), rotation vector sensor ({@link
+android.hardware.Sensor#TYPE_ROTATION_VECTOR}), and linear acceleration sensor ({@link
+android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}). The improved sensors rely on the gyroscope
+sensor to improve their output, so the sensors appear only on devices that have a gyroscope.</p>
 
 
 
@@ -999,22 +1054,20 @@
 
 <h3 id="TTS">Text-to-speech Engines</h3>
 
-<p>Android’s text-to-speech (TTS) APIs have been greatly extended to allow applications to more
-easily
-implement custom TTS engines, while applications that want to use a TTS engine have a couple new
-APIs for selecting the engine.</p>
+<p>Android’s text-to-speech (TTS) APIs have been significantly extended to allow applications to
+more easily implement custom TTS engines, while applications that want to use a TTS engine have a
+couple new APIs for selecting an engine.</p>
 
 
 <h4>Using text-to-speech engines</h4>
 
 <p>In previous versions of Android, you could use the {@link android.speech.tts.TextToSpeech} class
-to
-perform text-to-speech (TTS) operations using the TTS engine provided by the system or set a custom
-engine using {@link android.speech.tts.TextToSpeech#setEngineByPackageName
-setEngineByPackageName()}.
-In Android 4.0, the {@link android.speech.tts.TextToSpeech#setEngineByPackageName
-setEngineByPackageName()} method has been deprecated and you can now specify the engine to use with
-a new {@link android.speech.tts.TextToSpeech} that accepts the package name of a TTS engine.</p>
+to perform text-to-speech (TTS) operations using the TTS engine provided by the system or set a
+custom engine using {@link android.speech.tts.TextToSpeech#setEngineByPackageName
+setEngineByPackageName()}. In Android 4.0, the {@link
+android.speech.tts.TextToSpeech#setEngineByPackageName setEngineByPackageName()} method has been
+deprecated and you can now specify the engine to use with a new {@link
+android.speech.tts.TextToSpeech} constructor that accepts the package name of a TTS engine.</p>
 
 <p>You can also query the available TTS engines with {@link
 android.speech.tts.TextToSpeech#getEngines()}. This method returns a list of {@link
@@ -1024,30 +1077,29 @@
 
 <h4>Building text-to-speech engines</h4>
 
-<p>Previously, custom engines required that the engine be built using native code, based on a TTS
-engine header file. In Android 4.0, there is a framework API for building TTS engines. </p>
+<p>Previously, custom engines required that the engine be built using an undocumented native header
+file. In Android 4.0, there is a complete set of framework APIs for building TTS engines. </p>
 
 <p>The basic setup requires an implementation of {@link android.speech.tts.TextToSpeechService} that
 responds to the {@link android.speech.tts.TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} intent. The
 primary work for a TTS engine happens during the {@link
-android.speech.tts.TextToSpeechService#onSynthesizeText onSynthesizeText()} callback in the {@link
-android.speech.tts.TextToSpeechService}. The system delivers this method two objects:</p>
+android.speech.tts.TextToSpeechService#onSynthesizeText onSynthesizeText()} callback in a service
+that extends {@link android.speech.tts.TextToSpeechService}. The system delivers this method two
+objects:</p>
 <ul>
 <li>{@link android.speech.tts.SynthesisRequest}: This contains various data including the text to
 synthesize, the locale, the speech rate, and voice pitch.</li>
 <li>{@link android.speech.tts.SynthesisCallback}: This is the interface by which your TTS engine
-delivers the resulting speech data as streaming audio, by calling {@link
+delivers the resulting speech data as streaming audio. First the engine must call {@link
 android.speech.tts.SynthesisCallback#start start()} to indicate that the engine is ready to deliver
-the
-audio, then call {@link android.speech.tts.SynthesisCallback#audioAvailable audioAvailable()},
-passing it the audio
-data in a byte buffer. Once your engine has passed all audio through the buffer, call {@link
-android.speech.tts.SynthesisCallback#done()}.</li>
+the audio, then call {@link android.speech.tts.SynthesisCallback#audioAvailable audioAvailable()},
+passing it the audio data in a byte buffer. Once your engine has passed all audio through the
+buffer, call {@link android.speech.tts.SynthesisCallback#done()}.</li>
 </ul>
 
-<p>Now that the framework supports a true API for creating TTS engines, support for the previous
-technique using native code has been removed. Watch for a blog post about the compatibility layer
-that you can use to convert TTS engines built using the previous technique to the new framework.</p>
+<p>Now that the framework supports a true API for creating TTS engines, support for the native code
+implementation has been removed. Look for a blog post about a compatibility layer
+that you can use to convert your old TTS engines to the new framework.</p>
 
 <p>For an example TTS engine using the new APIs, see the <a
 href=”{@docRoot}resources/samples/TtsEngine/index.html”>Text To Speech Engine</a> sample app.</p>
@@ -1057,6 +1109,27 @@
 
 
 
+<h3 id="SpellChecker">Spell Checker Services</h3>
+
+<p>A new spell checker framework allows apps to create spell checkers in a manner similar to the
+input method framework. To create a new spell checker, you must implement a service that extends
+{@link android.service.textservice.SpellCheckerService} and extend the {@link
+android.service.textservice.SpellCheckerService.Session} class to provide spelling suggestions based
+on text provided by interface callback methods. In the {@link
+android.service.textservice.SpellCheckerService.Session} callback methods, you must return the
+spelling suggestions as {@link android.view.textservice.SuggestionsInfo} objects. </p>
+
+<p>Applications with a spell checker service must declare the {@link
+android.Manifest.permission#BIND_TEXT_SERVICE} permission as required by the service, such that
+other services must have this permission in order for them to bind with the spell checker service.
+The service must also declare an intent filter with {@code &lt;action
+android:name="android.service.textservice.SpellCheckerService" />} as the intent’s action and should
+include a {@code &lt;meta-data&gt;} element that declares configuration information for the spell
+checker. </p>
+
+
+
+
 
 
 
@@ -1066,34 +1139,36 @@
 
 <p>The {@link android.app.ActionBar} has been updated to support several new behaviors. Most
 importantly, the system gracefully manages the action bar’s size and configuration when running on
-smaller screens in order to provide an optimal user experience. For example, when the screen is
-narrow (such as when a handset is in portrait orientation), the action bar’s navigation tabs appear
-in a “stacked bar,” which appears directly below the main action bar. You can also opt-in to a
-“split action bar,” which will place all action items in a separate bar at the bottom of the screen
-when the screen is narrow.</p>
+smaller screens in order to provide an optimal user experience on all screen sizes. For example,
+when the screen is narrow (such as when a handset is in portrait orientation), the action bar’s
+navigation tabs appear in a “stacked bar,” which appears directly below the main action bar. You can
+also opt-in to a “split action bar,” which places all action items in a separate bar at the bottom
+of the screen when the screen is narrow.</p>
 
 
-<h4>Split Action Bar</h4>
+<h4>Split action bar</h4>
 
-<p>If your action bar includes several action items, not all of them will fit into the action bar
-when on a narrow screen, so the system will place them into the overflow menu. However, Android 4.0
+<p>If your action bar includes several action items, not all of them will fit into the action bar on
+a narrow screen, so the system will place more of them into the overflow menu. However, Android 4.0
 allows you to enable “split action bar” so that more action items can appear on the screen in a
 separate bar at the bottom of the screen. To enable split action bar, add {@link
 android.R.attr#uiOptions android:uiOptions} with {@code ”splitActionBarWhenNarrow”} to either your
-{@code &lt;application&gt;} tag or individual {@code &lt;activity&gt;} tags in your manifest file.
-When enabled, the system will enable the additional bar for action items when the screen is narrow
-and add all action items to the new bar (no action items will appear in the primary action bar).</p>
+<a href="guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a> tag or
+individual <a href="guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> tags
+in your manifest file. When enabled, the system will add an additional bar at the bottom of the
+screen for all action items when the screen is narrow (no action items will appear in the primary
+action bar).</p>
 
 <p>If you want to use the navigation tabs provided by the {@link android.app.ActionBar.Tab} APIs,
-but
-don’t want the stacked bar&mdash;you want only the tabs to appear, then enable the split action bar
-as described above and also call {@link android.app.ActionBar#setDisplayShowHomeEnabled
-setDisplayShowHomeEnabled(false)} to disable the application icon in the action bar. With nothing
-left in the main action bar, it disappears&mdash;all that’s left are the navigation tabs at the top
-and the action items at the bottom of the screen.</p>
+but don’t need the main action bar on top (you want only the tabs to appear at the top), then enable
+the split action bar as described above and also call {@link
+android.app.ActionBar#setDisplayShowHomeEnabled setDisplayShowHomeEnabled(false)} to disable the
+application icon in the action bar. With nothing left in the main action bar, it
+disappears&mdash;all that’s left are the navigation tabs at the top and the action items at the
+bottom of the screen.</p>
 
 
-<h4>Action Bar Styles</h4>
+<h4>Action bar styles</h4>
 
 <p>If you want to apply custom styling to the action bar, you can use new style properties {@link
 android.R.attr#backgroundStacked} and {@link android.R.attr#backgroundSplit} to apply a background
@@ -1103,31 +1178,38 @@
 setSplitBackgroundDrawable()}.</p>
 
 
-<h4>Action Provider</h4>
+<h4>Action provider</h4>
 
-<p>The new {@link android.view.ActionProvider} class facilitates user actions to which several
-different applications may respond. For example, a “share” action in your application might invoke
-several different apps that can handle the {@link android.content.Intent#ACTION_SEND} intent and the
-associated data. In this case, you can use the {@link android.widget.ShareActionProvider} (an
-extension of {@link android.view.ActionProvider}) in your action bar, instead of a traditional menu
-item that invokes the intent. The {@link android.widget.ShareActionProvider} populates a drop-down
-menu with all the available apps that can handle the intent.</p>
+<p>The new {@link android.view.ActionProvider} class allows you to create a specialized handler for
+action items. An action provider can define an action view, a default action behavior, and a submenu
+for each action item to which it is associated. When you want to create an action item that has
+dynamic behaviors (such as a variable action view, default action, or submenu), extending {@link
+android.view.ActionProvider} is a good solution in order to create a reusable component, rather than
+handling the various action item transformations in your fragment or activity.</p>
+
+<p>For example, the {@link android.widget.ShareActionProvider} is an extension of {@link
+android.view.ActionProvider} that facilitates a “share” action from the action bar. Instead of using
+traditional action item that invokes the {@link android.content.Intent#ACTION_SEND} intent, you can
+use this action provider to present an action view with a drop-down list of applications that handle
+the {@link android.content.Intent#ACTION_SEND} intent. When the user selects an application to use
+for the action, {@link android.widget.ShareActionProvider} remembers that selection and provides it
+in the action view for faster access to sharing with that app.</p>
 
 <p>To declare an action provider for an action item, include the {@code android:actionProviderClass}
-attribute in the {@code &lt;item&gt;} element for your activity’s options menu, with the class name
-of the action provider as the attribute value. For example:</p>
+attribute in the <a href="{@docRoot}guide/topics/resources/menu-resource.html#item-element">{@code
+&lt;item&gt;}</a> element for your activity’s options menu, with the class name of the action
+provider as the value. For example:</p>
 
 <pre>
 &lt;item android:id="@+id/menu_share"
       android:title="Share"
-      android:icon="@drawable/ic_share"
       android:showAsAction="ifRoom"
       android:actionProviderClass="android.widget.ShareActionProvider" /&gt;
 </pre>
 
 <p>In your activity’s {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}
-callback
-method, retrieve an instance of the action provider from the menu item and set the intent:</p>
+callback method, retrieve an instance of the action provider from the menu item and set the
+intent:</p>
 
 <pre>
 public boolean onCreateOptionsMenu(Menu menu) {
@@ -1146,17 +1228,18 @@
 class in ApiDemos.</p>
 
 
-<h4>Collapsible Action Views</h4>
+<h4>Collapsible action views</h4>
 
-<p>Menu items that appear as action items can now toggle between their action view state and
+<p>Action items that provide an action view can now toggle between their action view state and
 traditional action item state. Previously only the {@link android.widget.SearchView} supported
 collapsing when used as an action view, but now you can add an action view for any action item and
 switch between the expanded state (action view is visible) and collapsed state (action item is
 visible).</p>
 
 <p>To declare that an action item that contains an action view be collapsible, include the {@code
-“collapseActionView”} flag in the {@code android:showAsAction} attribute for the {@code
-&lt;item&gt;} element in the menu’s XML file.</p>
+“collapseActionView”} flag in the {@code android:showAsAction} attribute for the <a
+href="{@docRoot}guide/topics/resources/menu-resource.html#item-element">{@code
+&lt;item&gt;}</a> element in the menu’s XML file.</p>
 
 <p>To receive callbacks when an action view switches between expanded and collapsed, register an
 instance of {@link android.view.MenuItem.OnActionExpandListener} with the respective {@link
@@ -1173,20 +1256,20 @@
 collapsed.</p>
 
 
-<h4>Other APIs for Action Bar</h4>
+<h4>Other APIs for action bar</h4>
 <ul>
-<li>{@link android.app.ActionBar#setHomeButtonEnabled setHomeButtonEnabled()} allows you to disable
-the
-default behavior in which the application icon/logo behaves as a button (pass “false” to disable it
-as a button).</li>
+<li>{@link android.app.ActionBar#setHomeButtonEnabled setHomeButtonEnabled()} allows you to specify
+whether the icon/logo behaves as a button to navigate home or “up” (pass “true” to make it behave as
+a button).</li>
+
 <li>{@link android.app.ActionBar#setIcon setIcon()} and {@link android.app.ActionBar#setLogo
-setLogo()}
-to define the action bar icon or logo at runtime.</li>
+setLogo()} allow you to define the action bar icon or logo at runtime.</li>
+
 <li>{@link android.app.Fragment#setMenuVisibility Fragment.setMenuVisibility()} allows you to enable
-or
-disable the visibility of the options menu items declared by the fragment. This is useful if the
+or disable the visibility of the options menu items declared by the fragment. This is useful if the
 fragment has been added to the activity, but is not visible, so the menu items should be
 hidden.</li>
+
 <li>{@link android.app.FragmentManager#invalidateOptionsMenu
 FragmentManager.invalidateOptionsMenu()}
 allows you to invalidate the activity options menu during various states of the fragment lifecycle
@@ -1204,6 +1287,7 @@
 
 <p>Android 4.0 introduces a variety of new views and other UI components.</p>
 
+
 <h4>System UI</h4>
 
 <p>Since the early days of Android, the system has managed a UI component known as the <em>status
@@ -1214,8 +1298,8 @@
 Android 4.0, the system provides a new type of system UI called the <em>navigation bar</em>. The
 navigation bar shares some qualities with the system bar, because it provides navigation controls
 for devices that don’t have hardware counterparts for navigating the system, but the navigation
-controls is all that it provides (a device with the navigation bar, thus, also includes the status
-bar at the top of the screen).</p>
+controls is all that the navigation bar offers (a device with the navigation bar, thus, also
+includes the status bar at the top of the screen).</p>
 
 <p>To this day, you can hide the status bar on handsets using the {@link
 android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} flag. In Android 4.0, the APIs that control
@@ -1223,32 +1307,31 @@
 and navigation bar:</p>
 <ul>
 <li>The {@link android.view.View#SYSTEM_UI_FLAG_LOW_PROFILE} flag replaces View.STATUS_BAR_HIDDEN
-flag
-(now deprecated). When set, this flag enables “low profile” mode for the system bar or navigation
-bar. Navigation buttons dim and other elements in the system bar also hide.</li>
+flag. When set, this flag enables “low profile” mode for the system bar or
+navigation bar. Navigation buttons dim and other elements in the system bar also hide.</li>
+
 <li>The {@link android.view.View#SYSTEM_UI_FLAG_VISIBLE} flag replaces the {@code
-STATUS_BAR_VISIBLE}
-flag to request the system bar or navigation bar be visible.</li>
+STATUS_BAR_VISIBLE} flag to request the system bar or navigation bar be visible.</li>
+
 <li>The {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} is a new flag that requests that
-the
-navigation bar hide completely. Take note that this works only for the <em>navigation bar</em> used
-by some handsets (it does <strong>not</strong> hide the system bar on tablets). The navigation bar
-returns as soon as the system receives user input. As such, this mode is generally used for video
-playback or other cases in which user input is not required.</li>
+the navigation bar hide completely. Take note that this works only for the <em>navigation bar</em>
+used by some handsets (it does <strong>not</strong> hide the system bar on tablets). The navigation
+bar returns as soon as the system receives user input. As such, this mode is generally used for
+video playback or other cases in which the whole screen is needed but user input is not
+required.</li>
 </ul>
 
-<p>You can set each of these flags for the system bar by calling {@link
-android.view.View#setSystemUiVisibility setSystemUiVisibility()} on any view in your activity
-window. The window manager will combine (OR-together) all flags from all views in your window and
+<p>You can set each of these flags for the system bar and navigation bar by calling {@link
+android.view.View#setSystemUiVisibility setSystemUiVisibility()} on any view in your activity. The
+window manager will combine (OR-together) all flags from all views in your window and
 apply them to the system UI as long as your window has input focus. When your window loses input
 focus (the user navigates away from your app, or a dialog appears), your flags cease to have effect.
 Similarly, if you remove those views from the view hierarchy their flags no longer apply.</p>
 
 <p>To synchronize other events in your activity with visibility changes to the system UI (for
-example,
-hide the action bar or other UI controls when the system UI hides), you can register a {@link
-android.view.View.OnSystemUiVisibilityChangeListener} to get a callback when the visibility
-changes.</p>
+example, hide the action bar or other UI controls when the system UI hides), you should register a
+{@link android.view.View.OnSystemUiVisibilityChangeListener} to be notified when the visibility
+of the system bar or navigation bar changes.</p>
 
 <p>See the <a
 href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.html”>
@@ -1258,8 +1341,7 @@
 <h4>GridLayout</h4>
 
 <p>{@link android.widget.GridLayout} is a new view group that places child views in a rectangular
-grid.
-Unlike {@link android.widget.TableLayout}, {@link android.widget.GridLayout} relies on a flat
+grid. Unlike {@link android.widget.TableLayout}, {@link android.widget.GridLayout} relies on a flat
 hierarchy and does not make use of intermediate views such as table rows for providing structure.
 Instead, children specify which row(s) and column(s) they should occupy (cells can span multiple
 rows and/or columns), and by default are laid out sequentially across the grid’s rows and columns.
@@ -1277,11 +1359,10 @@
 <h4>TextureView</h4>
 
 <p>{@link android.view.TextureView} is a new view that allows you to display a content stream, such
-as
-a video or an OpenGL scene. Although similar to {@link android.view.SurfaceView}, {@link
+as a video or an OpenGL scene. Although similar to {@link android.view.SurfaceView}, {@link
 android.view.TextureView} is unique in that it behaves like a regular view, rather than creating a
 separate window, so you can treat it like any other {@link android.view.View} object. For example,
-you can apply transforms, animate it using {@link android.view.ViewPropertyAnimator}, or easily
+you can apply transforms, animate it using {@link android.view.ViewPropertyAnimator}, or
 adjust its opacity with {@link android.view.View#setAlpha setAlpha()}.</p>
 
 <p>Beware that {@link android.view.TextureView} works only within a hardware accelerated window.</p>
@@ -1289,16 +1370,14 @@
 <p>For more information, see the {@link android.view.TextureView} documentation.</p>
 
 
-<h4>Switch Widget</h4>
+<h4>Switch widget</h4>
 
 <p>The new {@link android.widget.Switch} widget is a two-state toggle that users can drag to one
-side
-or the other (or simply tap) to toggle an option between two states.</p>
+side or the other (or simply tap) to toggle an option between two states.</p>
 
-<p>You can declare a switch in your layout with the {@code &lt;Switch&gt;} element. You can use the
-{@code android:textOn} and {@code android:textOff} attributes to specify the text to appear on the
-switch when in the on and off setting. The {@code android:text} attribute also allows you to place a
-label alongside the switch.</p>
+<p>You can use the {@code android:textOn} and {@code android:textOff} attributes to specify the text
+to appear on the switch when in the on and off setting. The {@code android:text} attribute also
+allows you to place a label alongside the switch.</p>
 
 <p>For a sample using switches, see the <a
 href=”{@docRoot}resources/samples/ApiDemos/res/layout/switches.html”>switches.xml</a> layout file
@@ -1307,12 +1386,11 @@
 </a> activity.</p>
 
 
-<h4>Popup Menus</h4>
+<h4>Popup menus</h4>
 
 <p>Android 3.0 introduced {@link android.widget.PopupMenu} to create short contextual menus that pop
-up
-at an anchor point you specify (usually at the point of the item selected). Android 4.0 extends the
-{@link android.widget.PopupMenu} with a couple useful features:</p>
+up at an anchor point you specify (usually at the point of the item selected). Android 4.0 extends
+the {@link android.widget.PopupMenu} with a couple useful features:</p>
 <ul>
 <li>You can now easily inflate the contents of a popup menu from an XML <a
 href=”{@docRoot}guide/topics/resources/menu-resource.html”>menu resource</a> with {@link
@@ -1321,6 +1399,7 @@
 callback when the menu is dismissed.</li>
 </ul>
 
+
 <h4>Preferences</h4>
 
 <p>A new {@link android.preference.TwoStatePreference} abstract class serves as the basis for
@@ -1332,10 +1411,10 @@
 android.preference.SwitchPreference} for the Wi-Fi and Bluetooth settings.</p>
 
 
-<h4>Hover Events</h4>
+<h4>Hover events</h4>
 
 <p>The {@link android.view.View} class now supports “hover” events to enable richer interactions
-through the use of pointer devices (such as a mouse or other device that drives an on-screen
+through the use of pointer devices (such as a mouse or other devices that drive an on-screen
 cursor).</p>
 
 <p>To receive hover events on a view, implement the {@link android.view.View.OnHoverListener} and
@@ -1355,8 +1434,7 @@
 listener returns false, then the hover event will be dispatched to the parent view as usual.</p>
 
 <p>If your application uses buttons or other widgets that change their appearance based on the
-current
-state, you can now use the {@code android:state_hovered} attribute in a <a
+current state, you can now use the {@code android:state_hovered} attribute in a <a
 href=”{@docRoot}guide/topics/resources/drawable-resource.html#StateList”>state list drawable</a> to
 provide a different background drawable when a cursor hovers over the view.</p>
 
@@ -1365,11 +1443,10 @@
 ApiDemos.</p>
 
 
-<h4>Stylus and Mouse Button Input Events</h4>
+<h4>Stylus and mouse button events</h4>
 
 <p>Android now provides APIs for receiving input from a stylus input device such as a digitizer
-tablet
-peripheral or a stylus-enabled touch screen.</p>
+tablet peripheral or a stylus-enabled touch screen.</p>
 
 <p>Stylus input operates in a similar manner to touch or mouse input.  When the stylus is in contact
 with the digitizer, applications receive touch events just like they would when a finger is used to
@@ -1388,18 +1465,16 @@
 <p>Your application can also query which mouse or stylus buttons are pressed by querying the “button
 state” of a {@link android.view.MotionEvent} using {@link android.view.MotionEvent#getButtonState
 getButtonState()}.  The currently defined button states are: {@link
-android.view.MotionEvent#BUTTON_PRIMARY}, {@link
-android.view.MotionEvent#BUTTON_SECONDARY}, {@link
-android.view.MotionEvent#BUTTON_TERTIARY}, {@link android.view.MotionEvent#BUTTON_BACK},
-and {@link android.view.MotionEvent#BUTTON_FORWARD}.
-For convenience, the back and forward mouse buttons are automatically mapped to the {@link
-android.view.KeyEvent#KEYCODE_BACK} and {@link android.view.KeyEvent#KEYCODE_FORWARD} keys.  Your
-application can handle these keys to support mouse button based back and forward navigation.</p>
+android.view.MotionEvent#BUTTON_PRIMARY}, {@link android.view.MotionEvent#BUTTON_SECONDARY}, {@link
+android.view.MotionEvent#BUTTON_TERTIARY}, {@link android.view.MotionEvent#BUTTON_BACK}, and {@link
+android.view.MotionEvent#BUTTON_FORWARD}. For convenience, the back and forward mouse buttons are
+automatically mapped to the {@link android.view.KeyEvent#KEYCODE_BACK} and {@link
+android.view.KeyEvent#KEYCODE_FORWARD} keys.  Your application can handle these keys to support
+mouse button based back and forward navigation.</p>
 
 <p>In addition to precisely measuring the position and pressure of a contact, some stylus input
-devices
-also report the distance between the stylus tip and the digitizer, the stylus tilt angle, and the
-stylus orientation angle.  Your application can query this information using {@link
+devices also report the distance between the stylus tip and the digitizer, the stylus tilt angle,
+and the stylus orientation angle.  Your application can query this information using {@link
 android.view.MotionEvent#getAxisValue getAxisValue()} with the axis codes {@link
 android.view.MotionEvent#AXIS_DISTANCE}, {@link android.view.MotionEvent#AXIS_TILT}, and {@link
 android.view.MotionEvent#AXIS_ORIENTATION}.</p>
@@ -1474,29 +1549,31 @@
 element. You can alternatively disable hardware acceleration for individual views by calling {@link
 android.view.View#setLayerType setLayerType(LAYER_TYPE_SOFTWARE)}.</p>
 
+<p>For more information about hardware acceleration, including a list of unsupported drawing
+operations, see the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html">Hardware
+Acceleration</a> document.</p>
+
+
 
 <h3 id="Jni">JNI Changes</h3>
 
-<p>In previous versions of Android, JNI local references weren’t indirect handles; we used direct
-pointers. This didn’t seem like a problem as long as we didn’t have a garbage collector that moves
-objects, but it was because it meant that it was possible to write buggy code that still seemed to
-work. In Android 4.0, we’ve moved to using indirect references so we can detect these bugs before we
-need third-party native code to be correct.</p>
+<p>In previous versions of Android, JNI local references weren’t indirect handles; Android used
+direct pointers. This wasn't a problem as long as the garbage collector didn't move objects, but it
+seemed to work because it made it possible to write buggy code. In Android 4.0, the system now uses
+indirect references in order to detect these bugs.</p>
 
-<p>The ins and outs of JNI local references are described in “Local and Global References” in
-<a href="{@docRoot}guide/practices/design/jni.html">JNI Tips</a>. In Android 4.0, <a
-href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">CheckJNI</a>
-has been
-enhanced to detect these errors. Watch the <a href=”http://android-developers.blogspot.com/”>Android
-Developers Blog</a> for an upcoming post about common errors with JNI references and how you can fix
-them.</p>
+<p>The ins and outs of JNI local references are described in “Local and Global References” in <a
+href="{@docRoot}guide/practices/design/jni.html">JNI Tips</a>. In Android 4.0, <a
+href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">
+CheckJNI</a> has been enhanced to detect these errors. Watch the <a
+href=”http://android-developers.blogspot.com/”>Android Developers Blog</a> for an upcoming post
+about common errors with JNI references and how you can fix them.</p>
 
 <p>This change in the JNI implementation only affects apps that target Android 4.0 by setting either
-the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
-<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to
-{@code “14”} or higher. If you’ve set these attributes to any lower
-value, then JNI local references will behave the same as in previous versions.</p>
+the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+targetSdkVersion}</a> or <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> to {@code “14”} or higher. If you’ve set these attributes to any lower value,
+then JNI local references behave the same as in previous versions.</p>
 
 
 
@@ -1564,8 +1641,115 @@
 
 
 
+<h2 id="Honeycomb">Previous APIs</h2>
 
+<p>In addition to everything above, Android 4.0 naturally supports all APIs from previous releases.
+Because the Android 3.x (Honeycomb) platform is available only for large-screen devices, if you've
+been developing primarily for handsets, then you might not be aware of all the APIs added to Android
+in these recent releases.</p>
 
+<p>Here's a look at some of the most notable APIs you might have missed that are now available
+on handsets as well:</p>
+
+<dl>
+  <dt><a href="android-3.0.html">Android 3.0</a></dt>
+  <dd>
+    <ul>
+      <li>{@link android.app.Fragment}: A framework component that allows you to separate distinct
+elements of an activity into self-contained modules that define their own UI and lifecycle. See the
+<a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</li>
+      <li>{@link android.app.ActionBar}: A replacement for the traditional title bar at the top of
+the activity window. It includes the application logo in the left corner and provides a new
+interface for menu items. See the
+<a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</li>
+      <li>{@link android.content.Loader}: A framework component that facilitates asynchronour
+loading of data in combination with UI components to dynamically load data without blocking the
+main thread. See the
+<a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</li>
+      <li>System clipboard: Applications can copy and paste data (beyond mere text) to and from
+the system-wide clipboard. Clipped data can be plain text, a URI, or an intent. See the
+<a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a> developer guide.</li>
+      <li>Drag and drop: A set of APIs built into the view framework that facilitates drag and drop
+operations. See the
+<a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</li>
+      <li>An all new flexible animation framework allows you to animate arbitrary properties of any
+object (View, Drawable, Fragment, Object, or anything else) and define animation aspects such
+as duration, interpolation, repeat and more. The new framework makes Animations in Android
+simpler than ever. See the
+<a href="{@docRoot}guide/topics/graphics/property-animation.html">Property Animation</a> developer
+guide.</li>
+      <li>RenderScript graphics and compute engine: RenderScript offers a high performance 3D
+graphics rendering and compute API at the native level, which you write in the C (C99 standard),
+providing the type of performance you expect from a native environment while remaining portable
+across various CPUs and GPUs. See the
+<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer
+guide.</li>
+      <li>Hardware accelerated 2D graphics: You can now enable the OpenGL renderer for your
+application by setting {android:hardwareAccelerated="true"} in your manifest element's <a
+href="{@docRoot}guide/topics/manifest/application-element.html"><code>&lt;application&gt;</code></a>
+element or for individual <a
+href="{@docRoot}guide/topics/manifest/activity-element.html"><code>&lt;activity&gt;</code></a>
+elements. This results
+in smoother animations, smoother scrolling, and overall better performance and response to user
+interaction.
+      <p class="note"><strong>Note:</strong> If you set your application's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> to
+{@code "14"} or higher, hardware acceleration is enabled by default.</p></li>
+      <li>And much, much more. See the <a href="android-3.0.html">Android 3.0 Platform</a>
+notes for more information.</li>
+    </ul>
+  </dd>
+  
+  <dt><a href="android-3.1.html">Android 3.1</a></dt>
+  <dd>
+    <ul>
+      <li>USB APIs: Powerful new APIs for integrating connected peripherals with
+Android applications. The APIs are based on a USB stack and services that are
+built into the platform, including support for both USB host and device interactions. See the <a
+href="{@docRoot}guide/topics/usb/index.html">USB Host and Accessory</a> developer guide.</li>
+      <li>MTP/PTP APIs: Applications can interact directly with connected cameras and other PTP
+devices to receive notifications when devices are attached and removed, manage files and storage on
+those devices, and transfer files and metadata to and from them. The MTP API implements the PTP
+(Picture Transfer Protocol) subset of the MTP (Media Transfer Protocol) specification. See the
+{@link android.mtp} documentation.</li>
+      <li>RTP APIs: Android exposes an API to its built-in RTP (Real-time Transport Protocol) stack,
+which applications can use to manage on-demand or interactive data streaming. In particular, apps
+that provide VOIP, push-to-talk, conferencing, and audio streaming can use the API to initiate
+sessions and transmit or receive data streams over any available network. See the {@link
+android.net.rtp} documentation.</li>
+      <li>Support for joysticks and other generic motion inputs.</li>
+      <li>See the <a href="android-3.1.html">Android 3.1 Platform</a>
+notes for many more new APIs.</li>
+    </ul>
+  </dd>
+  
+  <dt><a href="android-3.2.html">Android 3.2</a></dt>
+  <dd>
+    <ul>
+      <li>New screens support APIs that give you more control over how your applications are
+displayed across different screen sizes. The API extends the existing screen support model with the
+ability to precisely target specific screen size ranges by dimensions, measured in
+density-independent pixel units (such as 600dp or 720dp wide), rather than by their generalized
+screen sizes (such as large or xlarge). For example, this is important in order to help you
+distinguish between a 5" device and a 7" device, which would both traditionally be bucketed as
+"large" screens. See the blog post, <a
+href="http://android-developers.blogspot.com/2011/07/new-tools-for-managing-screen-sizes.html">
+New Tools for Managing Screen Sizes</a>.</li>
+      <li>New constants for <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature&gt;}</a> to
+declare landscape or portrait screen orientation requirements.</li>
+      <li>The device "screen size" configuration now changes during a screen orientation
+change. If your app targets API level 13 or higher, you must handle the {@code "screenSize"}
+configuration change if you also want to handle the {@code "orientation"} configuration change. See
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> for more information.</li>
+      <li>See the <a href="android-3.2.html">Android 3.2 Platform</a>
+notes for other new APIs.</li>
+    </ul>
+  </dd>
+
+</dl>
 
 
 
@@ -1574,32 +1758,28 @@
 
 <h2 id="api-diff">API Differences Report</h2>
 
-<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API
-Level
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API Level
 {@sdkPlatformApiLevel}), see the <a
-href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API
-Differences Report</a>.</p>
-
-
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API Differences Report</a>.</p>
 
 
 
 <h2 id="api-level">API Level</h2>
 
-<p>The Android {@sdkPlatformVersion} platform delivers an updated version of the framework API. The
-Android {@sdkPlatformVersion} API is assigned an integer identifier &mdash;
-<strong>{@sdkPlatformApiLevel}</strong> &mdash; that is stored in the system itself. This
-identifier, called the "API Level", allows the system to correctly determine whether an application
-is compatible with the system, prior to installing the application. </p>
+<p>The Android {@sdkPlatformVersion} API is assigned an integer
+identifier&mdash;<strong>{@sdkPlatformApiLevel}</strong>&mdash;that is stored in the system itself.
+This identifier, called the "API level", allows the system to correctly determine whether an
+application is compatible with the system, prior to installing the application. </p>
 
 <p>To use APIs introduced in Android {@sdkPlatformVersion} in your application, you need compile the
-application against the Android library that is provided in the Android {@sdkPlatformVersion} SDK
-platform. Depending on your needs, you might also need to add an
+application against an Android platform that supports API level {@sdkPlatformApiLevel} or
+higher. Depending on your needs, you might also need to add an
 <code>android:minSdkVersion="{@sdkPlatformApiLevel}"</code> attribute to the
-<code>&lt;uses-sdk&gt;</code> element in the application's manifest.</p>
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a>
+element.</p>
 
-<p>For more information about how to use API Level, see the <a
-href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
+<p>For more information, see the <a href="{@docRoot}guide/appendix/api-levels.html">API Levels</a>
+document. </p>
 
 
 <h2 id="apps">Built-in Applications</h2>
@@ -1614,6 +1794,7 @@
 <li>API Demos</li>
 <li>Browser</li>
 <li>Calculator</li>
+<li>Calendar</li>
 <li>Camera</li>
 <li>Clock</li>
 <li>Custom Locale</li>
@@ -1632,7 +1813,7 @@
 <li>Phone</li>
 <li>Search</li>
 <li>Settings</li>
-<li>Spare Parts</li>
+<li>Speech Recorder</li>
 <li>Speech Recorder</li>
 <li>Widget Preview</li>
 </ul>
@@ -1643,13 +1824,10 @@
 
 <h2 id="locs" style="margin-top:.75em;">Locales</h2>
 
-<p>The system image included in the downloadable SDK platform provides a variety
-of
-built-in locales. In some cases, region-specific strings are available for the
-locales. In other cases, a default version of the language is used. The
-languages that are available in the Android 3.0 system
-image are listed below (with <em>language</em>_<em>country/region</em> locale
-descriptor).</p>
+<p>The system image included in the downloadable SDK platform provides a variety of built-in
+locales. In some cases, region-specific strings are available for the locales. In other cases, a
+default version of the language is used. The languages that are available in the Android 3.0 system
+image are listed below (with <em>language</em>_<em>country/region</em> locale descriptor).</p>
 
 <table style="border:0;padding-bottom:0;margin-bottom:0;">
 <tr>
@@ -1726,15 +1904,45 @@
 
 <h2 id="skins">Emulator Skins</h2>
 
-<p>The downloadable platform includes the following emulator skin:</p>
+<p>The downloadable platform includes the following emulator skins:</p>
 
 <ul>
   <li>
-    WVGA800 (1280x800, extra high density, normal screen)
+    QVGA (240x320, low density, small screen)
+  </li>
+  <li>
+    WQVGA400 (240x400, low density, normal screen)
+  </li>
+  <li>
+    WQVGA432 (240x432, low density, normal screen)
+  </li>
+  <li>
+    HVGA (320x480, medium density, normal screen)
+  </li>
+  <li>
+    WVGA800 (480x800, high density, normal screen)
+  </li>
+  <li>
+    WVGA854 (480x854 high density, normal screen)
+  </li>
+  <li>
+    WXGA720 (1280x720, extra-high density, normal screen) <span class="new">new</span>
+  </li>
+  <li>
+    WSVGA (1024x600, medium density, large screen) <span class="new">new</span>
+  </li>
+  <li>
+    WXGA (1280x800, medium density, xlarge screen)
   </li>
 </ul>
 
-<p>For more information about how to develop an application that displays
-and functions properly on all Android-powered devices, see <a
-href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a>.</p>
+<p>To test your application on an emulator that represents the latest Android device, you can create
+an AVD with the new WXGA720 skin (it's an xhdpi, normal screen device). Note that the emulator
+currently doesn't support the new on-screen navigation bar for devices without hardware navigation
+buttons, so when using this skin, you must use keyboard keys <em>Home</em> for the Home button,
+<em>ESC</em> for the Back button, and <em>F2</em> or <em>Page-up</em> for the Menu button.</p>
+
+<p>However, due to performance issues in the emulator when running high-resolution screens such as
+the one for the WXGA720 skin, we recommend that you primarily use the traditional WVGA800 skin
+(hdpi, normal screen) to test your application.</p>
+
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 333efa2..0d14f79 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
 page.title=ADT Plugin for Eclipse
 adt.zip.version=14.0.0
 adt.zip.download=ADT-14.0.0.zip
-adt.zip.bytes=6745584
-adt.zip.checksum=a645330d90fd9dae6187662bb1c3c644
+adt.zip.bytes=6745047
+adt.zip.checksum=014312e1553e3b8da55cb6a24e33e432
 
 @jd:body
 
@@ -66,6 +66,9 @@
 <p>The sections below provide notes about successive releases of
 the ADT Plugin, as denoted by revision number. </p>
 
+<p>For a summary of all known issues in ADT, see <a
+href="http://tools.android.com/release/knownissues">http://tools.android.com/release/knownissues</a>.</p>
+
 <script type="text/javascript">
 function toggleDiv(link) {
   var toggleable = $(link).parent();
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 065f41b..67be5c9 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,20 +2,20 @@
 sdk.redirect=0
 
 sdk.win_installer=installer_r14-windows.exe
-sdk.win_installer_bytes=33860145
-sdk.win_installer_checksum=7a563491bf4671d09b9da0dcde85f212
+sdk.win_installer_bytes=33860326
+sdk.win_installer_checksum=6d4f76385daaee766ad901699cdae6cc
 
 sdk.win_download=android-sdk_r14-windows.zip
-sdk.win_bytes=33852972
-sdk.win_checksum=d1381a0cc8e6f9358174aa6d051ba379
+sdk.win_bytes=33853090
+sdk.win_checksum=0c39628e296d6176ed928cc64498ba04
 
 sdk.mac_download=android-sdk_r14-macosx.zip
-sdk.mac_bytes=30426052
-sdk.mac_checksum=df0a5c5b5327ffcaf256ce735998e12a
+sdk.mac_bytes=30426431
+sdk.mac_checksum=189ce3e26dfb46298a7def21d3bdf271
 
 sdk.linux_download=android-sdk_r14-linux.tgz
-sdk.linux_bytes=26083315
-sdk.linux_checksum=2049d5c1a164fcae47a5e93c52200752
+sdk.linux_bytes=26082867
+sdk.linux_checksum=500483f8acd0d3cae94c68c3dcefbb98
 
 @jd:body
 
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 2d044ed..f5b61ee 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -23,6 +23,9 @@
 Tools you are using, refer to the "Installed Packages" listing in the Android SDK
 and AVD Manager. </p>
 
+<p>For a summary of all known issues in SDK Tools, see <a
+href="http://tools.android.com/release/knownissues">http://tools.android.com/release/knownissues</a>.</p>
+
 <script type="text/javascript">
 function toggleDiv(link) {
   var toggleable = $(link).parent();
@@ -66,7 +69,12 @@
   <a href="#" onclick="return toggleDiv(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
     width="9px" />SDK Tools, Revision 14</a> <em>(October 2011)</em>
+
   <div class="toggleme">
+    <p class="note"><strong>Important:</strong> To download the new Android
+    4.0 system components from the Android SDK Manager, you must first update the
+    SDK tools to revision 14 and restart the Android SDK Manager. If you do not,
+    the Android 4.0 system components will not be available for download.</p>
   <dl>
 <dt>Dependencies:</dt>
 <dd>
@@ -81,6 +89,9 @@
 <dt>General notes:</dt>
 <dd>
   <ul>
+    <li>Added webcam support to Android 4.0 or later platforms to emulate rear-facing cameras when one webcam is present,
+    and to emulate both rear-facing and front-facing cameras when two webcams are present. Webcam suport is for Windows and Linux only.
+    Mac support will come in a later release.</li>
      <li>Changed <code>default.properties</code> to <code>project.properties</code> and
     <code>build.properties</code> to <code>ant.properties</code>. Any existing
     projects that you build with Ant must be updated with the <code>android update project</code>
@@ -90,7 +101,6 @@
 commands, see the
 <a href="{@docRoot}guide/developing/building/building-cmdline.html#AntReference">Ant Command
 Reference</a>.</li>
-
     <li>Changed how library projects are built.</a></li>
     <li>Improved incremental builds, so that resource compilation runs less frequently. Builds no
     longer run when you edit strings or layouts (unless you add a new <code>id</code>) and no longer
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index cd2c0a3..ef4cf5c 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -283,7 +283,8 @@
     // outside the current field of view, even when using zoom.
     //
     // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
-    // FOCUS_MODE_MACRO, or FOCUS_MODE_CONTINOUS_VIDEO.
+    // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
+    // FOCUS_MODE_CONTINUOUS_PICTURE.
     // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
     static const char KEY_FOCUS_AREAS[];
     // Focal length in millimeter.
@@ -629,19 +630,29 @@
     // recording because the focus changes smoothly . Applications still can
     // call CameraHardwareInterface.takePicture in this mode but the subject may
     // not be in focus. Auto focus starts when the parameter is set.
-    // Applications should not call CameraHardwareInterface.autoFocus in this
-    // mode. To stop continuous focus, applications should change the focus mode
-    // to other modes.
+    //
+    // Applications can call CameraHardwareInterface.autoFocus in this mode. The
+    // focus callback will immediately return with a boolean that indicates
+    // whether the focus is sharp or not. The focus position is locked after
+    // autoFocus call. If applications want to resume the continuous focus,
+    // cancelAutoFocus must be called. Restarting the preview will not resume
+    // the continuous autofocus. To stop continuous focus, applications should
+    // change the focus mode to other modes.
     static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
     // Continuous auto focus mode intended for taking pictures. The camera
     // continuously tries to focus. The speed of focus change is more aggressive
     // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
-    // set. If applications call autoFocus in this mode, the focus callback will
-    // immediately return with a boolean that indicates the focus is sharp or
-    // not. The apps can then decide if they want to take a picture immediately
-    // or to change the focus mode to auto, and run a full autofocus cycle. To
-    // stop continuous focus, applications should change the focus mode to other
-    // modes.
+    // set.
+    //
+    // If applications call CameraHardwareInterface.autoFocus in this mode, the
+    // focus callback will immediately return with a boolean that indicates
+    // whether the focus is sharp or not. The apps can then decide if they want
+    // to take a picture immediately or to change the focus mode to auto, and
+    // run a full autofocus cycle. The focus position is locked after autoFocus
+    // call. If applications want to resume the continuous focus,
+    // cancelAutoFocus must be called. Restarting the preview will not resume
+    // the continuous autofocus. To stop continuous focus, applications should
+    // change the focus mode to other modes.
     static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
 
 private:
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 53d4970..2d51208 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -319,8 +319,12 @@
 
 void Context::printWatchdogInfo(void *ctx) {
     Context *rsc = (Context *)ctx;
-    LOGE("RS watchdog timeout: %i  %s  line %i %s", rsc->watchdog.inRoot,
-         rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
+    if (rsc->watchdog.command && rsc->watchdog.file) {
+        LOGE("RS watchdog timeout: %i  %s  line %i %s", rsc->watchdog.inRoot,
+             rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file);
+    } else {
+        LOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot);
+    }
 }
 
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 4f4f929..0c5e673 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -85,8 +85,7 @@
     private static final String TAG = "AudioService";
 
     /** Debug remote control client/display feature */
-    // TODO set to false before release
-    protected static final boolean DEBUG_RC = true;
+    protected static final boolean DEBUG_RC = false;
 
     /** How long to delay before persisting a change in volume/ringer mode. */
     private static final int PERSIST_DELAY = 3000;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index a9b539b..dc6c011 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -947,7 +947,12 @@
 
     if (mSendObjectFileSize - initialData > 0) {
         mfr.offset = initialData;
-        mfr.length = mSendObjectFileSize - initialData;
+        if (mSendObjectFileSize == 0xFFFFFFFF) {
+            // tell driver to read until it receives a short packet
+            mfr.length = 0xFFFFFFFF;
+        } else {
+            mfr.length = mSendObjectFileSize - initialData;
+        }
 
         LOGV("receiving %s\n", (const char *)mSendObjectFilePath);
         // transfer the file
diff --git a/packages/BackupRestoreConfirmation/res/values/strings.xml b/packages/BackupRestoreConfirmation/res/values/strings.xml
index e91c6e2..5c90fd0 100644
--- a/packages/BackupRestoreConfirmation/res/values/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values/strings.xml
@@ -35,8 +35,12 @@
 
     <!-- Text for message to user that they must enter their predefined backup password in order to perform this operation. -->
     <string name="current_password_text">Please enter your current backup password below:</string>
+    <!-- Text for message to user that they must enter their device encryption password in order to perform this restore operation. -->
+    <string name="device_encryption_restore_text">Please enter your device encryption password below.</string>
+    <!-- Text for message to user that they must enter their device encryption password in order to perform this backup operation. -->
+    <string name="device_encryption_backup_text">Please enter your device encryption password below. This will also be used to encrypt the backup archive.</string>
 
-    <!-- Text for message to user that they can must enter an encryption password to use for the full backup operation. -->
+    <!-- Text for message to user that they must enter an encryption password to use for the full backup operation. -->
     <string name="backup_enc_password_text">Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:</string>
     <!-- Text for message to user that they may optionally supply an encryption password to use for a full backup operation. -->
     <string name="backup_enc_password_optional">If you wish to encrypt the full backup data, enter a password below:</string>
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index fbdf3cc..7f1d059 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -27,6 +27,8 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.storage.IMountService;
+import android.util.Log;
 import android.util.Slog;
 import android.view.View;
 import android.widget.Button;
@@ -60,8 +62,10 @@
 
     Handler mHandler;
     IBackupManager mBackupManager;
+    IMountService mMountService;
     FullObserver mObserver;
     int mToken;
+    boolean mIsEncrypted;
     boolean mDidAcknowledge;
 
     TextView mStatusView;
@@ -152,6 +156,7 @@
         }
 
         mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
+        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
 
         mHandler = new ObserverHandler(getApplicationContext());
         final Object oldObserver = getLastNonConfigurationInstance();
@@ -174,8 +179,23 @@
         mEncPassword = (TextView) findViewById(R.id.enc_password);
         TextView curPwDesc = (TextView) findViewById(R.id.password_desc);
 
-        // We vary the password prompt depending on whether one is predefined
-        if (!haveBackupPassword()) {
+        // We vary the password prompt depending on whether one is predefined, and whether
+        // the device is encrypted.
+        mIsEncrypted = deviceIsEncrypted();
+        if (mIsEncrypted) {
+            Log.d(TAG, "Device is encrypted: requiring encryption pw");
+            TextView pwPrompt = (TextView) findViewById(R.id.password_desc);
+            // this password is mandatory; we hide the other options during backup
+            if (layoutId == R.layout.confirm_backup) {
+                pwPrompt.setText(R.string.device_encryption_backup_text);
+                TextView tv = (TextView) findViewById(R.id.enc_password);
+                tv.setVisibility(View.GONE);
+                tv = (TextView) findViewById(R.id.enc_password_desc);
+                tv.setVisibility(View.GONE);
+            } else {
+                pwPrompt.setText(R.string.device_encryption_restore_text);
+            }
+        } else if (!haveBackupPassword()) {
             curPwDesc.setVisibility(View.GONE);
             mCurPassword.setVisibility(View.GONE);
             if (layoutId == R.layout.confirm_backup) {
@@ -226,10 +246,12 @@
             mDidAcknowledge = true;
 
             try {
+                CharSequence encPassword = (mIsEncrypted)
+                        ? mCurPassword.getText() : mEncPassword.getText();
                 mBackupManager.acknowledgeFullBackupOrRestore(mToken,
                         allow,
                         String.valueOf(mCurPassword.getText()),
-                        String.valueOf(mEncPassword.getText()),
+                        String.valueOf(encPassword),
                         mObserver);
             } catch (RemoteException e) {
                 // TODO: bail gracefully if we can't contact the backup manager
@@ -237,6 +259,16 @@
         }
     }
 
+    boolean deviceIsEncrypted() {
+        try {
+            return (mMountService.getEncryptionState() != IMountService.ENCRYPTION_STATE_NONE);
+        } catch (Exception e) {
+            // If we can't talk to the mount service we have a serious problem; fail
+            // "secure" i.e. assuming that the device is encrypted.
+            return true;
+        }
+    }
+
     boolean haveBackupPassword() {
         try {
             return mBackupManager.hasBackupPassword();
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 3adcbec..4a1d37e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
index d7a591c..9378fac 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
index 277dcb8..6e84546 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
index edc1760..c56905e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
index fbc6b99..11ffbde 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
index fb938e8..2bb923e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
index 2d35517..783ad175 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
index fe68c3c..e499f9d 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 49411bd..39e3df0 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
index 77924f0..b4920c3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
index 000e98b..31c0936 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
index 62b940a..7e9b752 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
index 5beb543..3209234d 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
index f70d315..95c56ed 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
index be9953f..11b9a93 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
index de20bdd..0f85ca0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
index 8a3d90c..3d67766 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
index 45dda51c..b74e070 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
index 18e019c..24485e1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
index cb8ed3a..390d500 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
index ab4ad05..78998f9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
index 956b6c1..c539615 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
index 9d95f17..5c38d45 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
index e68d57d..6a79695 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
index 4ac361d9..99dbe1b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
index 5e7ecdc..6a73a89 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
index 462fad4..7042f2b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
index d284c02..3da781e 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
index 4a5e701..cf63e24 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
index 9a08949..8f68e1f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
index 314f422..894c63b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
index 4e0a48a..1ec5b49 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
index 4eeae1d..9ca3ca8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
index 1a6f1ef..74241e0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index d853993..faeee29 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
index 2e6e3ac..f7e7102 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
index 2864ec3..cc9c49f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
index 0bb0c72..5a313c5 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
index f23dd60..373a4a4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
index b1c3168..d299daf 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
index 5e41470..dcfdb7b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
index 639842b..fb8125a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notification_row_bg.xml b/packages/SystemUI/res/drawable/notification_row_bg.xml
index dc626d1..1bb2172 100644
--- a/packages/SystemUI/res/drawable/notification_row_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_row_bg.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
         android:exitFadeDuration="@android:integer/config_mediumAnimTime">
 
-    <item android:state_pressed="true"  android:drawable="@android:color/holo_blue_light" />
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_item_background_color_pressed" />
     <item android:state_pressed="false" android:drawable="@drawable/notification_item_background_color" />
 </selector>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index a63893e..af2c93c 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -77,7 +77,6 @@
             android:layout_height="match_parent"
             android:singleLine="true"
             android:paddingRight="6dip"
-            android:textSize="16sp"
             android:gravity="center_vertical|left"
             />
     </LinearLayout>
@@ -89,17 +88,19 @@
         android:animationCache="false"
         android:orientation="horizontal" >
         <ImageSwitcher android:id="@+id/tickerIcon"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginRight="8dip"
+            android:layout_width="@dimen/status_bar_icon_size"
+            android:layout_height="@dimen/status_bar_icon_size"
+            android:layout_marginRight="4dip"
             >
             <com.android.systemui.statusbar.AnimatedImageView
-                android:layout_width="25dip"
-                android:layout_height="25dip"
+                android:layout_width="@dimen/status_bar_icon_size"
+                android:layout_height="@dimen/status_bar_icon_size"
+                android:scaleType="center"
                 />
             <com.android.systemui.statusbar.AnimatedImageView
-                android:layout_width="25dip"
-                android:layout_height="25dip"
+                android:layout_width="@dimen/status_bar_icon_size"
+                android:layout_height="@dimen/status_bar_icon_size"
+                android:scaleType="center"
                 />
         </ImageSwitcher>
         <com.android.systemui.statusbar.phone.TickerView android:id="@+id/tickerText"
@@ -109,13 +110,13 @@
             android:paddingTop="2dip"
             android:paddingRight="10dip">
             <TextView
-                android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+                android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
                 />
             <TextView
-                android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+                android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 3e2def5..cd4e37c 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -35,7 +35,7 @@
         android:background="@drawable/notification_header_bg"
         >
         <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+            android:textAppearance="@style/TextAppearance.StatusBar.Date"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_alignParentLeft="true"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 3220e62..abbc89a 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -41,7 +41,7 @@
         android:layout_width="match_parent"
         android:layout_height="@dimen/notification_divider_height"
         android:layout_alignParentBottom="true"
-        android:background="@drawable/notification_item_background_color"
+        android:background="@drawable/status_bar_notification_row_background_color"
         />
 
 </RelativeLayout>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 5ba1908..c88d651 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -19,6 +19,7 @@
 <resources>
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="notification_item_background_color">#ff111111</drawable>
+    <drawable name="notification_item_background_color_pressed">#ff257390</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="status_bar_background">#ff000000</drawable>
     <drawable name="status_bar_recents_background">#b3000000</drawable>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e971896..65d5138 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -305,6 +305,9 @@
     <!-- Content description of the ringer silent icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_ringer_silent">Ringer silent.</string>
 
+    <!-- Content description to tell the user an application has been removed from recents -->
+    <string name="accessibility_recents_item_dismissed"><xliff:g id="app" example="Calendar">%s</xliff:g> dismissed.</string>
+
     <!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
     <string name="data_usage_disabled_dialog_3g_title">2G-3G data disabled</string>
     <!-- Title of dialog shown when 4G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 3d49cd1..dc5c540 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -41,6 +41,13 @@
     </style>
 
     <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
+        <!-- Note: must be dp to fit in status bar -->
+        <item name="android:textSize">16dp</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">@android:color/holo_blue_light</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Date" parent="@*android:style/TextAppearance.StatusBar.Icon">
         <item name="android:textSize">16sp</item>
         <item name="android:textStyle">normal</item>
         <item name="android:textColor">@android:color/holo_blue_light</item>
@@ -69,4 +76,10 @@
         <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
     </style>
 
+    <style name="TextAppearance.StatusBar.PhoneTicker"
+        parent="@*android:style/TextAppearance.StatusBar.Ticker">
+        <!-- Note: must be dp to fit in status bar -->
+        <item name="android:textSize">14dp</item>
+    </style>
+    
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 5b4c33e..8d5c33f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -38,6 +38,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
@@ -483,7 +484,8 @@
         } else {
             Intent intent = ad.intent;
             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-                    | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+                    | Intent.FLAG_ACTIVITY_TASK_ON_HOME
+                    | Intent.FLAG_ACTIVITY_NEW_TASK);
             if (DEBUG) Log.v(TAG, "Starting activity " + intent);
             context.startActivity(intent);
         }
@@ -511,6 +513,12 @@
         final ActivityManager am = (ActivityManager)
                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
         am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
+
+        // Accessibility feedback
+        setContentDescription(
+                mContext.getString(R.string.accessibility_recents_item_dismissed, ad.getLabel()));
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        setContentDescription(null);
     }
 
     private void startApplicationDetailsActivity(String packageName) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index e3a64a8..694da20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -116,15 +116,13 @@
 
         mDisabledFlags = disabledFlags;
 
-        final boolean disableNavigation = ((disabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) != 0);
+        final boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+        final boolean disableRecent = ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
         final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
 
         getBackButton()   .setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
-        getHomeButton()   .setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
-        getRecentsButton().setVisibility(disableNavigation ? View.INVISIBLE : View.VISIBLE);
- 
-        getMenuButton()   .setVisibility((disableNavigation || !mShowMenu)
-                                                           ? View.INVISIBLE : View.VISIBLE);
+        getHomeButton()   .setVisibility(disableHome       ? View.INVISIBLE : View.VISIBLE);
+        getRecentsButton().setVisibility(disableRecent     ? View.INVISIBLE : View.VISIBLE);
     }
 
     public void setMenuVisibility(final boolean show) {
@@ -136,9 +134,7 @@
 
         mShowMenu = show;
 
-        getMenuButton().setVisibility(
-            (0 != (mDisabledFlags & View.STATUS_BAR_DISABLE_NAVIGATION) || !mShowMenu)
-                ? View.INVISIBLE : View.VISIBLE);
+        getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
     }
 
     public void setLowProfile(final boolean lightsOut) {
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 e54de59..9c8c229 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -300,18 +300,6 @@
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
                 mNavigationBarView.setDisabledFlags(mDisabled);
-
-                sb.setOnSystemUiVisibilityChangeListener(
-                    new View.OnSystemUiVisibilityChangeListener() {
-                        @Override
-                        public void onSystemUiVisibilityChange(int visibility) {
-                            if (DEBUG) {
-                                Slog.d(TAG, "systemUi: " + visibility);
-                            }
-                            boolean hide = (0 != (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION));
-                            mNavigationBarView.setHidden(hide);
-                        }
-                    });
             }
         } catch (Resources.NotFoundException ex) {
             // no nav bar for you
@@ -1064,10 +1052,12 @@
         flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "NAVIGATION" : "navigation");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_NAVIGATION) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
         flagdbg.append(">");
@@ -1083,11 +1073,13 @@
             }
         }
 
-        if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
-            // the nav bar will take care of DISABLE_NAVIGATION and DISABLE_BACK
+        if ((diff & (StatusBarManager.DISABLE_HOME 
+                        | StatusBarManager.DISABLE_RECENT 
+                        | StatusBarManager.DISABLE_BACK)) != 0) {
+            // the nav bar will take care of these
             if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
 
-            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
+            if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
                 // close recents if it's visible
                 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
                 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index e76fe51..f5ceed0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.text.StaticLayout;
@@ -50,6 +51,7 @@
     private View mTickerView;
     private ImageSwitcher mIconSwitcher;
     private TextSwitcher mTextSwitcher;
+    private float mIconScale;
 
     private final class Segment {
         StatusBarNotification notification;
@@ -145,6 +147,11 @@
 
     public Ticker(Context context, View sb) {
         mContext = context;
+        final Resources res = context.getResources();
+        final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+        mIconScale = (float)imageBounds / (float)outerBounds;
+
         mTickerView = sb.findViewById(R.id.ticker);
 
         mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon);
@@ -152,6 +159,8 @@
                     AnimationUtils.loadAnimation(context, com.android.internal.R.anim.push_up_in));
         mIconSwitcher.setOutAnimation(
                     AnimationUtils.loadAnimation(context, com.android.internal.R.anim.push_up_out));
+        mIconSwitcher.setScaleX(mIconScale);
+        mIconSwitcher.setScaleY(mIconScale);
 
         mTextSwitcher = (TextSwitcher)sb.findViewById(R.id.tickerText);
         mTextSwitcher.setInAnimation(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 271e508..415a9a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -964,34 +964,24 @@
                 mTicker.halt();
             }
         }
-        if ((diff & (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK)) != 0) {
-            setNavigationVisibility(state &
-                    (StatusBarManager.DISABLE_NAVIGATION | StatusBarManager.DISABLE_BACK));
+        if ((diff & (StatusBarManager.DISABLE_RECENT 
+                        | StatusBarManager.DISABLE_BACK 
+                        | StatusBarManager.DISABLE_HOME)) != 0) {
+            setNavigationVisibility(state);
         }
     }
 
     private void setNavigationVisibility(int visibility) {
-        boolean disableNavigation = ((visibility & StatusBarManager.DISABLE_NAVIGATION) != 0);
+        boolean disableHome = ((visibility & StatusBarManager.DISABLE_HOME) != 0);
+        boolean disableRecent = ((visibility & StatusBarManager.DISABLE_RECENT) != 0);
         boolean disableBack = ((visibility & StatusBarManager.DISABLE_BACK) != 0);
 
-        Slog.i(TAG, "DISABLE_BACK: " + (disableBack ? "yes" : "no"));
-        Slog.i(TAG, "DISABLE_NAVIGATION: " + (disableNavigation ? "yes" : "no"));
+        mBackButton.setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
+        mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
+        mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
 
-        if (disableNavigation && disableBack) {
-            mNavigationArea.setVisibility(View.INVISIBLE);
-        } else {
-            int backVisiblity = (disableBack ? View.INVISIBLE : View.VISIBLE);
-            int navVisibility = (disableNavigation ? View.INVISIBLE : View.VISIBLE);
-
-            mBackButton.setVisibility(backVisiblity);
-            mHomeButton.setVisibility(navVisibility);
-            mRecentButton.setVisibility(navVisibility);
-            // don't change menu button visibility here
-
-            mNavigationArea.setVisibility(View.VISIBLE);
-        }
-
-        mInputMethodSwitchButton.setScreenLocked(disableNavigation);
+        mInputMethodSwitchButton.setScreenLocked(
+                (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);
     }
 
     private boolean hasTicker(Notification n) {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 8569143..11b6c15 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -57,8 +56,6 @@
 
     private static final String TAG = "GlobalActions";
 
-    private StatusBarManager mStatusBar;
-
     private final Context mContext;
     private final AudioManager mAudioManager;
 
@@ -103,13 +100,12 @@
         mKeyguardShowing = keyguardShowing;
         mDeviceProvisioned = isDeviceProvisioned;
         if (mDialog == null) {
-            mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE);
             mDialog = createDialog();
         }
         prepareDialog();
 
-        mStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
         mDialog.show();
+        mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
     }
 
     /**
@@ -249,7 +245,6 @@
 
     /** {@inheritDoc} */
     public void onDismiss(DialogInterface dialog) {
-        mStatusBar.disable(StatusBarManager.DISABLE_NONE);
     }
 
     /** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 8343bbd..6614d79 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -609,6 +609,10 @@
         public void onClockVisibilityChanged() {
             // ignored
         }
+
+        public void onDeviceProvisioned() {
+            // ignored
+        }
     };
 
     private SimStateCallback mSimStateCallback = new SimStateCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index f67f0e0..2d8185b 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -99,6 +99,7 @@
     private static final int MSG_RINGER_MODE_CHANGED = 305;
     private static final int MSG_PHONE_STATE_CHANGED = 306;
     private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
+    private static final int MSG_DEVICE_PROVISIONED = 308;
 
     /**
      * When we receive a
@@ -178,6 +179,9 @@
                     case MSG_CLOCK_VISIBILITY_CHANGED:
                         handleClockVisibilityChanged();
                         break;
+                    case MSG_DEVICE_PROVISIONED:
+                        handleDeviceProvisioned();
+                        break;
                 }
             }
         };
@@ -197,10 +201,8 @@
                     super.onChange(selfChange);
                     mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(),
                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
-                    if (mDeviceProvisioned && mContentObserver != null) {
-                        // We don't need the observer anymore...
-                        mContext.getContentResolver().unregisterContentObserver(mContentObserver);
-                        mContentObserver = null;
+                    if (mDeviceProvisioned) {
+                        mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
                     }
                     if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
                 }
@@ -212,8 +214,14 @@
 
             // prevent a race condition between where we check the flag and where we register the
             // observer by grabbing the value once again...
-            mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(),
+            boolean provisioned = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
+            if (provisioned != mDeviceProvisioned) {
+                mDeviceProvisioned = provisioned;
+                if (mDeviceProvisioned) {
+                    mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
+                }
+            }
         }
 
         // take a guess to start
@@ -271,6 +279,17 @@
         }, filter);
     }
 
+    protected void handleDeviceProvisioned() {
+        for (int i = 0; i < mInfoCallbacks.size(); i++) {
+            mInfoCallbacks.get(i).onDeviceProvisioned();
+        }
+        if (mContentObserver != null) {
+            // We don't need the observer anymore...
+            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+            mContentObserver = null;
+        }
+    }
+
     protected void handlePhoneStateChanged(String newState) {
         if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
         if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
@@ -477,6 +496,10 @@
          */
         void onClockVisibilityChanged();
 
+        /**
+         * Called when the device becomes provisioned
+         */
+        void onDeviceProvisioned();
     }
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 59b546d..de156c9 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -50,8 +50,6 @@
     public KeyguardViewBase(Context context) {
         super(context);
 
-        setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
-
         // This is a faster way to draw the background on devices without hardware acceleration
         setBackgroundDrawable(new Drawable() {
             @Override
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 90972da..2fd165a 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -171,6 +171,17 @@
             }
         }
 
+        // Disable aspects of the system/status/navigation bars that are not appropriate or
+        // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.
+        // Other disabled bits are handled by the KeyguardViewMediator talking directly to the
+        // status bar service.
+        int visFlags =
+                ( View.STATUS_BAR_DISABLE_BACK
+                | View.STATUS_BAR_DISABLE_HOME
+                | View.STATUS_BAR_DISABLE_CLOCK
+                );
+        mKeyguardHost.setSystemUiVisibility(visFlags);
+
         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
         mKeyguardHost.setVisibility(View.VISIBLE);
         mKeyguardView.requestFocus();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index c25e3ca..0471dfe 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -1188,19 +1188,12 @@
                 }
             }
 
+            // Disable aspects of the system/status/navigation bars that must not be re-enabled by
+            // windows that appear on top, ever
             int flags = StatusBarManager.DISABLE_NONE;
             if (mShowing) {
-                // disable navigation status bar components if lock screen is up
-                flags |= StatusBarManager.DISABLE_NAVIGATION;
-                if (!mHidden) {
-                    // showing lockscreen exclusively (no activities in front of it)
-                    // disable back button too
-                    flags |= StatusBarManager.DISABLE_BACK;
-                    if (mUpdateMonitor.isClockVisible()) {
-                        // lockscreen showing a clock, so hide statusbar clock
-                        flags |= StatusBarManager.DISABLE_CLOCK;
-                    }
-                }
+                // disable navigation status bar components (home, recents) if lock screen is up
+                flags |= StatusBarManager.DISABLE_RECENT;
                 if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
                     // showing secure lockscreen; disable expanding.
                     flags |= StatusBarManager.DISABLE_EXPAND;
@@ -1323,4 +1316,9 @@
     public void onTimeChanged() {
         // ignored
     }
+
+    /** {@inheritDoc} */
+    public void onDeviceProvisioned() {
+        mContext.sendBroadcast(mUserPresentIntent);
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 265024b..155f6fd 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -49,6 +49,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.IBinder;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -117,9 +118,17 @@
     private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
     private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;
 
-    // Long enough to stay black while dialer comes up
-    // Short enough to not be black if the user goes back immediately
-    private final int FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT = 1000;
+    // Long enough to stay visible while dialer comes up
+    // Short enough to not be visible if the user goes back immediately
+    private final int FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
+
+    // Long enough to stay visible while the service starts
+    // Short enough to not have to wait long for backup if service fails to start or crashes
+    // The service can take a couple of seconds to start on the first try after boot
+    private final int FACELOCK_VIEW_AREA_SERVICE_TIMEOUT = 3000;
+
+    // So the user has a consistent amount of time when brought to the backup method from FaceLock
+    private final int BACKUP_LOCK_TIMEOUT = 5000;
 
     /**
      * The current {@link KeyguardScreen} will use this to communicate back to us.
@@ -128,6 +137,10 @@
 
 
     private boolean mRequiresSim;
+    //True if we have some sort of overlay on top of the Lockscreen
+    //Also true if we've activated a phone call, either emergency dialing or incoming
+    //This resets when the phone is turned off with no current call
+    private boolean mHasOverlay;
 
 
     /**
@@ -209,6 +222,7 @@
     private Runnable mRecreateRunnable = new Runnable() {
         public void run() {
             updateScreen(mMode, true);
+            restoreWidgetState();
         }
     };
 
@@ -232,10 +246,20 @@
             // TODO: examine all widgets to derive clock status
             mUpdateMonitor.reportClockVisible(true);
         }
+
+        public boolean isVisible(View self) {
+            // TODO: this should be up to the lockscreen to determine if the view
+            // is currently showing. The idea is it can be used for the widget to
+            // avoid doing work if it's not visible. For now just returns the view's
+            // actual visibility.
+            return self.getVisibility() == View.VISIBLE;
+        }
     };
 
     private TransportControlView mTransportControlView;
 
+    private Parcelable mSavedState;
+
     /**
      * @return Whether we are stuck on the lock screen because the sim is
      *   missing.
@@ -268,6 +292,7 @@
         mUpdateMonitor = updateMonitor;
         mLockPatternUtils = lockPatternUtils;
         mWindowController = controller;
+        mHasOverlay = false;
 
         mUpdateMonitor.registerInfoCallback(this);
 
@@ -322,12 +347,15 @@
             }
 
             public void takeEmergencyCallAction() {
+                mHasOverlay = true;
                 // FaceLock must be stopped if it is running when emergency call is pressed
                 stopAndUnbindFromFaceLock();
 
-                // Delay hiding FaceLock area so unlock doesn't display while dialer is coming up
-                mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW,
-                        FACELOCK_VIEW_AREA_EMERGENCY_HIDE_TIMEOUT);
+                // Continue showing FaceLock area until dialer comes up
+                if (mLockPatternUtils.usingBiometricWeak() &&
+                        mLockPatternUtils.isBiometricWeakInstalled()) {
+                    showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
+                }
 
                 pokeWakelock(EMERGENCY_CALL_TIMEOUT);
                 if (TelephonyManager.getDefault().getCallState()
@@ -351,6 +379,7 @@
 
             public void keyguardDone(boolean authenticated) {
                 getCallback().keyguardDone(authenticated);
+                mSavedState = null; // clear state so we re-establish when locked again
             }
 
             public void keyguardDoneDrawing() {
@@ -504,14 +533,18 @@
 
     @Override
     public void onScreenTurnedOff() {
+        if (DEBUG) Log.d(TAG, "screen off");
         mScreenOn = false;
         mForgotPattern = false;
+        mHasOverlay = mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
         if (mMode == Mode.LockScreen) {
             ((KeyguardScreen) mLockScreen).onPause();
         } else {
             ((KeyguardScreen) mUnlockScreen).onPause();
         }
 
+        saveWidgetState();
+
         // When screen is turned off, need to unbind from FaceLock service if using FaceLock
         stopAndUnbindFromFaceLock();
     }
@@ -520,29 +553,50 @@
      *  FaceLock, but only if we're not dealing with a call
     */
     private void activateFaceLockIfAble() {
-        final boolean transportInvisible = mTransportControlView == null ? true :
-                mTransportControlView.getVisibility() != View.VISIBLE;
-        if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
-                && transportInvisible) {
+        if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE && !mHasOverlay) {
             bindToFaceLock();
-            //Eliminate the black background so that the lockpattern will be visible
-            //If FaceUnlock is cancelled
-            mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, 4000);
+            // Show FaceLock area, but only for a little bit so lockpattern will become visible if
+            // FaceLock fails to start or crashes
+            if (mLockPatternUtils.usingBiometricWeak() &&
+                    mLockPatternUtils.isBiometricWeakInstalled()) {
+                showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
+            }
         } else {
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         }
     }
 
     @Override
     public void onScreenTurnedOn() {
+        if (DEBUG) Log.d(TAG, "screen on");
         boolean runFaceLock = false;
         //Make sure to start facelock iff the screen is both on and focused
         synchronized(mFaceLockStartupLock) {
             mScreenOn = true;
             runFaceLock = mWindowFocused;
         }
+
         show();
-        if(runFaceLock) activateFaceLockIfAble();
+
+        restoreWidgetState();
+
+        if (runFaceLock) activateFaceLockIfAble();
+    }
+
+    private void saveWidgetState() {
+        if (mTransportControlView != null) {
+            if (DEBUG) Log.v(TAG, "Saving widget state");
+            mSavedState = mTransportControlView.onSaveInstanceState();
+        }
+    }
+
+    private void restoreWidgetState() {
+        if (mTransportControlView != null) {
+            if (DEBUG) Log.v(TAG, "Restoring widget state");
+            if (mSavedState != null) {
+                mTransportControlView.onRestoreInstanceState(mSavedState);
+            }
+        }
     }
 
     /** Unbind from facelock if something covers this window (such as an alarm)
@@ -550,6 +604,7 @@
      */
     @Override
     public void onWindowFocusChanged (boolean hasWindowFocus) {
+        if (DEBUG) Log.d(TAG, hasWindowFocus ? "focused" : "unfocused");
         boolean runFaceLock = false;
         //Make sure to start facelock iff the screen is both on and focused
         synchronized(mFaceLockStartupLock) {
@@ -557,8 +612,9 @@
             mWindowFocused = hasWindowFocus;
         }
         if(!hasWindowFocus) {
+            mHasOverlay = true;
             stopAndUnbindFromFaceLock();
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         } else if (runFaceLock) {
             activateFaceLockIfAble();
         }
@@ -573,10 +629,14 @@
         }
 
         if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
-            mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+            mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {
+            // Note that show() gets called before the screen turns off to set it up for next time
+            // it is turned on.  We don't want to set a timeout on the FaceLock area here because it
+            // may be gone by the time the screen is turned on again.  We set the timout when the
+            // screen turns on instead.
+            showFaceLockArea();
         } else {
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         }
     }
 
@@ -620,6 +680,7 @@
         mShowLockBeforeUnlock = resources.getBoolean(R.bool.config_enableLockBeforeUnlockScreen);
         mConfiguration = newConfig;
         if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed");
+        saveWidgetState();
         removeCallbacks(mRecreateRunnable);
         post(mRecreateRunnable);
     }
@@ -636,13 +697,17 @@
     public void onRingerModeChanged(int state) {}
     @Override
     public void onClockVisibilityChanged() {}
+    @Override
+    public void onDeviceProvisioned() {}
 
     //We need to stop faceunlock when a phonecall comes in
     @Override
     public void onPhoneStateChanged(int phoneState) {
+        if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
         if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
+            mHasOverlay = true;
             stopAndUnbindFromFaceLock();
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            hideFaceLockArea();
         }
     }
 
@@ -1075,6 +1140,32 @@
         return true;
     }
 
+    // Removes show and hide messages from the message queue
+    private void removeFaceLockAreaDisplayMessages() {
+        mHandler.removeMessages(MSG_SHOW_FACELOCK_AREA_VIEW);
+        mHandler.removeMessages(MSG_HIDE_FACELOCK_AREA_VIEW);
+    }
+
+    // Shows the FaceLock area immediately
+    private void showFaceLockArea() {
+        // Remove messages to prevent a delayed hide message from undo-ing the show
+        removeFaceLockAreaDisplayMessages();
+        mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+    }
+
+    // Hides the FaceLock area immediately
+    private void hideFaceLockArea() {
+        // Remove messages to prevent a delayed show message from undo-ing the hide
+        removeFaceLockAreaDisplayMessages();
+        mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+    }
+
+    // Shows the FaceLock area for a period of time
+    private void showFaceLockAreaWithTimeout(long timeoutMillis) {
+        showFaceLockArea();
+        mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, timeoutMillis);
+    }
+
     // Binds to FaceLock service, but does not tell it to start
     public void bindToFaceLock() {
         if (mLockPatternUtils.usingBiometricWeak() &&
@@ -1120,7 +1211,10 @@
             try {
                 mFaceLockService.registerCallback(mFaceLockCallback);
             } catch (RemoteException e) {
-                throw new RuntimeException("Remote exception");
+                Log.e(TAG, "Caught exception connecting to FaceLock: " + e.toString());
+                mFaceLockService = null;
+                mBoundToFaceLockService = false;
+                return;
             }
 
             if (mFaceLockAreaView != null) {
@@ -1137,6 +1231,7 @@
                 mFaceLockService = null;
                 mFaceLockServiceRunning = false;
             }
+            mBoundToFaceLockService = false;
             Log.w(TAG, "Unexpected disconnect from FaceLock service");
         }
     };
@@ -1152,7 +1247,8 @@
                     try {
                         mFaceLockService.startUi(windowToken, x, y, h, w);
                     } catch (RemoteException e) {
-                        throw new RuntimeException("Remote exception");
+                        Log.e(TAG, "Caught exception starting FaceLock: " + e.toString());
+                        return;
                     }
                     mFaceLockServiceRunning = true;
                 } else {
@@ -1176,7 +1272,7 @@
                         if (DEBUG) Log.d(TAG, "Stopping FaceLock");
                         mFaceLockService.stopUi();
                     } catch (RemoteException e) {
-                        throw new RuntimeException("Remote exception");
+                        Log.e(TAG, "Caught exception stopping FaceLock: " + e.toString());
                     }
                     mFaceLockServiceRunning = false;
                 }
@@ -1191,7 +1287,7 @@
         @Override
         public void unlock() {
             if (DEBUG) Log.d(TAG, "FaceLock unlock()");
-            mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW); // Keep fallback covered
+            showFaceLockArea(); // Keep fallback covered
             stopFaceLock();
 
             mKeyguardScreenCallback.keyguardDone(true);
@@ -1203,8 +1299,9 @@
         @Override
         public void cancel() {
             if (DEBUG) Log.d(TAG, "FaceLock cancel()");
-            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); // Expose fallback
+            hideFaceLockArea(); // Expose fallback
             stopFaceLock();
+            mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
         }
 
         // Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index ec0072c..3ad716b 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -28,6 +28,7 @@
 
 import android.os.CountDownTimer;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.security.KeyStore;
 import android.text.Editable;
 import android.text.InputType;
@@ -109,6 +110,10 @@
         mPasswordEntry.setOnEditorActionListener(this);
 
         mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
+        mKeyboardHelper.setEnableHaptics(
+                Settings.Secure.getInt(mContext.getContentResolver(),
+                        Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0)
+                        != 0);
         if (mIsAlpha) {
             // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard
             mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
@@ -150,9 +155,6 @@
                     //KeyguardStatusViewManager.LOCK_ICON);
         }
 
-        mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
-                com.android.internal.R.array.config_virtualKeyVibePattern : 0);
-
         // Poke the wakelock any time the text is selected or modified
         mPasswordEntry.setOnClickListener(new OnClickListener() {
             public void onClick(View v) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index de8d41a2..af86ae9 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -349,8 +349,9 @@
         }
 
         // Already prepared (isPrepared will be reset to false later)
-        if (st.isPrepared)
+        if (st.isPrepared) {
             return true;
+        }
         
         if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
             // Another Panel is prepared and possibly open, so close it
@@ -800,14 +801,23 @@
                     closePanel(st, true);
 
                 } else if (st.isPrepared) {
+                    boolean show = true;
+                    if (st.refreshMenuContent) {
+                        // Something may have invalidated the menu since we prepared it.
+                        // Re-prepare it to refresh.
+                        st.isPrepared = false;
+                        show = preparePanel(st, event);
+                    }
 
-                    // Write 'menu opened' to event log
-                    EventLog.writeEvent(50001, 0);
+                    if (show) {
+                        // Write 'menu opened' to event log
+                        EventLog.writeEvent(50001, 0);
 
-                    // Show menu
-                    openPanel(st, event);
+                        // Show menu
+                        openPanel(st, event);
 
-                    playSoundEffect = true;
+                        playSoundEffect = true;
+                    }
                 }
             }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3eb04cb..aac3209 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -128,7 +128,6 @@
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
 import android.view.KeyCharacterMap.FallbackAction;
-import android.view.WindowManagerPolicy.WindowManagerFuncs;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -180,26 +179,26 @@
     static final int PRIORITY_PHONE_LAYER = 7;
     // like the ANR / app crashed dialogs
     static final int SYSTEM_ALERT_LAYER = 8;
-    // system-level error dialogs
-    static final int SYSTEM_ERROR_LAYER = 9;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_LAYER = 10;
+    static final int INPUT_METHOD_LAYER = 9;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_DIALOG_LAYER = 11;
+    static final int INPUT_METHOD_DIALOG_LAYER = 10;
     // the keyguard; nothing on top of these can take focus, since they are
     // responsible for power management when displayed.
-    static final int KEYGUARD_LAYER = 12;
-    static final int KEYGUARD_DIALOG_LAYER = 13;
-    static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
-    static final int STATUS_BAR_LAYER = 15;
-    static final int STATUS_BAR_PANEL_LAYER = 16;
+    static final int KEYGUARD_LAYER = 11;
+    static final int KEYGUARD_DIALOG_LAYER = 12;
+    static final int STATUS_BAR_SUB_PANEL_LAYER = 13;
+    static final int STATUS_BAR_LAYER = 14;
+    static final int STATUS_BAR_PANEL_LAYER = 15;
     // the on-screen volume indicator and controller shown when the user
     // changes the device volume
-    static final int VOLUME_OVERLAY_LAYER = 17;
+    static final int VOLUME_OVERLAY_LAYER = 16;
     // things in here CAN NOT take focus, but are shown on top of everything else.
-    static final int SYSTEM_OVERLAY_LAYER = 18;
+    static final int SYSTEM_OVERLAY_LAYER = 17;
     // the navigation bar, if available, shows atop most things
-    static final int NAVIGATION_BAR_LAYER = 19;
+    static final int NAVIGATION_BAR_LAYER = 18;
+    // system-level error dialogs
+    static final int SYSTEM_ERROR_LAYER = 19;
     // the drag layer: input for drag-and-drop is associated with this window,
     // which sits above all other focusable windows
     static final int DRAG_LAYER = 20;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index dd649e7..eb75ebc 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -16,24 +16,6 @@
 
 package com.android.server;
 
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.commons.logging.impl.SimpleLog;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
@@ -42,9 +24,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.Intent.FilterComparison;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.Intent.FilterComparison;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -58,7 +40,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -68,20 +49,37 @@
 import android.util.TypedValue;
 import android.util.Xml;
 import android.widget.RemoteViews;
-import android.widget.RemoteViewsService;
 
 import com.android.internal.appwidget.IAppWidgetHost;
 import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.os.AtomicFile;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
 class AppWidgetService extends IAppWidgetService.Stub
 {
     private static final String TAG = "AppWidgetService";
 
     private static final String SETTINGS_FILENAME = "appwidgets.xml";
-    private static final String SETTINGS_TMP_FILENAME = SETTINGS_FILENAME + ".tmp";
     private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
 
     /*
@@ -1159,70 +1157,46 @@
 
     // only call from initialization -- it assumes that the data structures are all empty
     void loadStateLocked() {
-        File temp = savedStateTempFile();
-        File real = savedStateRealFile();
+        AtomicFile file = savedStateFile();
+        try {
+            FileInputStream stream = file.openRead();
+            readStateFromFileLocked(stream);
 
-        // prefer the real file.  If it doesn't exist, use the temp one, and then copy it to the
-        // real one.  if there is both a real file and a temp one, assume that the temp one isn't
-        // fully written and delete it.
-        if (real.exists()) {
-            readStateFromFileLocked(real);
-            if (temp.exists()) {
-                //noinspection ResultOfMethodCallIgnored
-                temp.delete();
+            if (stream != null) {
+                try {
+                    stream.close();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failed to close state FileInputStream " + e);
+                }
             }
-        } else if (temp.exists()) {
-            readStateFromFileLocked(temp);
-            //noinspection ResultOfMethodCallIgnored
-            temp.renameTo(real);
+        } catch (FileNotFoundException e) {
+            Slog.w(TAG, "Failed to read state: " + e);
         }
     }
-    
+
     void saveStateLocked() {
-        File temp = savedStateTempFile();
-        File real = savedStateRealFile();
-
-        if (!real.exists()) {
-            // If the real one doesn't exist, it's either because this is the first time
-            // or because something went wrong while copying them.  In this case, we can't
-            // trust anything that's in temp.  In order to have the loadState code not
-            // use the temporary one until it's fully written, create an empty file
-            // for real, which will we'll shortly delete.
-            try {
-                //noinspection ResultOfMethodCallIgnored
-                real.createNewFile();
-            } catch (IOException e) {
-                // Ignore
+        AtomicFile file = savedStateFile();
+        FileOutputStream stream;
+        try {
+            stream = file.startWrite();
+            if (writeStateToFileLocked(stream)) {
+                file.finishWrite(stream);
+            } else {
+                file.failWrite(stream);
+                Slog.w(TAG, "Failed to save state, restoring backup.");
             }
+        } catch (IOException e) {
+            Slog.w(TAG, "Failed open state file for write: " + e);
         }
-
-        if (temp.exists()) {
-            //noinspection ResultOfMethodCallIgnored
-            temp.delete();
-        }
-
-        if (!writeStateToFileLocked(temp)) {
-            Slog.w(TAG, "Failed to persist new settings");
-            return;
-        }
-
-        //noinspection ResultOfMethodCallIgnored
-        real.delete();
-        //noinspection ResultOfMethodCallIgnored
-        temp.renameTo(real);
     }
 
-    boolean writeStateToFileLocked(File file) {
-        FileOutputStream stream = null;
+    boolean writeStateToFileLocked(FileOutputStream stream) {
         int N;
 
         try {
-            stream = new FileOutputStream(file, false);
             XmlSerializer out = new FastXmlSerializer();
             out.setOutput(stream, "utf-8");
             out.startDocument(null, true);
-
-            
             out.startTag(null, "gs");
 
             int providerIndex = 0;
@@ -1264,31 +1238,17 @@
             out.endTag(null, "gs");
 
             out.endDocument();
-            stream.close();
             return true;
         } catch (IOException e) {
-            try {
-                if (stream != null) {
-                    stream.close();
-                }
-            } catch (IOException ex) {
-                // Ignore
-            }
-            if (file.exists()) {
-                //noinspection ResultOfMethodCallIgnored
-                file.delete();
-            }
+            Slog.w(TAG, "Failed to write state: " + e);
             return false;
         }
     }
 
-    void readStateFromFileLocked(File file) {
-        FileInputStream stream = null;
-
+    void readStateFromFileLocked(FileInputStream stream) {
         boolean success = false;
 
         try {
-            stream = new FileInputStream(file);
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(stream, null);
 
@@ -1390,22 +1350,15 @@
             } while (type != XmlPullParser.END_DOCUMENT);
             success = true;
         } catch (NullPointerException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (NumberFormatException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (XmlPullParserException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (IOException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
+            Slog.w(TAG, "failed parsing " + e);
         } catch (IndexOutOfBoundsException e) {
-            Slog.w(TAG, "failed parsing " + file, e);
-        }
-        try {
-            if (stream != null) {
-                stream.close();
-            }
-        } catch (IOException e) {
-            // Ignore
+            Slog.w(TAG, "failed parsing " + e);
         }
 
         if (success) {
@@ -1416,6 +1369,8 @@
             }
         } else {
             // failed reading, clean up
+            Slog.w(TAG, "Failed to read state, clearing widgets and hosts.");
+
             mAppWidgetIds.clear();
             mHosts.clear();
             final int N = mInstalledProviders.size();
@@ -1425,14 +1380,8 @@
         }
     }
 
-    File savedStateTempFile() {
-        return new File("/data/system/" + SETTINGS_TMP_FILENAME);
-        //return new File(mContext.getFilesDir(), SETTINGS_FILENAME);
-    }
-
-    File savedStateRealFile() {
-        return new File("/data/system/" + SETTINGS_FILENAME);
-        //return new File(mContext.getFilesDir(), SETTINGS_TMP_FILENAME);
+    AtomicFile savedStateFile() {
+        return new AtomicFile(new File("/data/system/" + SETTINGS_FILENAME));
     }
 
     BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index f9f5458..4ef8837 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -62,14 +62,15 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.WorkSource;
+import android.os.storage.IMountService;
 import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.SparseIntArray;
 import android.util.StringBuilderPrinter;
 
 import com.android.internal.backup.BackupConstants;
@@ -187,6 +188,7 @@
     private IActivityManager mActivityManager;
     private PowerManager mPowerManager;
     private AlarmManager mAlarmManager;
+    private IMountService mMountService;
     IBackupManager mBackupManagerBinder;
 
     boolean mEnabled;   // access to this is synchronized on 'this'
@@ -660,6 +662,7 @@
 
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
 
         mBackupManagerBinder = asInterface(asBinder());
 
@@ -1037,6 +1040,40 @@
 
     // Backup password management
     boolean passwordMatchesSaved(String candidatePw, int rounds) {
+        // First, on an encrypted device we require matching the device pw
+        final boolean isEncrypted;
+        try {
+            isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE);
+            if (isEncrypted) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Device encrypted; verifying against device data pw");
+                }
+                // 0 means the password validated
+                // -2 means device not encrypted
+                // Any other result is either password failure or an error condition,
+                // so we refuse the match
+                final int result = mMountService.verifyEncryptionPassword(candidatePw);
+                if (result == 0) {
+                    if (MORE_DEBUG) Slog.d(TAG, "Pw verifies");
+                    return true;
+                } else if (result != -2) {
+                    if (MORE_DEBUG) Slog.d(TAG, "Pw mismatch");
+                    return false;
+                } else {
+                    // ...else the device is supposedly not encrypted.  HOWEVER, the
+                    // query about the encryption state said that the device *is*
+                    // encrypted, so ... we may have a problem.  Log it and refuse
+                    // the backup.
+                    Slog.e(TAG, "verified encryption state mismatch against query; no match allowed");
+                    return false;
+                }
+            }
+        } catch (Exception e) {
+            // Something went wrong talking to the mount service.  This is very bad;
+            // assume that we fail password validation.
+            return false;
+        }
+
         if (mPasswordHash == null) {
             // no current password case -- require that 'currentPw' be null or empty
             if (candidatePw == null || "".equals(candidatePw)) {
@@ -1114,7 +1151,15 @@
     public boolean hasBackupPassword() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "hasBackupPassword");
-        return (mPasswordHash != null && mPasswordHash.length() > 0);
+
+        try {
+            return (mMountService.getEncryptionState() != IMountService.ENCRYPTION_STATE_NONE)
+                || (mPasswordHash != null && mPasswordHash.length() > 0);
+        } catch (Exception e) {
+            // If we can't talk to the mount service we have a serious problem; fail
+            // "secure" i.e. assuming that we require a password
+            return true;
+        }
     }
 
     // Maintain persistent state around whether need to do an initialize operation.
@@ -5007,7 +5052,17 @@
 
                         params.observer = observer;
                         params.curPassword = curPassword;
-                        params.encryptPassword = encPpassword;
+
+                        boolean isEncrypted;
+                        try {
+                            isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE);
+                            if (isEncrypted) Slog.w(TAG, "Device is encrypted; forcing enc password");
+                        } catch (RemoteException e) {
+                            // couldn't contact the mount service; fail "safe" and assume encryption
+                            Slog.e(TAG, "Unable to contact mount service!");
+                            isEncrypted = true;
+                        }
+                        params.encryptPassword = (isEncrypted) ? curPassword : encPpassword;
 
                         if (DEBUG) Slog.d(TAG, "Sending conf message with verb " + verb);
                         mWakelock.acquire();
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 582f0ed..5425813 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1897,6 +1897,53 @@
         }
     }
 
+    /**
+     * Validate a user-supplied password string with cryptfs
+     */
+    @Override
+    public int verifyEncryptionPassword(String password) throws RemoteException {
+        // Only the system process is permitted to validate passwords
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to access the crypt keeper");
+        }
+
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
+            "no permission to access the crypt keeper");
+
+        if (TextUtils.isEmpty(password)) {
+            throw new IllegalArgumentException("password cannot be empty");
+        }
+
+        waitForReady();
+
+        if (DEBUG_EVENTS) {
+            Slog.i(TAG, "validating encryption password...");
+        }
+
+        try {
+            ArrayList<String> response = mConnector.doCommand("cryptfs verifypw " + password);
+            String[] tokens = response.get(0).split(" ");
+
+            if (tokens == null || tokens.length != 2) {
+                String msg = "Unexpected result from cryptfs verifypw: {";
+                if (tokens == null) msg += "null";
+                else for (int i = 0; i < tokens.length; i++) {
+                    if (i != 0) msg += ',';
+                    msg += tokens[i];
+                }
+                msg += '}';
+                Slog.e(TAG, msg);
+                return -1;
+            }
+
+            Slog.i(TAG, "cryptfs verifypw => " + tokens[1]);
+            return Integer.parseInt(tokens[1]);
+        } catch (NativeDaemonConnectorException e) {
+            // Encryption failed
+            return e.getCode();
+        }
+    }
+
     public Parcelable[] getVolumeList() {
         synchronized(mVolumes) {
             int size = mVolumes.size();
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 1941c6a..994201b 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1698,11 +1698,6 @@
                     // make sure button and key backlights are off too
                     mButtonLight.turnOff();
                     mKeyboardLight.turnOff();
-                    // clear current value so we will update based on the new conditions
-                    // when the sensor is reenabled.
-                    mLightSensorValue = -1;
-                    // reset our highest light sensor value when the screen turns off
-                    mHighestLightSensorValue = -1;
                 }
             }
         }
@@ -2472,6 +2467,7 @@
         synchronized (mLocks) {
             mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
             if (mIsDocked) {
+                // allow brightness to decrease when docked
                 mHighestLightSensorValue = -1;
             }
             if ((mPowerState & SCREEN_ON_BIT) != 0) {
@@ -3047,11 +3043,21 @@
             long identity = Binder.clearCallingIdentity();
             try {
                 if (enable) {
+                    // reset our highest value when reenabling
+                    mHighestLightSensorValue = -1;
+                    // force recompute of backlight values
+                    if (mLightSensorValue >= 0) {
+                        int value = (int)mLightSensorValue;
+                        mLightSensorValue = -1;
+                        handleLightSensorValue(value);
+                    }
                     mSensorManager.registerListener(mLightListener, mLightSensor,
                             SensorManager.SENSOR_DELAY_NORMAL);
                 } else {
                     mSensorManager.unregisterListener(mLightListener);
                     mHandler.removeCallbacks(mAutoBrightnessTask);
+                    mLightSensorPendingDecrease = false;
+                    mLightSensorPendingIncrease = false;
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3103,43 +3109,45 @@
         }
     };
 
+    private void handleLightSensorValue(int value) {
+        long milliseconds = SystemClock.elapsedRealtime();
+        if (mLightSensorValue == -1 ||
+                milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
+            // process the value immediately if screen has just turned on
+            mHandler.removeCallbacks(mAutoBrightnessTask);
+            mLightSensorPendingDecrease = false;
+            mLightSensorPendingIncrease = false;
+            lightSensorChangedLocked(value);
+        } else {
+            if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
+                    (value < mLightSensorValue && mLightSensorPendingIncrease) ||
+                    (value == mLightSensorValue) ||
+                    (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
+                // delay processing to debounce the sensor
+                mHandler.removeCallbacks(mAutoBrightnessTask);
+                mLightSensorPendingDecrease = (value < mLightSensorValue);
+                mLightSensorPendingIncrease = (value > mLightSensorValue);
+                if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
+                    mLightSensorPendingValue = value;
+                    mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
+                }
+            } else {
+                mLightSensorPendingValue = value;
+            }
+        }
+    }
+
     SensorEventListener mLightListener = new SensorEventListener() {
         public void onSensorChanged(SensorEvent event) {
+            if (mDebugLightSensor) {
+                Slog.d(TAG, "onSensorChanged: light value: " + event.values[0]);
+            }
             synchronized (mLocks) {
                 // ignore light sensor while screen is turning off
                 if (isScreenTurningOffLocked()) {
                     return;
                 }
-
-                int value = (int)event.values[0];
-                long milliseconds = SystemClock.elapsedRealtime();
-                if (mDebugLightSensor) {
-                    Slog.d(TAG, "onSensorChanged: light value: " + value);
-                }
-                if (mLightSensorValue == -1 ||
-                        milliseconds < mLastScreenOnTime + mLightSensorWarmupTime) {
-                    // process the value immediately if screen has just turned on
-                    mHandler.removeCallbacks(mAutoBrightnessTask);
-                    mLightSensorPendingDecrease = false;
-                    mLightSensorPendingIncrease = false;
-                    lightSensorChangedLocked(value);
-                } else {
-                    if ((value > mLightSensorValue && mLightSensorPendingDecrease) ||
-                            (value < mLightSensorValue && mLightSensorPendingIncrease) ||
-                            (value == mLightSensorValue) ||
-                            (!mLightSensorPendingDecrease && !mLightSensorPendingIncrease)) {
-                        // delay processing to debounce the sensor
-                        mHandler.removeCallbacks(mAutoBrightnessTask);
-                        mLightSensorPendingDecrease = (value < mLightSensorValue);
-                        mLightSensorPendingIncrease = (value > mLightSensorValue);
-                        if (mLightSensorPendingDecrease || mLightSensorPendingIncrease) {
-                            mLightSensorPendingValue = value;
-                            mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY);
-                        }
-                    } else {
-                        mLightSensorPendingValue = value;
-                    }
-                }
+                handleLightSensorValue((int)event.values[0]);
             }
         }
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 660681b..5bfe6f8 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1402,7 +1402,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             if (hadLock) {
-                noteAcquireWifiLock(wifiLock);
+                noteReleaseWifiLock(wifiLock);
                 switch(wifiLock.mMode) {
                     case WifiManager.WIFI_MODE_FULL:
                         ++mFullLocksReleased;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d038d76..55fb371 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3427,8 +3427,10 @@
                     ac.removePackage(name);
                 }
             }
-            mMainStack.resumeTopActivityLocked(null);
-            mMainStack.scheduleIdleLocked();
+            if (mBooted) {
+                mMainStack.resumeTopActivityLocked(null);
+                mMainStack.scheduleIdleLocked();
+            }
         }
         
         return didSomething;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index b9d3d76..1aed7fe0 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2067,7 +2067,7 @@
      * task starting at a specified index.
      */
     private final void performClearTaskAtIndexLocked(int taskId, int i) {
-        while (i < (mHistory.size()-1)) {
+        while (i < mHistory.size()) {
             ActivityRecord r = mHistory.get(i);
             if (r.task.taskId != taskId) {
                 // Whoops hit the end.
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index a769c05..57e11cf 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -24,6 +24,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.Slog;
+import android.view.WindowManager;
 
 class AppErrorDialog extends BaseErrorDialog {
     private final static String TAG = "AppErrorDialog";
@@ -73,6 +74,9 @@
         setTitle(res.getText(com.android.internal.R.string.aerr_title));
         getWindow().addFlags(FLAG_SYSTEM_ERROR);
         getWindow().setTitle("Application Error: " + app.info.processName);
+        if (app.persistent) {
+            getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        }
 
         // After the timeout, pretend the user clicked the quit button
         mHandler.sendMessageDelayed(
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0a9ef3d..68f0e66 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -167,6 +167,7 @@
     static final boolean DEBUG_DRAG = false;
     static final boolean DEBUG_SCREEN_ON = false;
     static final boolean DEBUG_SCREENSHOT = false;
+    static final boolean DEBUG_BOOT = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -4728,6 +4729,14 @@
 
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
+                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (mSystemBooted) {
                 return;
             }
@@ -4745,6 +4754,14 @@
     }
 
     void enableScreenIfNeededLocked() {
+        if (DEBUG_BOOT) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
+                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                    + " mShowingBootMessages=" + mShowingBootMessages
+                    + " mSystemBooted=" + mSystemBooted, here);
+        }
         if (mDisplayEnabled) {
             return;
         }
@@ -4767,6 +4784,14 @@
 
     public void performEnableScreen() {
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (mDisplayEnabled) {
                 return;
             }
@@ -4780,10 +4805,22 @@
                 boolean haveBootMsg = false;
                 boolean haveApp = false;
                 boolean haveWallpaper = false;
-                boolean haveKeyguard = false;
+                boolean haveKeyguard = true;
                 final int N = mWindows.size();
                 for (int i=0; i<N; i++) {
                     WindowState w = mWindows.get(i);
+                    if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+                        // Only if there is a keyguard attached to the window manager
+                        // will we consider ourselves as having a keyguard.  If it
+                        // isn't attached, we don't know if it wants to be shown or
+                        // hidden.  If it is attached, we will say we have a keyguard
+                        // if the window doesn't want to be visible, because in that
+                        // case it explicitly doesn't want to be shown so we should
+                        // not delay turning the screen on for it.
+                        boolean vis = w.mViewVisibility == View.VISIBLE
+                                && w.mPolicyVisibility;
+                        haveKeyguard = !vis;
+                    }
                     if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
                         return;
                     }
@@ -4800,7 +4837,7 @@
                     }
                 }
 
-                if (DEBUG_SCREEN_ON) {
+                if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
                     Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
                             + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
                             + " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
@@ -4821,7 +4858,7 @@
             }
 
             mDisplayEnabled = true;
-            if (DEBUG_SCREEN_ON) Slog.i(TAG, "******************** ENABLING SCREEN!");
+            if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
             if (false) {
                 StringWriter sw = new StringWriter();
                 PrintWriter pw = new PrintWriter(sw);
@@ -4852,6 +4889,14 @@
     public void showBootMessage(final CharSequence msg, final boolean always) {
         boolean first = false;
         synchronized(mWindowMap) {
+            if (DEBUG_BOOT) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
+                        + " mAllowBootMessages=" + mAllowBootMessages
+                        + " mShowingBootMessages=" + mShowingBootMessages
+                        + " mSystemBooted=" + mSystemBooted, here);
+            }
             if (!mAllowBootMessages) {
                 return;
             }
@@ -4873,6 +4918,14 @@
     }
 
     public void hideBootMessagesLocked() {
+        if (DEBUG_BOOT) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
+                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
+                    + " mShowingBootMessages=" + mShowingBootMessages
+                    + " mSystemBooted=" + mSystemBooted, here);
+        }
         if (mShowingBootMessages) {
             mShowingBootMessages = false;
             mPolicy.hideBootMessages();
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 8f5a2eb..3d6cd68 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -726,7 +726,7 @@
                 isPrlLoaded = false;
             }
             if (!isPrlLoaded) {
-                newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
+                newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
             } else if (!isSidsAllZeros()) {
                 if (!namMatch && !mIsInPrl) {
                     // Use default
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 7c94c2d..94ad620 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -114,9 +114,9 @@
 //                v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
 //            }
 //        },
-        new Test("systemUiVisibility: STATUS_BAR_DISABLE_NAVIGATION") {
+        new Test("systemUiVisibility: STATUS_BAR_DISABLE_HOME") {
             public void run() {
-                mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_NAVIGATION);
+                mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
             }
         },
         new Test("Double Remove") {
@@ -227,16 +227,21 @@
                     }, 3000);
             }
         },
-        new Test("Disable Navigation") {
+        new Test("Disable Home (StatusBarManager)") {
             public void run() {
-                mStatusBarManager.disable(StatusBarManager.DISABLE_NAVIGATION);
+                mStatusBarManager.disable(StatusBarManager.DISABLE_HOME);
             }
         },
-        new Test("Disable Back") {
+        new Test("Disable Back (StatusBarManager)") {
             public void run() {
                 mStatusBarManager.disable(StatusBarManager.DISABLE_BACK);
             }
         },
+        new Test("Disable Recent (StatusBarManager)") {
+            public void run() {
+                mStatusBarManager.disable(StatusBarManager.DISABLE_RECENT);
+            }
+        },
         new Test("Disable Clock") {
             public void run() {
                 mStatusBarManager.disable(StatusBarManager.DISABLE_CLOCK);