Merge "Remove unneeded margin below action bar subtitles" into jb-mr1-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ef9f6d4..5f65f08 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4530,6 +4530,14 @@
 
             IContentProvider provider = pr.mProvider;
             IBinder jBinder = provider.asBinder();
+            if (!jBinder.isBinderAlive()) {
+                // The hosting process of the provider has died; we can't
+                // use this one.
+                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
+                        + ": existing object's process dead");
+                handleUnstableProviderDiedLocked(jBinder, true);
+                return null;
+            }
 
             // Only increment the ref count if we have one.  If we don't then the
             // provider is not reference counted and never needs to be released.
@@ -4670,33 +4678,37 @@
     }
 
     final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
-        synchronized(mProviderMap) {
-            ProviderRefCount prc = mProviderRefCountMap.get(provider);
-            if (prc != null) {
-                if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
-                        + provider + " " + prc.holder.info.name);
-                mProviderRefCountMap.remove(provider);
-                if (prc.client != null && prc.client.mNames != null) {
-                    for (String name : prc.client.mNames) {
-                        ProviderClientRecord pr = mProviderMap.get(name);
-                        if (pr != null && pr.mProvider.asBinder() == provider) {
-                            Slog.i(TAG, "Removing dead content provider: " + name);
-                            mProviderMap.remove(name);
-                        }
+        synchronized (mProviderMap) {
+            handleUnstableProviderDiedLocked(provider, fromClient);
+        }
+    }
+
+    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
+        ProviderRefCount prc = mProviderRefCountMap.get(provider);
+        if (prc != null) {
+            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
+                    + provider + " " + prc.holder.info.name);
+            mProviderRefCountMap.remove(provider);
+            if (prc.client != null && prc.client.mNames != null) {
+                for (String name : prc.client.mNames) {
+                    ProviderClientRecord pr = mProviderMap.get(name);
+                    if (pr != null && pr.mProvider.asBinder() == provider) {
+                        Slog.i(TAG, "Removing dead content provider: " + name);
+                        mProviderMap.remove(name);
                     }
                 }
-                if (fromClient) {
-                    // We found out about this due to execution in our client
-                    // code.  Tell the activity manager about it now, to ensure
-                    // that the next time we go to do anything with the provider
-                    // it knows it is dead (so we don't race with its death
-                    // notification).
-                    try {
-                        ActivityManagerNative.getDefault().unstableProviderDied(
-                                prc.holder.connection);
-                    } catch (RemoteException e) {
-                        //do nothing content provider object is dead any way
-                    }
+            }
+            if (fromClient) {
+                // We found out about this due to execution in our client
+                // code.  Tell the activity manager about it now, to ensure
+                // that the next time we go to do anything with the provider
+                // it knows it is dead (so we don't race with its death
+                // notification).
+                try {
+                    ActivityManagerNative.getDefault().unstableProviderDied(
+                            prc.holder.connection);
+                } catch (RemoteException e) {
+                    //do nothing content provider object is dead any way
                 }
             }
         }
diff --git a/core/java/android/nfc/INfcAdapterExtras.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
index 2b9d4f0..41ebf63 100644
--- a/core/java/android/nfc/INfcAdapterExtras.aidl
+++ b/core/java/android/nfc/INfcAdapterExtras.aidl
@@ -29,4 +29,5 @@
     int getCardEmulationRoute(in String pkg);
     void setCardEmulationRoute(in String pkg, int route);
     void authenticate(in String pkg, in byte[] token);
+    String getDriverName(in String pkg);
 }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 557d3f3..6d6d147 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -37,7 +37,8 @@
     void nap(long time);
 
     boolean isScreenOn();
-    void reboot(String reason);
+    void reboot(boolean confirm, String reason, boolean wait);
+    void shutdown(boolean confirm, boolean wait);
     void crash(String message);
 
     void setStayOnSetting(int val);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index ae50ddb..fb02c0a 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -596,7 +596,7 @@
      */
     public void reboot(String reason) {
         try {
-            mService.reboot(reason);
+            mService.reboot(false, reason, true);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 9bfa8c0..09ff7be 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -1083,6 +1083,12 @@
                 }
                 return;
             }
+            if (mSinglePane) {
+                mFragmentBreadCrumbs.setVisibility(View.GONE);
+                // Hide the breadcrumb section completely for single-pane
+                View bcSection = findViewById(com.android.internal.R.id.breadcrumb_section);
+                if (bcSection != null) bcSection.setVisibility(View.GONE);
+            }
             mFragmentBreadCrumbs.setMaxVisible(2);
             mFragmentBreadCrumbs.setActivity(this);
         }
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index d2bed48..123acca 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -475,10 +475,14 @@
         Alignment align = getParagraphAlignment(line);
         int dir = getParagraphDirection(line);
 
-        int x;
         if (align == Alignment.ALIGN_LEFT) {
-            x = left;
-        } else if (align == Alignment.ALIGN_NORMAL) {
+            align = (dir == DIR_LEFT_TO_RIGHT) ? Alignment.ALIGN_NORMAL : Alignment.ALIGN_OPPOSITE;
+        } else if (align == Alignment.ALIGN_RIGHT) {
+            align = (dir == DIR_LEFT_TO_RIGHT) ? Alignment.ALIGN_OPPOSITE : Alignment.ALIGN_NORMAL;
+        }
+
+        int x;
+        if (align == Alignment.ALIGN_NORMAL) {
             if (dir == DIR_LEFT_TO_RIGHT) {
                 x = left;
             } else {
@@ -498,12 +502,11 @@
                 }
             }
             int max = (int)getLineExtent(line, tabStops, false);
