Merge "Remove NfcFragment from activity when no longer sharing." 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/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/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/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/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 73e5026..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
@@ -8364,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()}.
@@ -8409,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
@@ -13095,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;
@@ -14086,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/WebView.java b/core/java/android/webkit/WebView.java
index 1c22a0b..48615bd 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4514,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
@@ -4530,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;
         }
@@ -4546,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()) {
@@ -9416,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);
         }
     }
 
@@ -9453,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,
@@ -9518,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();
@@ -9540,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/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/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/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
index 8f6f839..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,12 +335,13 @@
 
     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;
@@ -349,22 +353,81 @@
             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/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_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index c63ca94..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/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_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index ec7ef0c..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/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_sys_speakerphone.png b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
index 6938ab4..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/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index b15e847..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'
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index b4fbe72..b8cd947 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -100,8 +100,8 @@
       <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="#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>
@@ -653,7 +653,7 @@
 
 
 
-<h3 id="P2pWiFi">Peer-to-peer Wi-Fi</h3>
+<h3 id="WiFiDirect">Wi-Fi Direct</h3>
 
 <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
@@ -739,7 +739,7 @@
 
 
 
-<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 their applications are using.
 The Settings app provides controls that allow users to manage set limits for network data usage and
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index dab5b29..0d14f79 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -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/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 6cb246c..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();
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ce587b3..693b7b8 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -75,7 +75,7 @@
 }
 
 // This test probably doesn't belong here.
-TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
     sp<ANativeWindow> anw(mSurface);
 
     // Verify the screenshot works with no protected buffers.
@@ -114,31 +114,8 @@
     }
     heap = 0;
     w = h = fmt = 0;
-    ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt,
             64, 64, 0, 0x7fffffff));
-    ASSERT_TRUE(heap == NULL);
-
-    // XXX: This should not be needed, but it seems that the new buffers don't
-    // correctly show up after the upcoming dequeue/lock/queue loop without it.
-    // We should look into this at some point.
-    ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
-
-    // Un-set the PROTECTED usage bit and verify that the screenshot works
-    // again.  Note that we have to change the buffers geometry to ensure that
-    // the buffers get reallocated, as the new usage bits are a subset of the
-    // old.
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0));
-    for (int i = 0; i < 4; i++) {
-        // Loop to make sure SurfaceFlinger has retired a protected buffer.
-        ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
-        ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
-        ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
-    }
-    heap = 0;
-    w = h = fmt = 0;
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
-            0x7fffffff));
     ASSERT_TRUE(heap != NULL);
 }
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 0c5e673..e0c2b3b 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -368,6 +368,8 @@
         intentFilter.addAction(Intent.ACTION_USB_DGTL_HEADSET_PLUG);
         intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
         intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
+        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
+        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
         context.registerReceiver(mReceiver, intentFilter);
 
         // Register for package removal intent broadcasts for media button receiver persistence
@@ -2565,6 +2567,10 @@
                         removeMediaButtonReceiverForPackage(packageName);
                     }
                 }
+            } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                AudioSystem.setParameters("screen_state=on");
+            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                AudioSystem.setParameters("screen_state=off");
             }
         }
     }
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/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/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/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/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 80275b1..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;
@@ -221,6 +222,7 @@
     private Runnable mRecreateRunnable = new Runnable() {
         public void run() {
             updateScreen(mMode, true);
+            restoreWidgetState();
         }
     };
 
@@ -244,8 +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.
@@ -365,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() {
@@ -528,6 +543,8 @@
             ((KeyguardScreen) mUnlockScreen).onPause();
         }
 
+        saveWidgetState();
+
         // When screen is turned off, need to unbind from FaceLock service if using FaceLock
         stopAndUnbindFromFaceLock();
     }
@@ -558,8 +575,28 @@
             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)
@@ -643,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);
     }
@@ -895,13 +933,13 @@
     }
 
     private void initializeTransportControlView(View view) {
-        TransportControlView tcv = (TransportControlView) view.findViewById(R.id.transport);
-        if (tcv == null) {
+        mTransportControlView = (TransportControlView) view.findViewById(R.id.transport);
+        if (mTransportControlView == null) {
             if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
         } else {
             mUpdateMonitor.reportClockVisible(true);
-            tcv.setVisibility(View.GONE); // hide until it requests being shown.
-            tcv.setCallback(mWidgetCallback);
+            mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown.
+            mTransportControlView.setCallback(mWidgetCallback);
         }
     }
 
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();