-            if (align == Alignment.ALIGN_RIGHT) {
-                x = right - max;
-            } else if (align == Alignment.ALIGN_OPPOSITE) {
+            if (align == Alignment.ALIGN_OPPOSITE) {
                 if (dir == DIR_LEFT_TO_RIGHT) {
                     x = right - max;
                 } else {
+                    // max is negative here
                     x = left - max;
                 }
             } else { // Alignment.ALIGN_CENTER
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index ba8be6c..d2df45a 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -236,18 +236,6 @@
     }
 
     @Override
-    public void drawRect(Rect r, Paint paint) {
-        super.drawRect(r, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawRect(RectF r, Paint paint) {
-        super.drawRect(r, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
     public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
         super.drawRoundRect(rect, rx, ry, paint);
         recordShaderBitmap(paint);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 99987bf..37e0a36 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -507,17 +507,22 @@
      * @param width The width of the drawing surface.
      * @param height The height of the drawing surface.
      * @param surface The surface to hardware accelerate
+     *                
+     * @return true if the surface was initialized, false otherwise. Returning
+     *         false might mean that the surface was already initialized.
      */
-    void initializeIfNeeded(int width, int height, Surface surface)
+    boolean initializeIfNeeded(int width, int height, Surface surface)
             throws Surface.OutOfResourcesException {
         if (isRequested()) {
             // We lost the gl context, so recreate it.
             if (!isEnabled()) {
                 if (initialize(surface)) {
                     setup(width, height);
+                    return true;
                 }
             }
-        }        
+        }
+        return false;
     }
 
     /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2d083b6..ae51c1d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2904,6 +2904,7 @@
      */
     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
 
+    @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
     private Drawable mBackground;
 
     private int mBackgroundResource;
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index c013d85..023e58f 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -923,8 +923,12 @@
     private static void dumpViewProperties(Context context, Object view,
             BufferedWriter out, String prefix) throws IOException {
 
-        Class<?> klass = view.getClass();
+        if (view == null) {
+            out.write(prefix + "=4,null ");
+            return;
+        }
 
+        Class<?> klass = view.getClass();
         do {
             exportFields(context, view, out, klass, prefix);
             exportMethods(context, view, out, klass, prefix);
@@ -1064,8 +1068,8 @@
                     return;
                 } else if (!type.isPrimitive()) {
                     if (property.deepExport()) {
-                        dumpViewProperties(context, field.get(view), out, prefix
-                                + property.prefix());
+                        dumpViewProperties(context, field.get(view), out, prefix +
+                                property.prefix());
                         continue;
                     }
                 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 438f792..be2d5b3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -52,7 +52,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
-import android.os.UserHandle;
 import android.util.AndroidRuntimeException;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -2817,10 +2816,10 @@
             case MSG_RESIZED: {
                 // Recycled in the fall through...
                 SomeArgs args = (SomeArgs) msg.obj;
-                if (mWinFrame.equals((Rect) args.arg1)
-                        && mPendingContentInsets.equals((Rect) args.arg2)
-                        && mPendingVisibleInsets.equals((Rect) args.arg3)
-                        && ((Configuration) args.arg4 == null)) {
+                if (mWinFrame.equals(args.arg1)
+                        && mPendingContentInsets.equals(args.arg2)
+                        && mPendingVisibleInsets.equals(args.arg3)
+                        && args.arg4 == null) {
                     break;
                 }
                 } // fall through...
@@ -2882,8 +2881,10 @@
                                 mSurface != null && mSurface.isValid()) {
                             mFullRedrawNeeded = true;
                             try {
-                                mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
-                                        mHolder.getSurface());
+                                if (mAttachInfo.mHardwareRenderer.initializeIfNeeded(
+                                        mWidth, mHeight, mHolder.getSurface())) {
+                                    mFullRedrawNeeded = true;
+                                }
                             } catch (Surface.OutOfResourcesException e) {
                                 Log.e(TAG, "OutOfResourcesException locking surface", e);
                                 try {
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 0d9cf9a..6c5ed7e 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -375,31 +375,31 @@
     }
 
     private void notifyCellAdded() {
+        sendAccessEvent(R.string.lockscreen_access_pattern_cell_added);
         if (mOnPatternListener != null) {
             mOnPatternListener.onPatternCellAdded(mPattern);
         }
-        sendAccessEvent(R.string.lockscreen_access_pattern_cell_added);
     }
 
     private void notifyPatternStarted() {
+        sendAccessEvent(R.string.lockscreen_access_pattern_start);
         if (mOnPatternListener != null) {
             mOnPatternListener.onPatternStart();
         }
-        sendAccessEvent(R.string.lockscreen_access_pattern_start);
     }
 
     private void notifyPatternDetected() {
+        sendAccessEvent(R.string.lockscreen_access_pattern_detected);
         if (mOnPatternListener != null) {
             mOnPatternListener.onPatternDetected(mPattern);
         }
-        sendAccessEvent(R.string.lockscreen_access_pattern_detected);
     }
 
     private void notifyPatternCleared() {
+        sendAccessEvent(R.string.lockscreen_access_pattern_cleared);
         if (mOnPatternListener != null) {
             mOnPatternListener.onPatternCleared();
         }
-        sendAccessEvent(R.string.lockscreen_access_pattern_cleared);
     }
 
     /**
@@ -799,9 +799,7 @@
     }
 
     private void sendAccessEvent(int resId) {
-        setContentDescription(mContext.getString(resId));
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        setContentDescription(null);
+        announceForAccessibility(mContext.getString(resId));
     }
 
     private void handleActionUp(MotionEvent event) {
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 2a02f7c..5d6f738 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -20,6 +20,7 @@
 
 #include "SkCanvas.h"
 #include "SkDevice.h"
+#include "SkDrawFilter.h"
 #include "SkGraphics.h"
 #include "SkImageRef_GlobalPool.h"
 #include "SkPorterDuff.h"
@@ -784,7 +785,15 @@
 #define kStdUnderline_Thickness (1.0f / 18.0f)
 
 static void doDrawTextDecorations(SkCanvas* canvas, jfloat x, jfloat y, jfloat length, SkPaint* paint) {
-    uint32_t flags = paint->getFlags();
+    uint32_t flags;
+    SkDrawFilter* drawFilter = canvas->getDrawFilter();
+    if (drawFilter) {
+        SkPaint paintCopy(*paint);
+        drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type);
+        flags = paintCopy.getFlags();
+    } else {
+        flags = paint->getFlags();
+    }
     if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
         SkScalar left = SkFloatToScalar(x);
         SkScalar right = SkFloatToScalar(x + length);
diff --git a/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml b/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
index 0fb3443..8e86427 100644
--- a/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
+++ b/core/res/res/layout-xlarge/breadcrumbs_in_fragment.xml
@@ -15,6 +15,7 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+android:id/breadcrumb_section"
         android:orientation="vertical"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d423ecd..281d92a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -217,6 +217,7 @@
   <java-symbol type="id" name="sms_short_code_detail_message" />
   <java-symbol type="id" name="sms_short_code_remember_choice_checkbox" />
   <java-symbol type="id" name="sms_short_code_remember_undo_instruction" />
+  <java-symbol type="id" name="breadcrumb_section" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index 5f78aea..00f4467 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -12,7 +12,8 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_Downloads_20120823.zip">Download All</a>
+  <a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'All Design Assets']);"
+    href="{@docRoot}downloads/design/Android_Design_Downloads_20120823.zip">Download All</a>
 </p>
 
   </div>
@@ -37,10 +38,14 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_Fireworks_Stencil_20120814.png">Adobe&reg; Fireworks&reg; PNG Stencil</a>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_Illustrator_Vectors_20120814.ai">Adobe&reg; Illustrator&reg; Stencil</a>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle">Omni&reg; OmniGraffle&reg; Stencil</a>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_Holo_Widgets_20120814.zip">Adobe&reg; Photoshop&reg; Sources</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Fireworks Stencil']);"
+    href="{@docRoot}downloads/design/Android_Design_Fireworks_Stencil_20120814.png">Adobe&reg; Fireworks&reg; PNG Stencil</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Illustrator Stencil']);"
+    href="{@docRoot}downloads/design/Android_Design_Illustrator_Vectors_20120814.ai">Adobe&reg; Illustrator&reg; Stencil</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'OmniGraffle Stencil']);"
+    href="{@docRoot}downloads/design/Android_Design_OmniGraffle_Stencil_20120814.graffle">Omni&reg; OmniGraffle&reg; Stencil</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Photoshop Sources']);"
+    href="{@docRoot}downloads/design/Android_Design_Holo_Widgets_20120814.zip">Adobe&reg; Photoshop&reg; Sources</a>
 </p>
 
   </div>
@@ -66,7 +71,8 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_Icons_20120814.zip">Action Bar Icon Pack</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Action Bar Icons']);"
+    href="{@docRoot}downloads/design/Android_Design_Icons_20120814.zip">Action Bar Icon Pack</a>
 </p>
 
   </div>
@@ -91,8 +97,10 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="{@docRoot}downloads/design/Roboto_Hinted_20120823.zip">Roboto</a>
-  <a class="download-button" href="{@docRoot}downloads/design/Roboto_Specimen_Book_20111129.pdf">Specimen Book</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto ZIP']);"
+    href="{@docRoot}downloads/design/Roboto_Hinted_20120823.zip">Roboto</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto Specemin Book']);"
+    href="{@docRoot}downloads/design/Roboto_Specimen_Book_20111129.pdf">Specimen Book</a>
 </p>
 
   </div>
@@ -115,7 +123,8 @@
   <div class="layout-content-col span-4">
 
 <p>
-  <a class="download-button" href="{@docRoot}downloads/design/Android_Design_Color_Swatches_20120229.zip">Color Swatches</a>
+  <a class="download-button"  onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Color Swatches']);"
+    href="{@docRoot}downloads/design/Android_Design_Color_Swatches_20120229.zip">Color Swatches</a>
 </p>
 
   </div>
diff --git a/docs/html/design/patterns/actionbar.jd b/docs/html/design/patterns/actionbar.jd
index ba5b400..353cee6 100644
--- a/docs/html/design/patterns/actionbar.jd
+++ b/docs/html/design/patterns/actionbar.jd
@@ -293,7 +293,8 @@
 </p>
 <p>
 
-<a href="{@docRoot}downloads/design/Android_Design_Icons_20120229.zip">Download the Action Bar Icon Pack</a>
+<a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Action Bar Icons (@actionbar page)']);"
+   href="{@docRoot}downloads/design/Android_Design_Icons_20120814.zip">Download the Action Bar Icon Pack</a>
 
 </p>
 
diff --git a/docs/html/design/style/color.jd b/docs/html/design/style/color.jd
index 5be34ac..a7daacf 100644
--- a/docs/html/design/style/color.jd
+++ b/docs/html/design/style/color.jd
@@ -115,7 +115,8 @@
 
 <p>Blue is the standard accent color in Android's color palette. Each color has a corresponding darker
 shade that can be used as a complement when needed.</p>
-<p><a href="{@docRoot}downloads/design/Android_Design_Color_Swatches_20120229.zip">Download the swatches</a></p>
+<p><a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Color Swatches (@color page)']);"
+      href="{@docRoot}downloads/design/Android_Design_Color_Swatches_20120229.zip">Download the swatches</a></p>
 
 <img src="{@docRoot}design/media/color_spectrum.png">
 
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index 3ba3f71..ce11cf7 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -109,7 +109,8 @@
 
 </p>
 <p>
-<a href="{@docRoot}downloads/design/Android_Design_Icons_20120814.zip">Download the Action Bar Icon Pack</a>
+<a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Action Bar Icons (@iconography page)']);"
+   href="{@docRoot}downloads/design/Android_Design_Icons_20120814.zip">Download the Action Bar Icon Pack</a>
 </p>
 
 <div class="layout-content-row">
diff --git a/docs/html/design/style/typography.jd b/docs/html/design/style/typography.jd
index a699bed..427b8c6 100644
--- a/docs/html/design/style/typography.jd
+++ b/docs/html/design/style/typography.jd
@@ -18,8 +18,10 @@
 
     <img src="{@docRoot}design/media/typography_alphas.png">
 
-<p><a href="{@docRoot}downloads/design/Roboto_Hinted_20111129.zip">Download Roboto</a></p>
-<p><a href="{@docRoot}downloads/design/Roboto_Specimen_Book_20111129.pdf">Specimen Book</a></p>
+<p><a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto ZIP (@typography page)']);"
+      href="{@docRoot}downloads/design/Roboto_Hinted_20120823.zip">Download Roboto</a></p>
+<p><a onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Roboto Specimen Booke (@typography page)']);"
+      href="{@docRoot}downloads/design/Roboto_Specimen_Book_20111129.pdf">Specimen Book</a></p>
 
   </div>
 </div>
diff --git a/docs/html/distribute/googleplay/promote/badges.jd b/docs/html/distribute/googleplay/promote/badges.jd
index d6f15fb..90e8c0d 100644
--- a/docs/html/distribute/googleplay/promote/badges.jd
+++ b/docs/html/distribute/googleplay/promote/badges.jd
@@ -88,6 +88,9 @@
     $("#button-preview").html(linkStart + "apps/details?id=" + form["package"].value
             + imageStart + altText + imageSrc
             + selectedValue + imageEnd);
+            
+    // Send the event to Analytics
+    _gaq.push(['_trackEvent', 'Distribute', 'Create Google Play Badge', 'Package ' + selectedValue]);
   } else if (form["publisher"].value != "Example, Inc.") {
     $("#preview").show();
     $("#snippet").show().html(linkStartCode + "search?q=pub:" + form["publisher"].value
@@ -96,6 +99,9 @@
     $("#button-preview").html(linkStart + "search?q=pub:" + form["publisher"].value
             + imageStart + altText + imageSrc
             + selectedValue + imageEnd);
+   
+    // Send the event to Analytics
+    _gaq.push(['_trackEvent', 'Distribute', 'Create Google Play Badge', 'Publisher ' + selectedValue]);
   } else {
     alert("Please enter your package name or publisher name");
   }
@@ -199,8 +205,8 @@
 alt="Get it on Google Play (large)" /></label>
 </div>
 
-  <input type="button" onclick="return buildButton(this.parentNode)" value="Build my badge"
-style="padding:10px" />
+  <input onclick="return buildButton(this.parentNode);"
+    type="button" value="Build my badge" style="padding:10px" />
   <br/>
 </form>
 
diff --git a/docs/html/distribute/promote/device-art.jd b/docs/html/distribute/promote/device-art.jd
index af36625..93f772a 100644
--- a/docs/html/distribute/promote/device-art.jd
+++ b/docs/html/distribute/promote/device-art.jd
@@ -299,6 +299,8 @@
               g_currentFilename = data.name;
               g_currentImage = img;
               createFrame();
+              // Send the event to Analytics
+              _gaq.push(['_trackEvent', 'Distribute', 'Create Device Art', g_currentDevice.title]);
             });
           });
         });
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index d1c24df..62c054a 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -1,680 +1,806 @@
 page.title=Dialogs
-parent.title=User Interface
-parent.link=index.html
 @jd:body
 
+
+
 <div id="qv-wrapper">
   <div id="qv">
     <h2>In this document</h2>
+<ol>
+  <li><a href="#DialogFragment">Creating a Dialog Fragment</a></li>
+  <li><a href="#AlertDialog">Building an Alert Dialog</a>
     <ol>
-      <li><a href="#ShowingADialog">Showing a Dialog</a></li>
-      <li><a href="#DismissingADialog">Dismissing a Dialog</a></li>
-      <li><a href="#AlertDialog">Creating an AlertDialog</a>
-        <ol>
-          <li><a href="#AddingButtons">Adding buttons</a></li>
-          <li><a href="#AddingAList">Adding a list</a></li>
-        </ol>
-      </li>
-      <li><a href="#ProgressDialog">Creating a ProgressDialog</a>
-        <ol>
-          <li><a href="#ShowingAProgressBar">Showing a progress bar</a></li>
-        </ol>
-      </li>
-      <li><a href="#CustomDialog">Creating a Custom Dialog</a></li>
+      <li><a href="#AddingButtons">Adding buttons</a></li>
+      <li><a href="#AddingAList">Adding a list</a></li>
+      <li><a href="#CustomLayout">Creating a Custom Layout</a></li>
     </ol>
+  </li>
+  <li><a href="#PassingEvents">Passing Events Back to the Dialog's Host</a></li>
+  <li><a href="#ShowingADialog">Showing a Dialog</a></li>
+  <li><a href="#FullscreenDialog">Showing a Dialog Fullscreen or as an Embedded Fragment</a>
+    <ol>
+      <li><a href="#ActivityAsDialog">Showing an activity as a dialog on large screens</a></li>
+    </ol>
+  </li>
+  <li><a href="#DismissingADialog">Dismissing a Dialog</a></li>
+</ol>
 
     <h2>Key classes</h2>
     <ol>
-      <li>{@link android.app.Dialog}</li>
-      <li>{@link android.app.AlertDialog}</li>
       <li>{@link android.app.DialogFragment}</li>
-    </ol>
-
-    <h2>Related tutorials</h2>
-    <ol>
-      <li><a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Hello
-DatePicker</a></li>
-      <li><a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Hello
-TimePicker</a></li>
+      <li>{@link android.app.AlertDialog}</li>
     </ol>
     
     <h2>See also</h2>
     <ol>
-      <li><a href="{@docRoot}design/building-blocks/dialogs.html">Android Design: Dialogs</a></li>
+      <li><a href="{@docRoot}design/building-blocks/dialogs.html">Dialogs design guide</a></li>
+      <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> (Date/Time dialogs)</li>
     </ol>
   </div>
 </div>
 
-<p>A dialog is usually a small window that appears in front of the current Activity.
-The underlying Activity loses focus and the dialog accepts all user interaction. Dialogs are
-normally used for notifications that should interrupt the user and to perform short tasks that
-directly relate to the application in progress (such as a progress bar or a login prompt).</p>
-
-<p>The {@link android.app.Dialog} class is the base class for creating dialogs. However, you
-typically should not instantiate a {@link android.app.Dialog} directly. Instead, you should use one
-of the following subclasses:</p>
-<dl>
-  <dt>{@link android.app.AlertDialog}</dt>
-  <dd>A dialog that can manage zero, one, two, or three buttons, and/or a list of
-    selectable items that can include checkboxes or radio buttons. The AlertDialog 
-    is capable of constructing most dialog user interfaces and is the suggested dialog type.
-    See <a href="#AlertDialog">Creating an AlertDialog</a> below.</dd>
-  <dt>{@link android.app.ProgressDialog}</dt>
-  <dd>A dialog that displays a progress wheel or progress bar. Because it's an extension of
-    the AlertDialog, it also supports buttons.
-    See <a href="#ProgressDialog">Creating a ProgressDialog</a> below.</dd>
-  <dt>{@link android.app.DatePickerDialog}</dt>
-  <dd>A dialog that allows the user to select a date. See the 
-    <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Hello DatePicker</a> tutorial.</dd>
-  <dt>{@link android.app.TimePickerDialog}</dt>
-  <dd>A dialog that allows the user to select a time. See the 
-    <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Hello TimePicker</a> tutorial.</dd>
-</dl>
-
-<p>If you would like to customize your own dialog, you can extend the
-base {@link android.app.Dialog} object or any of the subclasses listed above and define a new layout.
-See the section on <a href="#CustomDialog">Creating a Custom Dialog</a> below.</p>
+<p>A dialog is a small window that prompts the user to
+make a decision or enter additional information. A dialog does not fill the screen and is
+normally used for modal events that require users to take an action before they can proceed.</p>
 
 <div class="note design">
 <p><strong>Dialog Design</strong></p>
-  <p>For design guidelines, read Android Design's <a
-href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a> guide.</p>
+  <p>For information about how to design your dialogs, including recommendations
+  for language, read the <a
+href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a> design guide.</p>
 </div>
 
+<img src="{@docRoot}images/ui/dialogs.png" />
+
+<p>The {@link android.app.Dialog} class is the base class for dialogs, but you
+should avoid instantiating {@link android.app.Dialog} directly.
+Instead, use one of the following subclasses:</p>
+<dl>
+  <dt>{@link android.app.AlertDialog}</dt>
+  <dd>A dialog that can show a title, up to three buttons, a list of
+    selectable items, or a custom layout.</dd>
+  <dt>{@link android.app.DatePickerDialog} or {@link android.app.TimePickerDialog}</dt>
+  <dd>A dialog with a pre-defined UI that allows the user to select a date or time.</dd>
+</dl>
+
+<div class="sidebox">
+<h2>Avoid ProgressDialog</h2>
+<p>Android includes another dialog class called
+{@link android.app.ProgressDialog} that shows a dialog with a progress bar. However, if you
+need to indicate loading or indeterminate progress, you should instead follow the design
+guidelines for <a href="{@docRoot}design/building-blocks/progress.html">Progress &amp;
+Activity</a> and use a {@link android.widget.ProgressBar} in your layout.</p>
+</div>
+
+<p>These classes define the style and structure for your dialog, but you should
+use a {@link android.support.v4.app.DialogFragment} as a container for your dialog.
+The {@link android.support.v4.app.DialogFragment} class provides all the controls you
+need to create your dialog and manage its appearance, instead of calling methods
+on the {@link android.app.Dialog} object.</p>
+
+<p>Using {@link android.support.v4.app.DialogFragment} to manage the dialog
+ensures that it correctly handles lifecycle events
+such as when the user presses the <em>Back</em> button or rotates the screen. The {@link
+android.support.v4.app.DialogFragment} class also allows you to reuse the dialog's UI as an
+embeddable component in a larger UI, just like a traditional {@link
+android.support.v4.app.Fragment} (such as when you want the dialog UI to appear differently
+on large and small screens).</p>
+
+<p>The following sections in this guide describe how to use a {@link
+android.support.v4.app.DialogFragment} in combination with an {@link android.app.AlertDialog}
+object. If you'd like to create a date or time picker, you should instead read the
+<a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a> guide.</p>
+
+<p class="note"><strong>Note:</strong>
+Because the {@link android.app.DialogFragment} class was originally added with
+Android 3.0 (API level 11), this document describes how to use the {@link
+android.support.v4.app.DialogFragment} class that's provided with the <a
+href="{@docRoot}tools/extras/support-library.html">Support Library</a>. By adding this library
+to your app, you can use {@link android.support.v4.app.DialogFragment} and a variety of other
+APIs on devices running Android 1.6 or higher. If the minimum version your app supports
+is API level 11 or higher, then you can use the framework version of {@link
+android.app.DialogFragment}, but be aware that the links in this document are for the support
+library APIs. When using the support library,
+be sure that you import <code>android.support.v4.app.DialogFragment</code>
+class and <em>not</em> <code>android.app.DialogFragment</code>.</p>
+
+
+<h2 id="DialogFragment">Creating a Dialog Fragment</h2>
+
+<p>You can accomplish a wide variety of dialog designs&mdash;including
+custom layouts and those described in the <a
+href="{@docRoot}design/building-blocks/dialogs.html">Dialogs</a>
+design guide&mdash;by extending
+{@link android.support.v4.app.DialogFragment} and creating a {@link android.app.AlertDialog}
+in the {@link android.support.v4.app.DialogFragment#onCreateDialog
+onCreateDialog()} callback method.</p>
+
+<p>For example, here's a basic {@link android.app.AlertDialog} that's managed within
+a {@link android.support.v4.app.DialogFragment}:</p>
+
+<pre>
+public class FireMissilesDialog extends DialogFragment {
+    &#64;Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Use the Builder class for convenient dialog construction
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        builder.setMessage(R.string.dialog_fire_missiles)
+               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
+                   public void onClick(DialogInterface dialog, int id) {
+                       // FIRE ZE MISSILES!
+                   }
+               })
+               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                   public void onClick(DialogInterface dialog, int id) {
+                       // User cancelled the dialog
+                   }
+               });
+        // Create the AlertDialog object and return it
+        return builder.create();
+    }
+}
+</pre>
+
+<div class="figure" style="width:290px;margin:0 0 0 20px">
+<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong>
+A dialog with a message and two action buttons.</p>
+</div>
+
+<p>Now, when you create an instance of this class and call {@link
+android.support.v4.app.DialogFragment#show show()} on that object, the dialog appears as
+shown in figure 1.</p>
+
+<p>The next section describes more about using the {@link android.app.AlertDialog.Builder}
+APIs to create the dialog.</p>
+
+<p>Depending on how complex your dialog is, you can implement a variety of other callback
+methods in the {@link android.support.v4.app.DialogFragment}, including all the basic
+<a href="{@docRoot}guide/components/fragments.html#Lifecycle">fragment lifecycle methods</a>.
+
+
+
+
+
+<h2 id="AlertDialog">Building an Alert Dialog</h2>
+
+
+<p>The {@link android.app.AlertDialog} class allows you to build a variety of dialog designs and
+is often the only dialog class you'll need.
+As shown in figure 2, there are three regions of an alert dialog:</p>
+
+<div class="figure" style="width:311px;margin-top:0">
+<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0"/>
+<p class="img-caption"><strong>Figure 2.</strong> The layout of a dialog.</p>
+</div>
+
+<ol>
+<li><b>Title</b>
+  <p>This is optional and should be used only when the content area
+  is occupied by a detailed message, a list, or custom layout. If you need to state
+  a simple message or question (such as the dialog in figure 1), you don't need a title.</li>
+<li><b>Content area</b>
+  <p>This can display a message, a list, or other custom layout.</p></li>
+<li><b>Action buttons</b>
+  <p>There should be no more than three action buttons in a dialog.</p></li>
+</ol>
+
+<p>The {@link android.app.AlertDialog.Builder}
+class provides APIs that allow you to create an {@link android.app.AlertDialog}
+with these kinds of content, including a custom layout.</p>
+
+<p>To build an {@link android.app.AlertDialog}:</p>
+
+<pre>
+<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b>
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+<b>// 2. Chain together various setter methods to set the dialog characteristics</b>
+builder.setMessage(R.string.dialog_message)
+       .setTitle(R.string.dialog_title);
+
+<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b>
+AlertDialog dialog = builder.create();
+</pre>
+
+<p>The following topics show how to define various dialog attributes using the
+{@link android.app.AlertDialog.Builder} class.</p>
+
+
+
+
+<h3 id="AddingButtons">Adding buttons</h3>
+
+<p>To add action buttons like those in figure 2,
+call the {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} and
+{@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()} methods:</p>
+
+<pre style="clear:right">
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+// Add the buttons
+builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+           public void onClick(DialogInterface dialog, int id) {
+               // User clicked OK button
+           }
+       });
+builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+           public void onClick(DialogInterface dialog, int id) {
+               // User cancelled the dialog
+           }
+       });
+// Set other dialog properties
+...
+
+// Create the AlertDialog
+AlertDialog dialog = builder.create();
+</pre>
+
+<p>The <code>set...Button()</code> methods require a title for the button (supplied
+by a <a href="{@docRoot}guide/topics/resources/string-resource.html">string resource</a>) and a 
+{@link android.content.DialogInterface.OnClickListener} that defines the action to take 
+when the user presses the button.</p>
+
+<p>There are three different action buttons you can add:</p>
+<dl>
+  <dt>Positive</dt>
+  <dd>You should use this to accept and continue with the action (the "OK" action).</dd>
+  <dt>Negative</dt>
+  <dd>You should use this to cancel the action.</dd>
+  <dt>Neutral</dt>
+  <dd>You should use this when the user may not want to proceed with the action,
+  but doesn't necessarily want to cancel. It appears between the positive and negative
+  buttons. For example, the action might be "Remind me later."</dd> 
+</dl>
+
+<p>You can add only one of each button type to an {@link
+android.app.AlertDialog}. That is, you cannot have more than one "positive" button.</p>
+
+
+
+<div class="figure" style="width:290px;margin:0 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_list.png" alt="" />
+<p class="img-caption"><strong>Figure 3.</strong>
+A dialog with a title and list.</p>
+</div>
+
+<h3 id="AddingAList">Adding a list</h3>
+
+<p>There are three kinds of lists available with the {@link android.app.AlertDialog} APIs:</p>
+<ul>
+<li>A traditional single-choice list</li>
+<li>A persistent single-choice list (radio buttons)</li>
+<li>A persistent multiple-choice list (checkboxes)</li>
+</ul>
+
+<p>To create a single-choice list like the one in figure 3, 
+use the {@link android.app.AlertDialog.Builder#setItems setItems()} method:</p>
+
+<pre style="clear:right">
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+    builder.setTitle(R.string.pick_color);
+           .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
+               public void onClick(DialogInterface dialog, int which) {
+               // The 'which' argument contains the index position
+               // of the selected item
+           }
+    });
+    return builder.create();
+}
+</pre>
+
+<p>Because the list appears in the dialog's content area,
+the dialog cannot show both a message and a list and you should set a title for the
+dialog with {@link android.app.AlertDialog.Builder#setTitle setTitle()}. 
+To specify the items for the list, call {@link
+android.app.AlertDialog.Builder#setItems setItems()}, passing an array.
+Alternatively, you can specify a list using {@link
+android.app.AlertDialog.Builder#setAdapter setAdapter()}. This allows you to back the list
+with dynamic data (such as from a database) using a {@link android.widget.ListAdapter}.</p>
+
+<p>If you choose to back your list with a {@link android.widget.ListAdapter},
+always use a {@link android.support.v4.content.Loader} so that the content loads
+asynchronously. This is described further in
+<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts
+with an Adapter</a> and the <a href="{@docRoot}guide/components/loaders.html">Loaders</a>
+guide.</p>
+
+<p class="note"><strong>Note:</strong> By default, touching a list item dismisses the dialog,
+unless you're using one of the following persistent choice lists.</p>
+
+<div class="figure" style="width:290px;margin:-30px 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_checkboxes.png" />
+<p class="img-caption"><strong>Figure 4.</strong>
+A list of multiple-choice items.</p>
+</div>
+
+
+<h4 id="Checkboxes">Adding a persistent multiple-choice or single-choice list</h4>
+
+<p>To add a list of multiple-choice items (checkboxes) or 
+single-choice items (radio buttons), use the
+{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String,
+DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} or 
+{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 
+setSingleChoiceItems()} methods, respectively.</p>
+
+<p>For example, here's how you can create a multiple-choice list like the
+one shown in figure 4 that saves the selected
+items in an {@link java.util.ArrayList}:</p>
+
+<pre style="clear:right">
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+    mSelectedItems = new ArrayList();  // Where we track the selected items
+    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+    // Set the dialog title
+    builder.setTitle(R.string.pick_toppings)
+    // Specify the list array, the items to be selected by default (null for none),
+    // and the listener through which to receive callbacks when items are selected
+           .setMultiChoiceItems(R.array.toppings, null,
+                      new DialogInterface.OnMultiChoiceClickListener() {
+               &#64;Override
+               public void onClick(DialogInterface dialog, int which,
+                       boolean isChecked) {
+                   if (isChecked) {
+                       // If the user checked the item, add it to the selected items
+                       mSelectedItems.add(which);
+                   } else if (mSelectedItems.contains(which)) {
+                       // Else, if the item is already in the array, remove it 
+                       mSelectedItems.remove(Integer.valueOf(which));
+                   }
+               }
+           })
+    // Set the action buttons
+           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+               &#64;Override
+               public void onClick(DialogInterface dialog, int id) {
+                   // User clicked OK, so save the mSelectedItems results somewhere
+                   // or return them to the component that opened the dialog
+                   ...
+               }
+           })
+           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+               &#64;Override
+               public void onClick(DialogInterface dialog, int id) {
+                   ...
+               }
+           });
+
+    return builder.create();
+}
+</pre>
+
+<p>Although both a traditional list and a list with radio buttons
+provide a "single choice" action, you should use {@link
+android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 
+setSingleChoiceItems()} if you want to persist the user's choice.
+That is, if opening the dialog again later should indicate what the user's current choice is,
+then you create a list with radio buttons.</p>
+
+
+
+
+
+<h3 id="CustomLayout">Creating a Custom Layout</h3>
+
+<div class="figure" style="width:290px;margin:-30px 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_custom.png" alt="" />
+<p class="img-caption"><strong>Figure 5.</strong> A custom dialog layout.</p>
+</div>
+
+<p>If you want a custom layout in a dialog, create a layout and add it to an
+{@link android.app.AlertDialog} by calling {@link
+android.app.AlertDialog.Builder#setView setView()} on your {@link
+android.app.AlertDialog.Builder} object.</p>
+
+<p>By default, the custom layout fills the dialog window, but you can still
+use {@link android.app.AlertDialog.Builder} methods to add buttons and a title.</p>
+
+<p>For example, here's the layout file for the dialog in Figure 5:</p>
+
+<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p>
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    &lt;ImageView
+        android:src="@drawable/header_logo"
+        android:layout_width="match_parent"
+        android:layout_height="64dp"
+        android:scaleType="center"
+        android:background="#FFFFBB33"
+        android:contentDescription="@string/app_name" />
+    &lt;EditText
+        android:id="@+id/username"
+        android:inputType="textEmailAddress"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:layout_marginLeft="4dp"
+        android:layout_marginRight="4dp"
+        android:layout_marginBottom="4dp"
+        android:hint="@string/username" />
+    &lt;EditText
+        android:id="@+id/password"
+        android:inputType="textPassword"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:layout_marginLeft="4dp"
+        android:layout_marginRight="4dp"
+        android:layout_marginBottom="16dp"
+        android:fontFamily="sans-serif"
+        android:hint="@string/password"/>
+&lt;/LinearLayout>
+</pre>
+
+<p class="note"><strong>Tip:</strong> By default, when you set an {@link android.widget.EditText}
+element to use the {@code "textPassword"} input type, the font family is set to monospace, so
+you should change its font family to {@code "sans-serif"} so that both text fields use
+a matching font style.</p>
+
+<p>To inflate the layout in your {@link android.support.v4.app.DialogFragment},
+get a {@link android.view.LayoutInflater} with 
+{@link android.app.Activity#getLayoutInflater()} and call
+{@link android.view.LayoutInflater#inflate inflate()}, where the first parameter
+is the layout resource ID and the second parameter is a parent view for the layout.
+You can then call {@link android.app.AlertDialog#setView setView()}
+to place the layout in the dialog.</p>
+
+<pre>
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+    // Get the layout inflater
+    LayoutInflater inflater = getActivity().getLayoutInflater();
+
+    // Inflate and set the layout for the dialog
+    // Pass null as the parent view because its going in the dialog layout
+    builder.setView(inflater.inflate(R.layout.dialog_signin, null))
+    // Add action buttons
+           .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
+               &#64;Override
+               public void onClick(DialogInterface dialog, int id) {
+                   // sign in the user ...
+               }
+           })
+           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+               public void onClick(DialogInterface dialog, int id) {
+                   NoticeDialog.this.getDialog().cancel();
+               }
+           });      
+    return builder.create();
+}
+</pre>
+
+<div class="note">
+<p><strong>Tip:</strong> If you want a custom dialog,
+you can instead display an {@link android.app.Activity} as a dialog
+instead of using the {@link android.app.Dialog} APIs. Simply create an activity and set its theme to
+{@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog}
+in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> manifest element:</p>
+
+<pre>
+&lt;activity android:theme="&#64;android:style/Theme.Holo.Dialog" >
+</pre>
+<p>That's it. The activity now displays in a dialog window instead of fullscreen.</p>
+</div>
+
+
+
+<h2 id="PassingEvents">Passing Events Back to the Dialog's Host</h2>
+
+<p>When the user touches one of the dialog's action buttons or selects an item from its list,
+your {@link android.support.v4.app.DialogFragment} might perform the necessary
+action itself, but often you'll want to deliver the event to the activity or fragment that
+opened the dialog. To do this, define an interface with a method for each type of click event,
+then implement that interface in the host component that will
+receive the action events from the dialog.</p>
+
+<p>For example, here's a {@link android.support.v4.app.DialogFragment} that defines an
+interface through which it delivers the events back to the host activity:</p>
+
+<pre>
+public class NoticeDialog extends DialogFragment {
+    
+    /* The activity that creates an instance of this dialog fragment must
+     * implement this interface in order to receive event callbacks.
+     * Each method passes the DialogFragment in case the host needs to query it. */
+    public interface NoticeDialogListener {
+        public void onDialogPositiveClick(DialogFragment dialog);
+        public void onDialogNegativeClick(DialogFragment dialog);
+    }
+    
+    // Use this instance of the interface to deliver action events
+    static NoticeDialogListener mListener;
+        
+    /* Call this to instantiate a new NoticeDialog.
+     * @param activity  The activity hosting the dialog, which must implement the
+     *                  NoticeDialogListener to receive event callbacks.
+     * @returns A new instance of NoticeDialog.
+     * @throws  ClassCastException if the host activity does not
+     *          implement NoticeDialogListener
+     */
+    public static NoticeDialog newInstance(Activity activity) {
+        // Verify that the host activity implements the callback interface
+        try {
+            // Instantiate the NoticeDialogListener so we can send events with it
+            mListener = (NoticeDialogListener) activity;
+        } catch (ClassCastException e) {
+            // The activity doesn't implement the interface, throw exception
+            throw new ClassCastException(activity.toString()
+                    + " must implement NoticeDialogListener");
+        }
+        NoticeDialog frag = new NoticeDialog();
+        return frag;
+    }
+    
+    ...
+}
+</pre>
+
+<p>The activity hosting the dialog creates and shows an instance of the dialog
+by calling {@code NoticeDialog.newInstance()} and receives the dialog's
+events through an implementation of the {@code NoticeDialogListener} interface:</p>
+
+<pre>
+public class MainActivity extends FragmentActivity
+                          implements NoticeDialog.NoticeDialogListener{
+    ...
+    
+    public void showNoticeDialog() {
+        // Create an instance of the dialog fragment and show it
+        DialogFragment dialog = NoticeDialog.newInstance(this);
+        dialog.show(getSupportFragmentManager(), "NoticeDialog");
+    }
+
+    &#64;Override
+    public void onDialogPositiveClick(DialogFragment dialog) {
+        // User touched the dialog's positive button
+        ...
+    }
+
+    &#64;Override
+    public void onDialogNegativeClick(DialogFragment dialog) {
+        // User touched the dialog's negative button
+        ...
+    }
+}
+</pre>
+
+<p>Because the host activity implements the {@code NoticeDialogListener}&mdash;which is
+enforced by the {@code newInstance()} method shown above&mdash;the dialog fragment can use the
+interface callback methods to deliver click events to the activity:</p>
+
+<pre>
+public class NoticeDialog extends DialogFragment {
+    ...
+
+    &#64;Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Build the dialog and set up the button click handlers
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        builder.setMessage(R.string.dialog_fire_missiles)
+               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
+                   public void onClick(DialogInterface dialog, int id) {
+                       // Send the positive button event back to the host activity
+                       mListener.onDialogPositiveClick(NoticeDialog.this);
+                   }
+               })
+               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                   public void onClick(DialogInterface dialog, int id) {
+                       // Send the negative button event back to the host activity
+                       mListener.onDialogPositiveClick(NoticeDialog.this);
+                   }
+               });
+        return builder.create();
+    }
+}
+</pre>
+
+
+
 
 
 <h2 id="ShowingADialog">Showing a Dialog</h2>
 
-<p>A dialog is always created and displayed as a part of an {@link android.app.Activity}. 
-You should normally create dialogs from within your Activity's
-{@link android.app.Activity#onCreateDialog(int)} callback method. 
-When you use this callback, the Android system automatically manages the state of 
-each dialog and hooks them to the Activity, effectively making it the "owner" of each dialog.
-As such, each dialog inherits certain properties from the Activity. For example, when a dialog
-is open, the Menu key reveals the options menu defined for the Activity and the volume
-keys modify the audio stream used by the Activity.</p>
+<p>When you want to show your dialog, create an instance of your {@link
+android.support.v4.app.DialogFragment} and call {@link android.support.v4.app.DialogFragment#show
+show()}, passing the {@link android.support.v4.app.FragmentManager} and a tag name
+for the dialog fragment.</p>
 
-<p class="note"><strong>Note:</strong> If you decide to create a dialog outside of the 
-<code>onCreateDialog()</code> method, it will not be attached to an Activity. You can, however,
-attach it to an Activity with {@link android.app.Dialog#setOwnerActivity(Activity)}.</p>
+<p>You can get the {@link android.support.v4.app.FragmentManager} by calling
+{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} from
+the {@link android.support.v4.app.FragmentActivity} or {@link
+android.support.v4.app.Fragment#getFragmentManager()} from a {@link
+android.support.v4.app.Fragment}. For example:</p>
 
-<p>When you want to show a dialog, call 
-{@link android.app.Activity#showDialog(int)} and pass it an integer that uniquely identifies the 
-dialog that you want to display.</p>
-
-<p>When a dialog is requested for the first time, Android calls 
-{@link android.app.Activity#onCreateDialog(int)} from your Activity, which is
-where you should instantiate the {@link android.app.Dialog}. This callback method
-is passed the same ID that you passed to {@link android.app.Activity#showDialog(int)}. 
-After you create the Dialog, return the object at the end of the method.</p>
-
-<p>Before the dialog is displayed, Android also calls the optional callback method
-{@link android.app.Activity#onPrepareDialog(int,Dialog)}. Define this method if you want to change
-any properties of the dialog each time it is opened. This method is called
-every time a dialog is opened, whereas {@link android.app.Activity#onCreateDialog(int)} is only
-called the very first time a dialog is opened. If you don't define 
-{@link android.app.Activity#onPrepareDialog(int,Dialog) onPrepareDialog()}, then the dialog will 
-remain the same as it was the previous time it was opened. This method is also passed the dialog's
-ID, along with the Dialog object you created in {@link android.app.Activity#onCreateDialog(int)
-onCreateDialog()}.</p>
-
-<p>The best way to define the {@link android.app.Activity#onCreateDialog(int)} and 
-{@link android.app.Activity#onPrepareDialog(int,Dialog)} callback methods is with a 
-<em>switch</em> statement that checks the <var>id</var> parameter that's passed into the method. 
-Each <em>case</em> should check for a unique dialog ID and then create and define the respective Dialog.
-For example, imagine a game that uses two different dialogs: one to indicate that the game
-has paused and another to indicate that the game is over. First, define an integer ID for
-each dialog:</p>
 <pre>
-static final int DIALOG_PAUSED_ID = 0;
-static final int DIALOG_GAMEOVER_ID = 1;
-</pre>
-
-<p>Then, define the {@link android.app.Activity#onCreateDialog(int)} callback with a 
-switch case for each ID:</p>
-<pre>
-protected Dialog onCreateDialog(int id) {
-    Dialog dialog;
-    switch(id) {
-    case DIALOG_PAUSED_ID:
-        // do the work to define the pause Dialog
-        break;
-    case DIALOG_GAMEOVER_ID:
-        // do the work to define the game over Dialog
-        break;
-    default:
-        dialog = null;
-    }
-    return dialog;
+public void confirmFireMissiles() {
+    DialogFragment newFragment = FireMissilesDialog.newInstance(this);
+    newFragment.show(getSupportFragmentManager(), "missiles");
 }
 </pre>
 
-<p class="note"><strong>Note:</strong> In this example, there's no code inside
-the case statements because the procedure for defining your Dialog is outside the scope
-of this section. See the section below about <a href="#AlertDialog">Creating an AlertDialog</a>,
-offers code suitable for this example.</p>
+<p>The second argument, {@code "missiles"}, is a unique tag name that the system uses to save
+and restore the fragment state when necessary. The tag also allows you to get a handle to
+the fragment by calling {@link android.support.v4.app.FragmentManager#findFragmentByTag
+findFragmentByTag()}.</p>
 
-<p>When it's time to show one of the dialogs, call {@link android.app.Activity#showDialog(int)}
-with the ID of a dialog:</p>
+
+
+
+<h2 id="FullscreenDialog">Showing a Dialog Fullscreen or as an Embedded Fragment</h2>
+
+<p>You might have a UI design in which you want a piece of the UI to appear as a dialog in some
+situations, but as a full screen or embedded fragment in others (perhaps depending on whether
+the device is a large screen or small screen). The {@link android.support.v4.app.DialogFragment}
+class offers you this flexibility because it can still behave as an embeddable {@link
+android.support.v4.app.Fragment}.</p>
+
+<p>However, you cannot use {@link android.app.AlertDialog.Builder AlertDialog.Builder}
+or other {@link android.app.Dialog} objects to build the dialog in this case. If
+you want the {@link android.support.v4.app.DialogFragment} to be
+embeddable, you must define the dialog's UI in a layout, then load the layout in the
+{@link android.support.v4.app.DialogFragment#onCreateView
+onCreateView()} callback.</p>
+
+<p>Here's an example {@link android.support.v4.app.DialogFragment} that can appear as either a
+dialog or an embeddable fragment (using a layout named <code>purchase_items.xml</code>):</p>
+
 <pre>
-showDialog(DIALOG_PAUSED_ID);
+public class CustomLayoutDialog extends DialogFragment {
+    /** The system calls this to get the DialogFragment's layout, regardless
+        of whether it's being displayed as a dialog or an embedded fragment. */
+    &#64;Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        // Inflate the layout to use as dialog or embedded fragment
+        return inflater.inflate(R.layout.purchase_items, container, false);
+    }
+  
+    /** The system calls this only when creating the layout in a dialog. */
+    &#64;Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // The only reason you might override this method when using onCreateView() is
+        // to modify any dialog characteristics. For example, the dialog includes a
+        // title by default, but your custom layout might not need it. So here you can
+        // remove the dialog title, but you must call the superclass to get the Dialog.
+        Dialog dialog = super.onCreateDialog(savedInstanceState);
+        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+        return dialog;
+    }
+}
 </pre>
 
+<p>And here's some code that decides whether to show the fragment as a dialog
+or a fullscreen UI, based on the screen size:</p>
+
+<pre>
+public void showDialog() {
+    FragmentManager fragmentManager = getSupportFragmentManager();
+    CustomLayoutDialog newFragment = new CustomLayoutDialog();
+    
+    if (mIsLargeLayout) {
+        // The device is using a large layout, so show the fragment as a dialog
+        newFragment.show(fragmentManager, "dialog");
+    } else {
+        // The device is smaller, so show the fragment fullscreen
+        FragmentTransaction transaction = fragmentManager.beginTransaction();
+        // For a little polish, specify a transition animation
+        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+        // To make it fullscreen, use the 'content' root view as the container
+        // for the fragment, which is always the root view for the activity
+        transaction.add(android.R.id.content, newFragment)
+                   .addToBackStack(null).commit();
+    }
+}
+</pre>
+
+<p>For more information about performing fragment transactions, see the
+<a href="{@docRoot}guide/components/fragments.html">Fragments</a> guide.</p>
+
+<p>In this example, the <code>mIsLargeLayout</code> boolean specifies whether the current device
+should use the app's large layout design (and thus show this fragment as a dialog, rather
+than fullscreen). The best way to set this kind of boolean is to declare a
+<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">bool resource value</a>
+with an <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources"
+>alternative resource</a> value for different screen sizes. For example, here are two
+versions of the bool resource for different screen sizes:</p>
+
+<p class="code-caption">res/values/bools.xml</p>
+<pre>
+&lt;!-- Default boolean values -->
+&lt;resources>
+    &lt;bool name="large_layout">false&lt;/bool>
+&lt;/resources>
+</pre>
+
+<p class="code-caption">res/values-large/bools.xml</p>
+<pre>
+&lt;!-- Large screen boolean values -->
+&lt;resources>
+    &lt;bool name="large_layout">true&lt;/bool>
+&lt;/resources>
+</pre>
+
+<p>Then you can initialize the {@code mIsLargeLayout} value during the activity's
+{@link android.app.Activity#onCreate onCreate()} method:</p>
+
+<pre>
+boolean mIsLargeLayout;
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    setContentView(R.layout.activity_main);
+
+    mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
+}
+</pre>
+
+
+
+<h3 id="ActivityAsDialog">Showing an activity as a dialog on large screens</h3>
+
+<p>Instead of showing a dialog as a fullscreen UI when on small screens, you can accomplish
+the same result by showing an {@link android.app.Activity} as a dialog when on
+large screens. Which approach you choose depends on your app design, but
+showing an activity as a dialog is often useful when your app is already designed for small
+screens and you'd like to improve the experience on tablets by showing a short-lived activity
+as a dialog.</p>
+
+<p>To show an activity as a dialog only when on large screens,
+apply the {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge}
+theme to the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> manifest element:</p>
+
+<pre>
+&lt;activity android:theme="&#64;android:style/Theme.Holo.DialogWhenLarge" >
+</pre>
+
+<p>For more information about styling your activities with themes, see the <a
+href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a> guide.</p>
+
+
 
 <h2 id="DismissingADialog">Dismissing a Dialog</h2>
 
-<p>When you're ready to close your dialog, you can dismiss it by calling
-{@link android.app.Dialog#dismiss()} on the Dialog object.
-If necessary, you can also call {@link android.app.Activity#dismissDialog(int)} from the
-Activity, which effectively calls {@link android.app.Dialog#dismiss()} on the 
-Dialog for you.</p>
+<p>When the user touches any of the action buttons created with an
+{@link android.app.AlertDialog.Builder}, the system dismisses the dialog for you.</p>
 
-<p>If you are using {@link android.app.Activity#onCreateDialog(int)} to manage the state
-of your dialogs (as discussed in the previous section), then every time your dialog is
-dismissed, the state of the Dialog
-object is retained by the Activity. If you decide that you will no longer need this object or 
-it's important that the state is cleared, then you should call
-{@link android.app.Activity#removeDialog(int)}. This will remove any internal references
-to the object and if the dialog is showing, it will dismiss it.</p>
+<p>The system also dismisses the dialog when the user touches an item in a dialog list, except
+when the list uses radio buttons or checkboxes. Otherwise, you can manually dismiss your dialog
+by calling {@link android.support.v4.app.DialogFragment#dismiss()} on your {@link
+android.support.v4.app.DialogFragment}.</p>
 
-<h3>Using dismiss listeners</h3>
+<p>In case you need to perform certain
+actions when the dialog goes away, you can implement the {@link
+android.support.v4.app.DialogFragment#onDismiss onDismiss()} method in your {@link
+android.support.v4.app.DialogFragment}.</p>
 
-<p>If you'd like your application to perform some procedures the moment that a dialog is dismissed, 
-then you should attach an on-dismiss listener to your Dialog.</p>
+<p>You can also <em>cancel</em> a dialog. This is a special event that indicates the user
+explicitly left the dialog without completing the task. This occurs if the user presses the 
+<em>Back</em> button, touches the screen outside the dialog area,
+or if you explicitly call {@link android.app.Dialog#cancel()} on the {@link
+android.app.Dialog} (such as in response to a "Cancel" button in the dialog).</p>
 
-<p>First define the {@link android.content.DialogInterface.OnDismissListener} interface.
-This interface has just one method,
-{@link android.content.DialogInterface.OnDismissListener#onDismiss(DialogInterface)}, which
-will be called when the dialog is dismissed.
-Then simply pass your OnDismissListener implementation to 
-{@link android.app.Dialog#setOnDismissListener(DialogInterface.OnDismissListener)
-setOnDismissListener()}.</p>
+<p>As shown in the example above, you can respond to the cancel event by implementing
+{@link android.support.v4.app.DialogFragment#onCancel onCancel()} in your {@link
+android.support.v4.app.DialogFragment} class.</p>
 
-<p>However, note that dialogs can also be "cancelled." This is a special case that indicates
-the dialog was explicitly cancelled by the user. This will occur if the user presses the 
-"back" button to close the dialog, or if the dialog explicitly calls {@link android.app.Dialog#cancel()}
-(perhaps from a "Cancel" button in the dialog). When a dialog is cancelled,
-the OnDismissListener will still be notified, but if you'd like to be informed that the dialog
-was explicitly cancelled (and not dismissed normally), then you should register 
-an {@link android.content.DialogInterface.OnCancelListener} with
-{@link android.app.Dialog#setOnCancelListener(DialogInterface.OnCancelListener)
-setOnCancelListener()}.</p>
-
-
-<h2 id="AlertDialog">Creating an AlertDialog</h2>
-
-<p>An {@link android.app.AlertDialog} is an extension of the {@link android.app.Dialog}
-class. It is capable of constructing most dialog user interfaces and is the suggested dialog type.
-You should use it for dialogs that use any of the following features:</p>
-<ul>
-  <li>A title</li>
-  <li>A text message</li>
-  <li>One, two, or three buttons</li>
-  <li>A list of selectable items (with optional checkboxes or radio buttons)</li>
-</ul>
-
-<p>To create an AlertDialog, use the {@link android.app.AlertDialog.Builder} subclass.
-Get a Builder with {@link android.app.AlertDialog.Builder#AlertDialog.Builder(Context)} and
-then use the class's public methods to define all of the
-AlertDialog properties. After you're done with the Builder, retrieve the 
-AlertDialog object with {@link android.app.AlertDialog.Builder#create()}.</p>
-
-<p>The following topics show how to define various properties of the AlertDialog using the
-AlertDialog.Builder class. If you use any of the following sample code inside your 
-{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method, 
-you can return the resulting Dialog object to display the dialog.</p>
-
-
-<h3 id="AddingButtons">Adding buttons</h3>
-
-<img src="{@docRoot}images/dialog_buttons.png" alt="" style="float:right" />
-
-<p>To create an AlertDialog with side-by-side buttons like the one shown in the screenshot to the right,
-use the <code>set...Button()</code> methods:</p>
-
-<pre>
-AlertDialog.Builder builder = new AlertDialog.Builder(this);
-builder.setMessage("Are you sure you want to exit?")
-       .setCancelable(false)
-       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
-           public void onClick(DialogInterface dialog, int id) {
-                MyActivity.this.finish();
-           }
-       })
-       .setNegativeButton("No", new DialogInterface.OnClickListener() {
-           public void onClick(DialogInterface dialog, int id) {
-                dialog.cancel();
-           }
-       });
-AlertDialog alert = builder.create();
-</pre>
-
-<p>First, add a message for the dialog with 
-{@link android.app.AlertDialog.Builder#setMessage(CharSequence)}. Then, begin
-method-chaining and set the dialog
-to be <em>not cancelable</em> (so the user cannot close the dialog with the back button)
-with {@link android.app.AlertDialog.Builder#setCancelable(boolean)}. For each button, 
-use one of the <code>set...Button()</code> methods, such as
-{@link android.app.AlertDialog.Builder#setPositiveButton(CharSequence,DialogInterface.OnClickListener)
-setPositiveButton()}, that accepts the name for the button and a 
-{@link android.content.DialogInterface.OnClickListener} that defines the action to take 
-when the user selects the button.</p>
-
-<p class="note"><strong>Note:</strong> You can only add one of each button type to the
-AlertDialog. That is, you cannot have more than one "positive" button. This limits the number
-of possible buttons to three: positive, neutral, and negative. These names are technically irrelevant to the
-actual functionality of your buttons, but should help you keep track of which one does what.</p>
-
-
-<h3 id="AddingAList">Adding a list</h3>
-
-<img src="{@docRoot}images/dialog_list.png" alt="" style="float:right" />
-
-<p>To create an AlertDialog with a list of selectable items like the one shown to the right, 
-use the <code>setItems()</code> method:</p>
-
-<pre>
-final CharSequence[] items = {"Red", "Green", "Blue"};
-
-AlertDialog.Builder builder = new AlertDialog.Builder(this);
-builder.setTitle("Pick a color");
-builder.setItems(items, new DialogInterface.OnClickListener() {
-    public void onClick(DialogInterface dialog, int item) {
-        Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
-    }
-});
-AlertDialog alert = builder.create();
-</pre>
-
-<p>First, add a title to the dialog with 
-{@link android.app.AlertDialog.Builder#setTitle(CharSequence)}. 
-Then, add a list of selectable items with
-{@link android.app.AlertDialog.Builder#setItems(CharSequence[],DialogInterface.OnClickListener)
-setItems()}, which accepts the array of items to display and a 
-{@link android.content.DialogInterface.OnClickListener} that defines the action to take 
-when the user selects an item.</p>
-
-
-<h4>Adding checkboxes and radio buttons</h4>
-
-<img src="{@docRoot}images/dialog_singlechoicelist.png" alt="" style="float:right" />
-
-<p>To create a list of multiple-choice items (checkboxes) or 
-single-choice items (radio buttons) inside the dialog, use the
-{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String,
-DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} and 
-{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 
-setSingleChoiceItems()} methods, respectively.
-If you create one of these selectable lists in the
-{@link android.app.Activity#onCreateDialog(int) onCreateDialog()} callback method,
-Android manages the state of the list for you. As long as the Activity is active, 
-the dialog remembers the items that were previously selected, but when the user exits the
-Activity, the selection is lost.
-
-<p class="note"><strong>Note:</strong> To save the selection when the user leaves or
-pauses the Activity, you must properly save and restore the setting throughout
-the <a href="{@docRoot}guide/components/activities.html#Lifecycle">activity lifecycle</a>. 
-To permanently save the selections, even when the Activity process is completely shutdown, 
-you need to save the settings
-with one of the <a href="{@docRoot}guide/topics/data/data-storage.html">Data
-Storage</a> techniques.</p>
-
-<p>To create an AlertDialog with a list of single-choice items like the one shown to the right,
-use the same code from the previous example, but replace the <code>setItems()</code> method with
-{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) 
-setSingleChoiceItems()}:</p>
-
-<pre>
-final CharSequence[] items = {"Red", "Green", "Blue"};
-
-AlertDialog.Builder builder = new AlertDialog.Builder(this);
-builder.setTitle("Pick a color");
-builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
-    public void onClick(DialogInterface dialog, int item) {
-        Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
-    }
-});
-AlertDialog alert = builder.create();
-</pre>
-
-<p>The second parameter in the
-{@link android.app.AlertDialog.Builder#setSingleChoiceItems(CharSequence[],int,DialogInterface.OnClickListener)
-setSingleChoiceItems()} method is an integer value for the <var>checkedItem</var>, which indicates the 
-zero-based list position of the default selected item. Use "-1" to indicate that no item should be 
-selected by default.</p>
-
-
-<h2 id="ProgressDialog">Creating a ProgressDialog</h2>
-
-<img src="{@docRoot}images/dialog_progress_spinning.png" alt="" style="float:right" />
-
-<p>A {@link android.app.ProgressDialog} is an extension of the {@link android.app.AlertDialog}
-class that can display a progress animation in the form of a spinning wheel, for a task with
-progress that's undefined, or a progress bar, for a task that has a defined progression.
-The dialog can also provide buttons, such as one to cancel a download.</p>
-
-<p>Opening a progress dialog can be as simple as calling 
-{@link android.app.ProgressDialog#show(Context,CharSequence,CharSequence)
-ProgressDialog.show()}. For example, the progress dialog shown to the right can be 
-easily achieved without managing the dialog through the 
-{@link android.app.Activity#onCreateDialog(int)} callback,
-as shown here:</p>
-
-<pre>
-ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", 
-                        "Loading. Please wait...", true);
-</pre>
-
-<p>The first parameter is the application {@link android.content.Context}, 
-the second is a title for the dialog (left empty), the third is the message, 
-and the last parameter is whether the progress
-is indeterminate (this is only relevant when creating a progress bar, which is
-discussed in the next section).
-</p>
-
-<p>The default style of a progress dialog is the spinning wheel.
-If you want to create a progress bar that shows the loading progress with granularity,
-some more code is required, as discussed in the next section.</p>
-
-
-<h3 id="ShowingAProgressBar">Showing a progress bar</h3>
-
-<img src="/images/dialog_progress_bar.png" alt="" style="float:right" />
-
-<p>To show the progression with an animated progress bar:</p>
-
-<ol>
-  <li>Initialize the 
-    ProgressDialog with the class constructor, 
-    {@link android.app.ProgressDialog#ProgressDialog(Context)}.</li>
-  <li>Set the progress style to "STYLE_HORIZONTAL" with 
-    {@link android.app.ProgressDialog#setProgressStyle(int)} and 
-    set any other properties, such as the message.</li>
-  <li>When you're ready to show the dialog, call 
-    {@link android.app.Dialog#show()} or return the ProgressDialog from the  
-    {@link android.app.Activity#onCreateDialog(int)} callback.</li>
-  <li>You can increment the amount of progress displayed
-    in the bar by calling either {@link android.app.ProgressDialog#setProgress(int)} with a value for 
-    the total percentage completed so far or {@link android.app.ProgressDialog#incrementProgressBy(int)}
-    with an incremental value to add to the total percentage completed so far.</li>
-</ol>
-
-<p>For example, your setup might look like this:</p>
-<pre>
-ProgressDialog progressDialog;
-progressDialog = new ProgressDialog(mContext);
-progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-progressDialog.setMessage("Loading...");
-progressDialog.setCancelable(false);
-</pre>
-
-<p>The setup is simple. Most of the code needed to create a progress dialog is actually 
-involved in the process that updates it. You might find that it's
-necessary to create a second thread in your application for this work and then report the progress
-back to the Activity's UI thread with a {@link android.os.Handler} object. 
-If you're not familiar with using additional 
-threads with a Handler, see the example Activity below that uses a second thread to
-increment a progress dialog managed by the Activity.</p>
-
-<script type="text/javascript">
-function toggleDiv(link) {
-  var toggleable = $(link).parent();
-  if (toggleable.hasClass("closed")) {
-    $(".toggleme", toggleable).slideDown("fast");
-    toggleable.removeClass("closed");
-    toggleable.addClass("open");
-    $(".toggle-img", toggleable).attr("title", "hide").attr("src", "/assets/images/triangle-opened.png");
-  } else {
-    $(".toggleme", toggleable).slideUp("fast");
-    toggleable.removeClass("open");
-    toggleable.addClass("closed");
-    $(".toggle-img", toggleable).attr("title", "show").attr("src", "/assets/images/triangle-closed.png");
-  }
-  return false;
-}
-</script>
-<style>
-.toggleme {
-  padding:0 0 1px 0;
-}
-.toggleable a {
-  text-decoration:none;
-}
-.toggleable.closed .toggleme {
-  display:none;
-}
-#jd-content .toggle-img {
-  margin:0;
-}
-</style>
-
-<div class="toggleable closed">
-  <a href="#" onclick="return toggleDiv(this)">
-        <img src="/assets/images/triangle-closed.png" class="toggle-img" />
-        <strong>Example ProgressDialog with a second thread</strong></a>
-  <div class="toggleme">
-        <p>This example uses a second thread to track the progress of a process (which actually just
-counts up to 100). The thread sends a {@link android.os.Message} back to the main
-Activity through a {@link android.os.Handler} each time progress is made. The main Activity then updates the 
-ProgressDialog.</p>
-
-<pre>
-package com.example.progressdialog;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-
-public class NotificationTest extends Activity {
-    static final int PROGRESS_DIALOG = 0;
-    Button button;
-    ProgressThread progressThread;
-    ProgressDialog progressDialog;
-   
-    /** Called when the activity is first created. */
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-
-        // Setup the button that starts the progress dialog
-        button = (Button) findViewById(R.id.progressDialog);
-        button.setOnClickListener(new OnClickListener(){
-            public void onClick(View v) {
-                showDialog(PROGRESS_DIALOG);
-            }
-        }); 
-    }
-   
-    protected Dialog onCreateDialog(int id) {
-        switch(id) {
-        case PROGRESS_DIALOG:
-            progressDialog = new ProgressDialog(NotificationTest.this);
-            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-            progressDialog.setMessage("Loading...");
-            return progressDialog;
-        default:
-            return null;
-        }
-    }
-
-    &#64;Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
-        switch(id) {
-        case PROGRESS_DIALOG:
-            progressDialog.setProgress(0);
-            progressThread = new ProgressThread(handler);
-            progressThread.start();
-    }
-
-    // Define the Handler that receives messages from the thread and update the progress
-    final Handler handler = new Handler() {
-        public void handleMessage(Message msg) {
-            int total = msg.arg1;
-            progressDialog.setProgress(total);
-            if (total >= 100){
-                dismissDialog(PROGRESS_DIALOG);
-                progressThread.setState(ProgressThread.STATE_DONE);
-            }
-        }
-    };
-
-    /** Nested class that performs progress calculations (counting) */
-    private class ProgressThread extends Thread {
-        Handler mHandler;
-        final static int STATE_DONE = 0;
-        final static int STATE_RUNNING = 1;
-        int mState;
-        int total;
-       
-        ProgressThread(Handler h) {
-            mHandler = h;
-        }
-       
-        public void run() {
-            mState = STATE_RUNNING;   
-            total = 0;
-            while (mState == STATE_RUNNING) {
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                    Log.e("ERROR", "Thread Interrupted");
-                }
-                Message msg = mHandler.obtainMessage();
-                msg.arg1 = total;
-                mHandler.sendMessage(msg);
-                total++;
-            }
-        }
-        
-        /* sets the current state for the thread,
-         * used to stop the thread */
-        public void setState(int state) {
-            mState = state;
-        }
-    }
-}
-</pre>
-  </div> <!-- end toggleme -->
-</div> <!-- end toggleable -->
-
-
-
-<h2 id="CustomDialog">Creating a Custom Dialog</h2>
-
-<img src="{@docRoot}images/dialog_custom.png" alt="" style="float:right" />
-
-<p>If you want a customized design for a dialog, you can create your own layout
-for the dialog window with layout and widget elements.
-After you've defined your layout, pass the root View object or
-layout resource ID to {@link android.app.Dialog#setContentView(View)}.</p>
-
-<p>For example, to create the dialog shown to the right:</p>
-
-<ol>
-  <li>Create an XML layout saved as <code>custom_dialog.xml</code>:
-<pre>
-&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/layout_root"
-              android:orientation="horizontal"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent"
-              android:padding="10dp"
-              >
-    &lt;ImageView android:id="@+id/image"
-               android:layout_width="wrap_content"
-               android:layout_height="fill_parent"
-               android:layout_marginRight="10dp"
-               />
-    &lt;TextView android:id="@+id/text"
-              android:layout_width="wrap_content"
-              android:layout_height="fill_parent"
-              android:textColor="#FFF"
-              />
-&lt;/LinearLayout>
-</pre>
-
-    <p>This XML defines an {@link android.widget.ImageView} and a {@link android.widget.TextView}
-    inside a {@link android.widget.LinearLayout}.</p>
-  <li>Set the above layout as the dialog's content view and define the content 
-    for the ImageView and TextView elements:</p>
-<pre>
-Context mContext = getApplicationContext();
-Dialog dialog = new Dialog(mContext);
-
-dialog.setContentView(R.layout.custom_dialog);
-dialog.setTitle("Custom Dialog");
-
-TextView text = (TextView) dialog.findViewById(R.id.text);
-text.setText("Hello, this is a custom dialog!");
-ImageView image = (ImageView) dialog.findViewById(R.id.image);
-image.setImageResource(R.drawable.android);
-</pre>
-
-    <p>After you instantiate the Dialog, set your custom layout as the dialog's content view with 
-    {@link android.app.Dialog#setContentView(int)}, passing it the layout resource ID.
-    Now that the Dialog has a defined layout, you can capture View objects from the layout with
-    {@link android.app.Dialog#findViewById(int)} and modify their content.</p>
-  </li>
-
-  <li>That's it. You can now show the dialog as described in 
-    <a href="#ShowingADialog">Showing A Dialog</a>.</li>
-</ol>
-
-<p>A dialog made with the base Dialog class must have a title. If you don't call
-{@link android.app.Dialog#setTitle(CharSequence) setTitle()}, then the space used for the title
-remains empty, but still visible. If you don't want
-a title at all, then you should create your custom dialog using the
-{@link android.app.AlertDialog} class. However, because an AlertDialog is created easiest with 
-the {@link android.app.AlertDialog.Builder} class, you do not have access to the 
-{@link android.app.Dialog#setContentView(int)} method used above. Instead, you must use 
-{@link android.app.AlertDialog.Builder#setView(View)}. This method accepts a {@link android.view.View} object,
-so you need to inflate the layout's root View object from
-XML.</p>
-
-<p>To inflate the XML layout, retrieve the {@link android.view.LayoutInflater} with 
-{@link android.app.Activity#getLayoutInflater()} 
-(or {@link android.content.Context#getSystemService(String) getSystemService()}),
-and then call
-{@link android.view.LayoutInflater#inflate(int, ViewGroup)}, where the first parameter
-is the layout resource ID and the second is the ID of the root View. At this point, you can use
-the inflated layout to find View objects in the layout and define the content for the
-ImageView and TextView elements. Then instantiate the AlertDialog.Builder and set the
-inflated layout for the dialog with {@link android.app.AlertDialog.Builder#setView(View)}.</p>
-
-<p>Here's an example, creating a custom layout in an AlertDialog:</p>
-
-<pre>
-AlertDialog.Builder builder;
-AlertDialog alertDialog;
-
-Context mContext = getApplicationContext();
-LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
-View layout = inflater.inflate(R.layout.custom_dialog,
-                               (ViewGroup) findViewById(R.id.layout_root));
-
-TextView text = (TextView) layout.findViewById(R.id.text);
-text.setText("Hello, this is a custom dialog!");
-ImageView image = (ImageView) layout.findViewById(R.id.image);
-image.setImageResource(R.drawable.android);
-
-builder = new AlertDialog.Builder(mContext);
-builder.setView(layout);
-alertDialog = builder.create();
-</pre>
-
-<p>Using an AlertDialog for your custom layout lets you
-take advantage of built-in AlertDialog features like managed buttons,
-selectable lists, a title, an icon and so on.</p>
-
-<p>For more information, refer to the reference documentation for the 
-{@link android.app.Dialog} and {@link android.app.AlertDialog.Builder} 
-classes.</p>
-
+<p class="note"><strong>Note:</strong> The system calls
+{@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} upon each event that
+invokes the {@link android.support.v4.app.DialogFragment#onCancel onCancel()} callback. However,
+if you call {@link android.app.Dialog#dismiss Dialog.dismiss()} or {@link
+android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()},
+the system calls {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>but
+not</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. So you should generally
+call {@link android.support.v4.app.DialogFragment#dismiss dismiss()} when the user presses the
+<em>positive</em> button in your dialog in order to remove the dialog from view.</p>
 
 
diff --git a/docs/html/images/dialog_buttons.png b/docs/html/images/dialog_buttons.png
deleted file mode 100755
index 81aaec4..0000000
--- a/docs/html/images/dialog_buttons.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/dialog_custom.png b/docs/html/images/dialog_custom.png
deleted file mode 100755
index b2523fd..0000000
--- a/docs/html/images/dialog_custom.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/dialog_list.png b/docs/html/images/dialog_list.png
deleted file mode 100755
index f2736bf..0000000
--- a/docs/html/images/dialog_list.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/dialog_progress_bar.png b/docs/html/images/dialog_progress_bar.png
deleted file mode 100755
index 3e74419..0000000
--- a/docs/html/images/dialog_progress_bar.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/dialog_progress_spinning.png b/docs/html/images/dialog_progress_spinning.png
deleted file mode 100755
index 501f4802..0000000
--- a/docs/html/images/dialog_progress_spinning.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/dialog_singlechoicelist.png b/docs/html/images/dialog_singlechoicelist.png
deleted file mode 100755
index 90629f0..0000000
--- a/docs/html/images/dialog_singlechoicelist.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/ui/dialog_buttons.png b/docs/html/images/ui/dialog_buttons.png
new file mode 100644
index 0000000..ed952a1
--- /dev/null
+++ b/docs/html/images/ui/dialog_buttons.png
Binary files differ
diff --git a/docs/html/images/ui/dialog_checkboxes.png b/docs/html/images/ui/dialog_checkboxes.png
new file mode 100644
index 0000000..8f272e5
--- /dev/null
+++ b/docs/html/images/ui/dialog_checkboxes.png
Binary files differ
diff --git a/docs/html/images/ui/dialog_custom.png b/docs/html/images/ui/dialog_custom.png
new file mode 100644
index 0000000..244473b
--- /dev/null
+++ b/docs/html/images/ui/dialog_custom.png
Binary files differ
diff --git a/docs/html/images/ui/dialog_list.png b/docs/html/images/ui/dialog_list.png
new file mode 100644
index 0000000..437fc74
--- /dev/null
+++ b/docs/html/images/ui/dialog_list.png
Binary files differ
diff --git a/docs/html/images/ui/dialogs.png b/docs/html/images/ui/dialogs.png
new file mode 100644
index 0000000..d45b0b5
--- /dev/null
+++ b/docs/html/images/ui/dialogs.png
Binary files differ
diff --git a/docs/html/images/ui/dialogs_regions.png b/docs/html/images/ui/dialogs_regions.png
new file mode 100644
index 0000000..2bfc1a4
--- /dev/null
+++ b/docs/html/images/ui/dialogs_regions.png
Binary files differ
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 4561397..d11e554 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
+import android.view.ViewDebug;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -34,6 +35,7 @@
  * @attr ref android.R.styleable#ColorDrawable_color
  */
 public class ColorDrawable extends Drawable {
+    @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
     private ColorState mState;
     private final Paint mPaint = new Paint();
     private boolean mMutated;
@@ -174,6 +176,7 @@
 
     final static class ColorState extends ConstantState {
         int mBaseColor; // base color, independent of setAlpha()
+        @ViewDebug.ExportedProperty
         int mUseColor;  // basecolor modulated by setAlpha()
         int mChangingConfigurations;
 
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
index 61e5d4f..2a04b42 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -69,13 +69,13 @@
     /**
      * Set the radius of the Blur.
      *
-     * Supported range 0-25
+     * Supported range 0 < radius <= 25
      *
      * @param radius The radius of the blur
      */
     public void setRadius(float radius) {
-        if (radius < 0 || radius > 25) {
-            throw new RSIllegalArgumentException("Radius out of range (0-25).");
+        if (radius <= 0 || radius > 25) {
+            throw new RSIllegalArgumentException("Radius out of range (0 < r <= 25).");
         }
         setVar(0, radius);
     }
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
index 9c87c22..ffed804 100644
--- a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
+++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
@@ -234,4 +234,21 @@
             attemptDeadServiceRecovery(e);
         }
     }
+
+    /**
+     * Returns the name of this adapter's driver.
+     *
+     * <p>Different NFC adapters may use different drivers.  This value is
+     * informational and should not be parsed.
+     *
+     * @return the driver name, or empty string if unknown
+     */
+    public String getDriverName() {
+        try {
+            return sService.getDriverName(mPackageName);
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            return "";
+        }
+    }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 2716b04..a9869d9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -68,7 +68,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 91;
+    private static final int DATABASE_VERSION = 92;
 
     private Context mContext;
     private int mUserHandle;
@@ -1433,6 +1433,22 @@
             upgradeVersion = 91;
         }
 
+        if (upgradeVersion == 91) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                try {
+                    // Move ringer mode from system to global settings
+                    String[] settingsToMove = { Settings.System.MODE_RINGER };
+                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, settingsToMove, true);
+
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+            upgradeVersion = 92;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -1757,9 +1773,6 @@
                     Settings.System.VOLUME_BLUETOOTH_SCO,
                     AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
 
-            loadSetting(stmt, Settings.System.MODE_RINGER,
-                    AudioManager.RINGER_MODE_NORMAL);
-
             // By default:
             // - ringtones, notification, system and music streams are affected by ringer mode
             // on non voice capable devices (tablets)
@@ -2049,6 +2062,9 @@
             loadIntegerSetting(stmt, Settings.Global.WIFI_SLEEP_POLICY,
                     R.integer.def_wifi_sleep_policy);
 
+            loadSetting(stmt, Settings.Global.MODE_RINGER,
+                    AudioManager.RINGER_MODE_NORMAL);
+
             // --- Previously in 'secure'
             loadBooleanSetting(stmt, Settings.Global.PACKAGE_VERIFIER_ENABLE,
                     R.bool.def_package_verifier_enable);
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 7f6098a..db25c1a 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -71,7 +71,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:fadingEdge="none"
-            android:overScrollMode="always"
+            android:overScrollMode="ifContentScrolls"
             >
             <com.android.systemui.statusbar.policy.NotificationRowLayout
                 android:id="@+id/latestItems"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index dddef6d..942e814 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -66,7 +66,7 @@
     <!-- Vibration duration for MultiWaveView used in SearchPanelView -->
     <integer translatable="false" name="config_search_panel_view_vibration_duration">20</integer>
 
-    <!-- The length of the vibration when the notificaiotn pops open. -->
+    <!-- The length of the vibration when the notification pops open. -->
     <integer name="one_finger_pop_duration_ms">10</integer>
 
     <!-- Whether we're using the tablet-optimized recents interface (we use this
@@ -94,5 +94,8 @@
     <!-- Timeouts for brightness dialog to disappear -->
     <integer name="quick_settings_brightness_dialog_short_timeout">2000</integer>
     <integer name="quick_settings_brightness_dialog_long_timeout">4000</integer>
+
+    <integer name="blinds_pop_duration_ms">10</integer>
+
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 99036ef..4bf6c10 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -184,7 +184,7 @@
     <!-- Height of the carrier/wifi name label -->
     <dimen name="carrier_label_height">24dp</dimen>
 
-    <!-- The distance you can pull a notificaiton before it pops open -->
+    <!-- The distance you can pull a notification before it pops open -->
     <dimen name="one_finger_pop_limit">32dp</dimen>
 
     <!-- The fixed height of each tile -->
@@ -196,4 +196,9 @@
     <!-- Minimum fraction of the screen that should be taken up by the notification panel.
          Not used at this screen size. -->
     <item type="dimen" name="notification_panel_min_height_frac">0%</item>
+
+    <dimen name="blinds_pop_threshold">32dp</dimen>
+
+    <!-- The size of the gesture span needed to activate the "pull" notification expansion -->
+    <dimen name="pull_span_min">25dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 674d9a3..dcfd0b3 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -50,7 +50,7 @@
     private static final long EXPAND_DURATION = 250;
     private static final long GLOW_DURATION = 150;
 
-    // Set to false to disable focus-based gestures (two-finger pull).
+    // Set to false to disable focus-based gestures (spread-finger vertical pull).
     private static final boolean USE_DRAG = true;
     // Set to false to disable scale-based gestures (both horizontal and vertical).
     private static final boolean USE_SPAN = true;
@@ -69,8 +69,12 @@
     @SuppressWarnings("unused")
     private Context mContext;
 
-    private boolean mStretching;
-    private boolean mPullingWithOneFinger;
+    private boolean mExpanding;
+    private static final int NONE    = 0;
+    private static final int BLINDS  = 1<<0;
+    private static final int PULL    = 1<<1;
+    private static final int STRETCH = 1<<2;
+    private int mExpansionStyle = NONE;
     private boolean mWatchingForPull;
     private boolean mHasPopped;
     private View mEventSource;
@@ -86,8 +90,9 @@
     private int mLastMotionY;
     private float mPopLimit;
     private int mPopDuration;
+    private float mPullGestureMinXSpan;
     private Callback mCallback;
-    private ScaleGestureDetector mDetector;
+    private ScaleGestureDetector mSGD;
     private ViewScaler mScaler;
     private ObjectAnimator mScaleAnimation;
     private AnimatorSet mGlowAnimationSet;
@@ -122,7 +127,7 @@
             if (height < 0) {
                 height = mView.getMeasuredHeight();
             }
-            return (float) height;
+            return height;
         }
         public int getNaturalHeight(int maximum) {
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
@@ -161,8 +166,9 @@
         mGravity = Gravity.TOP;
         mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
         mScaleAnimation.setDuration(EXPAND_DURATION);
-        mPopLimit = mContext.getResources().getDimension(R.dimen.one_finger_pop_limit);
-        mPopDuration = mContext.getResources().getInteger(R.integer.one_finger_pop_duration_ms);
+        mPopLimit = mContext.getResources().getDimension(R.dimen.blinds_pop_threshold);
+        mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms);
+        mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min);
 
         AnimatorListenerAdapter glowVisibilityController = new AnimatorListenerAdapter() {
             @Override
@@ -193,41 +199,30 @@
         final ViewConfiguration configuration = ViewConfiguration.get(mContext);
         mTouchSlop = configuration.getScaledTouchSlop();
 
-        mDetector =
-                new ScaleGestureDetector(context,
+        mSGD = new ScaleGestureDetector(context,
                                          new ScaleGestureDetector.SimpleOnScaleGestureListener() {
             @Override
             public boolean onScaleBegin(ScaleGestureDetector detector) {
                 if (DEBUG_SCALE) Slog.v(TAG, "onscalebegin()");
-                float x = detector.getFocusX();
-                float y = detector.getFocusY();
+                float focusX = detector.getFocusX();
+                float focusY = detector.getFocusY();
 
                 // your fingers have to be somewhat close to the bounds of the view in question
-                mInitialTouchFocusY = detector.getFocusY();
+                mInitialTouchFocusY = focusY;
                 mInitialTouchSpan = Math.abs(detector.getCurrentSpan());
                 if (DEBUG_SCALE) Slog.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
 
-                mStretching = initScale(findView(x, y));
-                return mStretching;
+                final View underFocus = findView(focusX, focusY);
+                if (underFocus != null) {
+                    startExpanding(underFocus, STRETCH);
+                }
+                return mExpanding;
             }
 
             @Override
             public boolean onScale(ScaleGestureDetector detector) {
                 if (DEBUG_SCALE) Slog.v(TAG, "onscale() on " + mCurrView);
-
-                // are we scaling or dragging?
-                float span = Math.abs(detector.getCurrentSpan()) - mInitialTouchSpan;
-                span *= USE_SPAN ? 1f : 0f;
-                float drag = detector.getFocusY() - mInitialTouchFocusY;
-                drag *= USE_DRAG ? 1f : 0f;
-                drag *= mGravity == Gravity.BOTTOM ? -1f : 1f;
-                float pull = Math.abs(drag) + Math.abs(span) + 1f;
-                float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
-                float target = hand + mOldHeight;
-                float newHeight = clamp(target);
-                mScaler.setHeight(newHeight);
-
-                setGlow(calculateGlow(target, newHeight));
+                updateExpansion();
                 return true;
             }
 
@@ -236,13 +231,28 @@
                 if (DEBUG_SCALE) Slog.v(TAG, "onscaleend()");
                 // I guess we're alone now
                 if (DEBUG_SCALE) Slog.d(TAG, "scale end");
-                finishScale(false);
+                finishExpanding(false);
                 clearView();
-                mStretching = false;
             }
         });
     }
 
+    private void updateExpansion() {
+        // are we scaling or dragging?
+        float span = Math.abs(mSGD.getCurrentSpan()) - mInitialTouchSpan;
+        span *= USE_SPAN ? 1f : 0f;
+        float drag = mSGD.getFocusY() - mInitialTouchFocusY;
+        drag *= USE_DRAG ? 1f : 0f;
+        drag *= mGravity == Gravity.BOTTOM ? -1f : 1f;
+        float pull = Math.abs(drag) + Math.abs(span) + 1f;
+        float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
+        float target = hand + mOldHeight;
+        float newHeight = clamp(target);
+        mScaler.setHeight(newHeight);
+
+        setGlow(calculateGlow(target, newHeight));
+    }
+
     private float clamp(float target) {
         float out = target;
         out = out < mSmallSize ? mSmallSize : (out > mLargeSize ? mLargeSize : out);
@@ -255,8 +265,8 @@
         if (mEventSource != null) {
             int[] location = new int[2];
             mEventSource.getLocationOnScreen(location);
-            x += (float) location[0];
-            y += (float) location[1];
+            x += location[0];
+            y += location[1];
             v = mCallback.getChildAtRawPosition(x, y);
         } else {
             v = mCallback.getChildAtPosition(x, y);
@@ -274,14 +284,14 @@
         if (mEventSource != null) {
             int[] location = new int[2];
             mEventSource.getLocationOnScreen(location);
-            x += (float) location[0];
-            y += (float) location[1];
+            x += location[0];
+            y += location[1];
             if (DEBUG) Slog.d(TAG, "  to global (" + x + ", " + y + ")");
         }
         int[] location = new int[2];
         v.getLocationOnScreen(location);
-        x -= (float) location[0];
-        y -= (float) location[1];
+        x -= location[0];
+        y -= location[1];
         if (DEBUG) Slog.d(TAG, "  to local (" + x + ", " + y + ")");
         if (DEBUG) Slog.d(TAG, "  inside (" + v.getWidth() + ", " + v.getHeight() + ")");
         boolean inside = (x > 0f && y > 0f && x < v.getWidth() & y < v.getHeight());
@@ -303,7 +313,7 @@
     private float calculateGlow(float target, float actual) {
         // glow if overscale
         if (DEBUG_GLOW) Slog.d(TAG, "target: " + target + " actual: " + actual);
-        float stretch = (float) Math.abs((target - actual) / mMaximumStretch);
+        float stretch = Math.abs((target - actual) / mMaximumStretch);
         float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
         if (DEBUG_GLOW) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
         return (GLOW_BASE + strength * (1f - GLOW_BASE));
@@ -340,32 +350,54 @@
                 View.INVISIBLE : View.VISIBLE);
     }
 
+    @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (DEBUG) Slog.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
-                         " stretching=" + mStretching +
-                         " onefinger=" + mPullingWithOneFinger);
-        // check for a two-finger gesture
-        mDetector.onTouchEvent(ev);
-        if (mStretching) {
+        final int action = ev.getAction();
+        if (DEBUG_SCALE) Slog.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
+                         " expanding=" + mExpanding +
+                         (0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") +
+                         (0 != (mExpansionStyle & PULL) ? " (pull)" : "") +
+                         (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : ""));
+        // check for a spread-finger vertical pull gesture
+        mSGD.onTouchEvent(ev);
+        final int x = (int) mSGD.getFocusX();
+        final int y = (int) mSGD.getFocusY();
+        if (mExpanding) {
             return true;
         } else {
-            final int action = ev.getAction();
-            if ((action == MotionEvent.ACTION_MOVE) && mPullingWithOneFinger) {
+            if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) {
+                // we've begun Venetian blinds style expansion
+                return true;
+            }
+            final float xspan = mSGD.getCurrentSpanX();
+            if ((action == MotionEvent.ACTION_MOVE &&
+                    xspan > mPullGestureMinXSpan &&
+                    xspan > mSGD.getCurrentSpanY())) {
+                // detect a vertical pulling gesture with fingers somewhat separated
+                if (DEBUG_SCALE) Slog.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
+
+                mInitialTouchFocusY = y;
+
+                final View underFocus = findView(x, y);
+                if (underFocus != null) {
+                    startExpanding(underFocus, PULL);
+                }
                 return true;
             }
             if (mScrollView != null && mScrollView.getScrollY() > 0) {
                 return false;
             }
+            // Now look for other gestures
             switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_MOVE: {
                 if (mWatchingForPull) {
-                    final int x = (int) ev.getX();
-                    final int y = (int) ev.getY();
                     final int yDiff = y - mLastMotionY;
                     if (yDiff > mTouchSlop) {
+                        if (DEBUG) Slog.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
                         mLastMotionY = y;
-                        mPullingWithOneFinger = initScale(findView(x, y));
-                        if (mPullingWithOneFinger) {
+                        final View underFocus = findView(x, y);
+                        if (underFocus != null) {
+                            startExpanding(underFocus, BLINDS);
                             mInitialTouchY = mLastMotionY;
                             mHasPopped = false;
                         }
@@ -375,35 +407,35 @@
             }
 
             case MotionEvent.ACTION_DOWN:
-                mWatchingForPull = isInside(mScrollView, ev.getX(), ev.getY());
-                mLastMotionY = (int) ev.getY();
+                mWatchingForPull = isInside(mScrollView, x, y);
+                mLastMotionY = y;
                 break;
 
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
-                if (mPullingWithOneFinger) {
-                    finishScale(false);
-                    clearView();
-                }
-                mPullingWithOneFinger = false;
-                mWatchingForPull = false;
+                if (DEBUG) Slog.d(TAG, "up/cancel");
+                finishExpanding(false);
+                clearView();
                 break;
             }
-            return mPullingWithOneFinger;
+            return mExpanding;
         }
     }
 
+    @Override
     public boolean onTouchEvent(MotionEvent ev) {
         final int action = ev.getAction();
-        if (DEBUG_SCALE) Slog.d(TAG, "touch: act=" + (action) +
-                         " stretching=" + mStretching +
-                         " onefinger=" + mPullingWithOneFinger);
-        if (mStretching) {
-            mDetector.onTouchEvent(ev);
-        }
+        if (DEBUG_SCALE) Slog.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
+                " expanding=" + mExpanding +
+                (0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") +
+                (0 != (mExpansionStyle & PULL) ? " (pull)" : "") +
+                (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : ""));
+
+        mSGD.onTouchEvent(ev);
+
         switch (action) {
             case MotionEvent.ACTION_MOVE: {
-                if (mPullingWithOneFinger) {
+                if (0 != (mExpansionStyle & BLINDS)) {
                     final float rawHeight = ev.getY() - mInitialTouchY + mOldHeight;
                     final float newHeight = clamp(rawHeight);
                     final boolean wasClosed = (mOldHeight == mSmallSize);
@@ -430,57 +462,59 @@
                         setGlow(calculateGlow(4f * pull, 0f));
                     }
 
-                    final int x = (int) ev.getX();
-                    final int y = (int) ev.getY();
-                    View underPointer = findView(x, y);
-                    if (isFinished && underPointer != null && underPointer != mCurrView) {
-                        finishScale(false);
-                        initScale(underPointer);
-                        mInitialTouchY = ev.getY();
+                    final int x = (int) mSGD.getFocusX();
+                    final int y = (int) mSGD.getFocusY();
+                    View underFocus = findView(x, y);
+                    if (isFinished && underFocus != null && underFocus != mCurrView) {
+                        finishExpanding(false); // @@@ needed?
+                        startExpanding(underFocus, BLINDS);
+                        mInitialTouchY = y;
                         mHasPopped = false;
                     }
                     return true;
                 }
+
+                if (mExpanding) {
+                    updateExpansion();
+                    return true;
+                }
+
                 break;
             }
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
-                if (DEBUG) Slog.d(TAG, "cancel");
-                mStretching = false;
-                if (mPullingWithOneFinger) {
-                    finishScale(false);
-                    mPullingWithOneFinger = false;
-                }
+                if (DEBUG) Slog.d(TAG, "up/cancel");
+                finishExpanding(false);
                 clearView();
                 break;
         }
         return true;
     }
-    private boolean initScale(View v) {
-        if (v != null) {
-            if (DEBUG) Slog.d(TAG, "scale begins on view: " + v);
-            mCallback.setUserLockedChild(v, true);
-            setView(v);
-            setGlow(GLOW_BASE);
-            mScaler.setView(v);
-            mOldHeight = mScaler.getHeight();
-            if (mCallback.canChildBeExpanded(v)) {
-                if (DEBUG) Slog.d(TAG, "working on an expandable child");
-                mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
-            } else {
-                if (DEBUG) Slog.d(TAG, "working on a non-expandable child");
-                mNaturalHeight = mOldHeight;
-            }
-            if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
-                        " mNaturalHeight: " + mNaturalHeight);
-            v.getParent().requestDisallowInterceptTouchEvent(true);
-            return true;
+
+    private void startExpanding(View v, int expandType) {
+        mExpanding = true;
+        mExpansionStyle = expandType; 
+        if (DEBUG) Slog.d(TAG, "scale type " + expandType + " beginning on view: " + v);
+        mCallback.setUserLockedChild(v, true);
+        setView(v);
+        setGlow(GLOW_BASE);
+        mScaler.setView(v);
+        mOldHeight = mScaler.getHeight();
+        if (mCallback.canChildBeExpanded(v)) {
+            if (DEBUG) Slog.d(TAG, "working on an expandable child");
+            mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
         } else {
-            return false;
+            if (DEBUG) Slog.d(TAG, "working on a non-expandable child");
+            mNaturalHeight = mOldHeight;
         }
+        if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
+                    " mNaturalHeight: " + mNaturalHeight);
+        v.getParent().requestDisallowInterceptTouchEvent(true);
     }
 
-    private void finishScale(boolean force) {
+    private void finishExpanding(boolean force) {
+        if (!mExpanding) return;
+
         float currentHeight = mScaler.getHeight();
         float targetHeight = mSmallSize;
         float h = mScaler.getHeight();
@@ -501,6 +535,10 @@
             mScaleAnimation.start();
         }
         mCallback.setUserLockedChild(mCurrView, false);
+
+        mExpanding = false;
+        mExpansionStyle = NONE;
+
         if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView);
     }
 
@@ -527,8 +565,8 @@
 
     @Override
     public void onClick(View v) {
-        initScale(v);
-        finishScale(true);
+        startExpanding(v, STRETCH);
+        finishExpanding(true);
         clearView();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index ca1f75c..de62179 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -295,6 +295,7 @@
     }
 
     public void fling(float vel, boolean always) {
+        if (DEBUG) LOG("fling: vel=%.3f, this=%s", vel, this);
         mVel = vel;
 
         if (always||mVel != 0) {
@@ -416,7 +417,10 @@
 
     public void collapse() {
         // TODO: abort animation or ongoing touch
+        if (DEBUG) LOG("collapse: " + this);
         if (!isFullyCollapsed()) {
+            mTimeAnimator.cancel();
+            mClosing = true;
             // collapse() should never be a rubberband, even if an animation is already running
             mRubberbanding = false;
             fling(-mSelfCollapseVelocityPx, /*always=*/ true);
@@ -424,10 +428,10 @@
     }
 
     public void expand() {
+        if (DEBUG) LOG("expand: " + this);
         if (isFullyCollapsed()) {
             mBar.startOpeningPanel(this);
-            if (DEBUG) LOG("expand: calling fling(%s, true)", mSelfExpandVelocityPx);
-            fling (mSelfExpandVelocityPx, /*always=*/ true);
+            fling(mSelfExpandVelocityPx, /*always=*/ true);
         } else if (DEBUG) {
             if (DEBUG) LOG("skipping expansion: is expanded");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 15ac5c0..516b1ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -149,6 +149,7 @@
 
     @Override
     public void onPanelFullyOpened(PanelView openPanel) {
+        super.onPanelFullyOpened(openPanel);
         mFadingPanel = openPanel;
         mShouldFade = true; // now you own the fade, mister
     }
diff --git a/policy/src/com/android/internal/policy/impl/EnableAccessibilityController.java b/policy/src/com/android/internal/policy/impl/EnableAccessibilityController.java
index 889463b..71b0d53 100644
--- a/policy/src/com/android/internal/policy/impl/EnableAccessibilityController.java
+++ b/policy/src/com/android/internal/policy/impl/EnableAccessibilityController.java
@@ -40,6 +40,7 @@
 
 import com.android.internal.R;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -131,8 +132,9 @@
 
     private static List<AccessibilityServiceInfo> getInstalledSpeakingAccessibilityServices(
             Context context) {
-        List<AccessibilityServiceInfo> services = AccessibilityManager.getInstance(
-                context).getInstalledAccessibilityServiceList();
+        List<AccessibilityServiceInfo> services = new ArrayList<AccessibilityServiceInfo>();
+        services.addAll(AccessibilityManager.getInstance(context)
+                .getInstalledAccessibilityServiceList());
         Iterator<AccessibilityServiceInfo> iterator = services.iterator();
         while (iterator.hasNext()) {
             AccessibilityServiceInfo service = iterator.next();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 3df9bb2..f0dfba1 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -67,6 +67,7 @@
     private AppWidgetHost mAppWidgetHost;
     private KeyguardWidgetPager mAppWidgetContainer;
     private ViewFlipper mSecurityViewContainer;
+    private KeyguardSelectorView mKeyguardSelectorView;
     private KeyguardTransportControlView mTransportControl;
     private boolean mEnableMenuKey;
     private boolean mIsVerifyUnlockOnly;
@@ -90,6 +91,7 @@
     /*package*/ interface UserSwitcherCallback {
         void hideSecurityView(int duration);
         void showSecurityView();
+        void showUnlockHint();
     }
 
     public KeyguardHostView(Context context) {
@@ -144,6 +146,7 @@
         KeyguardWidgetRegion kgwr = (KeyguardWidgetRegion) findViewById(R.id.kg_widget_region);
         kgwr.setVisibility(VISIBLE);
         mSecurityViewContainer = (ViewFlipper) findViewById(R.id.view_flipper);
+        mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
 
         addDefaultWidgets();
         updateSecurityViews();
@@ -373,6 +376,18 @@
         showSecurityScreen(mSecurityModel.getBackupFor(currentMode));
     }
 
+    public boolean showNextSecurityScreenIfPresent() {
+        SecurityMode securityMode = mSecurityModel.getSecurityMode();
+        // Allow an alternate, such as biometric unlock
+        securityMode = mSecurityModel.getAlternateFor(securityMode);
+        if (SecurityMode.None == securityMode) {
+            return false;
+        } else {
+            showSecurityScreen(securityMode); // switch to the alternate security view
+            return true;
+        }
+    }
+
     private void showNextSecurityScreenOrFinish(boolean authenticated) {
         boolean finish = false;
         if (SecurityMode.None == mCurrentSecuritySelection) {
@@ -794,6 +809,12 @@
                 public void showSecurityView() {
                     mSecurityViewContainer.setAlpha(1.0f);
                 }
+
+                @Override
+                public void showUnlockHint() {
+                    mKeyguardSelectorView.ping();
+                }
+
             };
             multiUser.setCallback(callback);
         }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
index a034f4c..7266883 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
@@ -57,32 +57,29 @@
         KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
                 LayoutInflater.from(context).inflate(resId, userSelector, false);
 
-        icon.setup(info, userSelector);
+        icon.init(info, userSelector);
         return icon;
     }
 
     public KeyguardMultiUserAvatar(Context context) {
-        super(context, null, 0);
+        this(context, null, 0);
     }
 
     public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
-        super(context, attrs, 0);
+        this(context, attrs, 0);
     }
 
     public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-    }
 
-    public void setup(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
-        mUserInfo = user;
-        mUserSelector = userSelector;
-        init();
-    }
-
-    private void init() {
         Resources res = mContext.getResources();
         mActiveTextColor = res.getColor(R.color.kg_multi_user_text_active);
         mInactiveTextColor = res.getColor(R.color.kg_multi_user_text_inactive);
+    }
+
+    public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
+        mUserInfo = user;
+        mUserSelector = userSelector;
 
         mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
         mUserName = (TextView) findViewById(R.id.keyguard_user_name);        
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
index 3b45c22..8214142 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
@@ -107,7 +107,8 @@
         if (!(v instanceof KeyguardMultiUserAvatar)) return;
         final KeyguardMultiUserAvatar avatar = (KeyguardMultiUserAvatar) v;
         if (mActiveUserAvatar == avatar) {
-            // They clicked the active user, no need to do anything
+            // If they click the currently active user, show the unlock hint
+            mCallback.showUnlockHint();
             return;
         } else {
             // Reset the previously active user to appear inactive
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index 4003754..e3b7b01 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -179,6 +179,10 @@
         return mGlowPadView.getTargetPosition(resId) != -1;
     }
 
+    public void ping() {
+        mGlowPadView.ping();
+    }
+
     private void updateTargets() {
         int currentUserHandle = mLockPatternUtils.getCurrentUser();
         DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index c4f761f..23a96fb 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -36,6 +36,7 @@
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 
+import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.R;
 
@@ -191,6 +192,7 @@
 
         if (userSwitched) {
             mKeyguardView.goToUserSwitcher();
+            mKeyguardView.showNextSecurityScreenIfPresent();
         }
 
         if (mScreenOn) {
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 0045f4a..40758d3 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -127,6 +127,8 @@
     private long mDischargeStartTime;
     private int mDischargeStartLevel;
 
+    private boolean mUpdatesStopped;
+
     private Led mLed;
 
     private boolean mSentLowBatteryBroadcast = false;
@@ -231,7 +233,7 @@
             Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
             intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            mContext.startActivity(intent);
+            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
     }
 
@@ -244,16 +246,18 @@
             Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
             intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            mContext.startActivity(intent);
+            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
     }
 
     private void updateLocked() {
-        // Update the values of mAcOnline, et. all.
-        native_update();
+        if (!mUpdatesStopped) {
+            // Update the values of mAcOnline, et. all.
+            native_update();
 
-        // Process the new values.
-        processValuesLocked();
+            // Process the new values.
+            processValuesLocked();
+        }
     }
 
     private void processValuesLocked() {
@@ -543,6 +547,9 @@
         synchronized (mLock) {
             if (args == null || args.length == 0 || "-a".equals(args[0])) {
                 pw.println("Current Battery Service state:");
+                if (mUpdatesStopped) {
+                    pw.println("  (UPDATES STOPPED -- use 'reset' to restart)");
+                }
                 pw.println("  AC powered: " + mAcOnline);
                 pw.println("  USB powered: " + mUsbOnline);
                 pw.println("  Wireless powered: " + mWirelessOnline);
@@ -554,35 +561,41 @@
                 pw.println("  voltage:" + mBatteryVoltage);
                 pw.println("  temperature: " + mBatteryTemperature);
                 pw.println("  technology: " + mBatteryTechnology);
-            } else if (false) {
-                // DO NOT SUBMIT WITH THIS TURNED ON
-                if (args.length == 3 && "set".equals(args[0])) {
-                    String key = args[1];
-                    String value = args[2];
-                    try {
-                        boolean update = true;
-                        if ("ac".equals(key)) {
-                            mAcOnline = Integer.parseInt(value) != 0;
-                        } else if ("usb".equals(key)) {
-                            mUsbOnline = Integer.parseInt(value) != 0;
-                        } else if ("wireless".equals(key)) {
-                            mWirelessOnline = Integer.parseInt(value) != 0;
-                        } else if ("status".equals(key)) {
-                            mBatteryStatus = Integer.parseInt(value);
-                        } else if ("level".equals(key)) {
-                            mBatteryLevel = Integer.parseInt(value);
-                        } else if ("invalid".equals(key)) {
-                            mInvalidCharger = Integer.parseInt(value);
-                        } else {
-                            update = false;
-                        }
-                        if (update) {
-                            processValuesLocked();
-                        }
-                    } catch (NumberFormatException ex) {
-                        pw.println("Bad value: " + value);
+            } else if (args.length == 3 && "set".equals(args[0])) {
+                String key = args[1];
+                String value = args[2];
+                try {
+                    boolean update = true;
+                    if ("ac".equals(key)) {
+                        mAcOnline = Integer.parseInt(value) != 0;
+                    } else if ("usb".equals(key)) {
+                        mUsbOnline = Integer.parseInt(value) != 0;
+                    } else if ("wireless".equals(key)) {
+                        mWirelessOnline = Integer.parseInt(value) != 0;
+                    } else if ("status".equals(key)) {
+                        mBatteryStatus = Integer.parseInt(value);
+                    } else if ("level".equals(key)) {
+                        mBatteryLevel = Integer.parseInt(value);
+                    } else if ("invalid".equals(key)) {
+                        mInvalidCharger = Integer.parseInt(value);
+                    } else {
+                        pw.println("Unknown set option: " + key);
+                        update = false;
                     }
+                    if (update) {
+                        mUpdatesStopped = true;
+                        processValuesLocked();
+                    }
+                } catch (NumberFormatException ex) {
+                    pw.println("Bad value: " + value);
                 }
+            } else if (args.length == 1 && "reset".equals(args[0])) {
+                mUpdatesStopped = false;
+                updateLocked();
+            } else {
+                pw.println("Dump current battery state, or:");
+                pw.println("  set ac|usb|wireless|status|level|invalid <value>");
+                pw.println("  reset");
             }
         }
     }
diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java
index a4341b7..be65141 100644
--- a/services/java/com/android/server/ShutdownActivity.java
+++ b/services/java/com/android/server/ShutdownActivity.java
@@ -17,9 +17,13 @@
 package com.android.server;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Slog;
 
 import com.android.server.power.ShutdownThread;
@@ -39,15 +43,27 @@
         mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);
         Slog.i(TAG, "onCreate(): confirm=" + mConfirm);
 
-        Handler h = new Handler();
-        h.post(new Runnable() {
+        Thread thr = new Thread("ShutdownActivity") {
+            @Override
             public void run() {
-                if (mReboot) {
-                    ShutdownThread.reboot(ShutdownActivity.this, null, mConfirm);
-                } else {
-                    ShutdownThread.shutdown(ShutdownActivity.this, mConfirm);
+                IPowerManager pm = IPowerManager.Stub.asInterface(
+                        ServiceManager.getService(Context.POWER_SERVICE));
+                try {
+                    if (mReboot) {
+                        pm.reboot(mConfirm, null, false);
+                    } else {
+                        pm.shutdown(mConfirm, false);
+                    }
+                } catch (RemoteException e) {
                 }
             }
-        });
+        };
+        thr.start();
+        finish();
+        // Wait for us to tell the power manager to shutdown.
+        try {
+            thr.join();
+        } catch (InterruptedException e) {
+        }
     }
 }
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index 1342250..8bbf923 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -305,7 +305,7 @@
     void rebootSystem(String reason) {
         Slog.i(TAG, "Rebooting system because: " + reason);
         PowerManagerService pms = (PowerManagerService) ServiceManager.getService("power");
-        pms.reboot(reason);
+        pms.reboot(false, reason, false);
     }
 
     /**
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index c9f89b1..2d81b6c 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -645,7 +645,9 @@
                 // We are in dragging state so we have two pointers and another one
                 // goes down => delegate the three pointers to the view hierarchy
                 mCurrentState = STATE_DELEGATING;
-                sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+                if (mDraggingPointerId != INVALID_POINTER_ID) {
+                    sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+                }
                 sendDownForAllActiveNotInjectedPointers(event, policyFlags);
             } break;
             case MotionEvent.ACTION_MOVE: {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 08b9038..0f3dc92 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -6401,7 +6401,7 @@
                  * do, then we'll defer to them to verify the packages.
                  */
                 final int requiredUid = mRequiredVerifierPackage == null ? -1
-                        : getPackageUid(mRequiredVerifierPackage, 0);
+                        : getPackageUid(mRequiredVerifierPackage, getUser().getIdentifier());
                 if (requiredUid != -1 && isVerificationEnabled(flags)) {
                     final Intent verification = new Intent(
                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index d1c24eb..9a01022 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -1282,15 +1282,25 @@
         return changed;
     }
 
-    // Also used when exiting a dream to determine whether we should go back
-    // to being fully awake or else go to sleep for good.
+    /**
+     * Returns true if the device should go to sleep now.
+     * Also used when exiting a dream to determine whether we should go back
+     * to being fully awake or else go to sleep for good.
+     */
     private boolean isItBedTimeYetLocked() {
-        return mBootCompleted && !mStayOn
-                && (mWakeLockSummary
-                        & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
-                                | WAKE_LOCK_PROXIMITY_SCREEN_OFF)) == 0
-                && (mUserActivitySummary
-                        & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) == 0;
+        return mBootCompleted && !isScreenBeingKeptOnLocked();
+    }
+
+    /**
+     * Returns true if the screen is being kept on by a wake lock, user activity
+     * or the stay on while powered setting.
+     */
+    private boolean isScreenBeingKeptOnLocked() {
+        return mStayOn
+                || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
+                        | WAKE_LOCK_PROXIMITY_SCREEN_OFF)) != 0
+                || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
+                        | USER_ACTIVITY_SCREEN_DIM)) != 0;
     }
 
     /**
@@ -1298,6 +1308,9 @@
      */
     private void updateDreamLocked(int dirty) {
         if ((dirty & (DIRTY_WAKEFULNESS
+                | DIRTY_USER_ACTIVITY
+                | DIRTY_WAKE_LOCKS
+                | DIRTY_BOOT_COMPLETED
                 | DIRTY_SETTINGS
                 | DIRTY_IS_POWERED
                 | DIRTY_STAY_ON
@@ -1380,15 +1393,15 @@
     }
 
     /**
-     * Returns true if the device is allowed to dream in its current state,
-     * assuming that there was either an explicit request to nap or the user activity
-     * timeout expired and no wake locks are held.
+     * Returns true if the device is allowed to dream in its current state
+     * assuming that it is currently napping or dreaming.
      */
     private boolean canDreamLocked() {
-        return mIsPowered
-                && mDreamsSupportedConfig
+        return mDreamsSupportedConfig
                 && mDreamsEnabledSetting
-                && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
+                && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
+                && mBootCompleted
+                && (mIsPowered || isScreenBeingKeptOnLocked());
     }
 
     /**
@@ -1589,22 +1602,39 @@
     }
 
     /**
-     * Reboot the device immediately, passing 'reason' (may be null)
+     * Reboot the device, passing 'reason' (may be null)
      * to the underlying __reboot system call.  Should not return.
      */
     @Override // Binder call
-    public void reboot(String reason) {
+    public void reboot(boolean confirm, String reason, boolean wait) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            rebootInternal(reason);
+            rebootInternal(false, confirm, reason, wait);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
-    private void rebootInternal(final String reason) {
+    /**
+     * Shutdown the devic, passing 'reason' (may be null)
+     * to the underlying __reboot system call.  Should not return.
+     */
+    @Override // Binder call
+    public void shutdown(boolean confirm, boolean wait) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            rebootInternal(true, confirm, null, wait);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void rebootInternal(final boolean shutdown, final boolean confirm,
+            final String reason, boolean wait) {
         if (mHandler == null || !mSystemReady) {
             throw new IllegalStateException("Too early to call reboot()");
         }
@@ -1612,7 +1642,11 @@
         Runnable runnable = new Runnable() {
             public void run() {
                 synchronized (this) {
-                    ShutdownThread.reboot(mContext, reason, false);
+                    if (shutdown) {
+                        ShutdownThread.shutdown(mContext, confirm);
+                    } else {
+                        ShutdownThread.reboot(mContext, reason, confirm);
+                    }
                 }
             }
         };
@@ -1623,11 +1657,13 @@
         mHandler.sendMessage(msg);
 
         // PowerManager.reboot() is documented not to return so just wait for the inevitable.
-        synchronized (runnable) {
-            while (true) {
-                try {
-                    runnable.wait();
-                } catch (InterruptedException e) {
+        if (wait) {
+            synchronized (runnable) {
+                while (true) {
+                    try {
+                        runnable.wait();
+                    } catch (InterruptedException e) {
+                    }
                 }
             }
         }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java
index a2e4298..0c6d41d 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blur25.java
@@ -33,7 +33,7 @@
 
     private int MAX_RADIUS = 25;
     private ScriptC_threshold mScript;
-    private int mRadius = MAX_RADIUS;
+    private float mRadius = MAX_RADIUS;
     private float mSaturation = 1.0f;
     private Allocation mScratchPixelsAllocation1;
     private Allocation mScratchPixelsAllocation2;
@@ -51,13 +51,14 @@
 
 
     public void onBar1Changed(int progress) {
-        float fRadius = progress / 100.0f;
-        fRadius *= (float)(MAX_RADIUS);
-        mRadius = (int)fRadius;
+        mRadius = ((float)progress) / 100.0f * MAX_RADIUS;
+        if (mRadius <= 0.10f) {
+            mRadius = 0.10f;
+        }
         if (mUseIntrinsic) {
             mIntrinsic.setRadius(mRadius);
         } else {
-            mScript.invoke_setRadius(mRadius);
+            mScript.invoke_setRadius((int)mRadius);
         }
     }
 
@@ -111,7 +112,7 @@
         if (mUseIntrinsic) {
             mIntrinsic.setRadius(mRadius);
         } else {
-            mScript.invoke_setRadius(mRadius);
+            mScript.invoke_setRadius((int)mRadius);
         }
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 5e23f24..1ccbc40 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -60,7 +60,12 @@
     }
 
     @Override
-    public void reboot(String arg0) throws RemoteException {
+    public void reboot(boolean confirm, String reason, boolean wait) {
+        // pass for now.
+    }
+
+    @Override
+    public void shutdown(boolean confirm, boolean wait) {
         // pass for now.
     }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index ef57e63..ca329e6 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -1662,7 +1662,6 @@
     private void stopDhcpServer(String intf) {
         try {
             mNwService.stopTethering();
-            mNwService.clearInterfaceAddresses(intf);
         } catch (Exception e) {
             loge("Error stopping Dhcp server" + e);
             return;
@@ -2166,6 +2165,13 @@
             mDhcpStateMachine = null;
         }
 
+        try {
+            mNwService.clearInterfaceAddresses(mGroup.getInterface());
+        } catch (Exception e) {
+            loge("Failed to clear addresses " + e);
+        }
+        NetworkUtils.resetConnections(mGroup.getInterface(), NetworkUtils.RESET_ALL_ADDRESSES);
+
         mGroup = null;
         mWifiNative.p2pFlush();
         mServiceDiscReqId = null;