Merge "Add live region politeness to View, AccessibilityNodeInfo" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index ffe9d63..ac3948f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19038,8 +19038,8 @@
     method public void clear();
     method public int describeContents();
     method public int getColorMode();
-    method public android.print.PrintAttributes.Margins getMargins();
     method public android.print.PrintAttributes.MediaSize getMediaSize();
+    method public android.print.PrintAttributes.Margins getMinMargins();
     method public android.print.PrintAttributes.Resolution getResolution();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int COLOR_MODE_COLOR = 2; // 0x2
@@ -19049,10 +19049,10 @@
 
   public static final class PrintAttributes.Builder {
     ctor public PrintAttributes.Builder();
-    method public android.print.PrintAttributes create();
+    method public android.print.PrintAttributes build();
     method public android.print.PrintAttributes.Builder setColorMode(int);
-    method public android.print.PrintAttributes.Builder setMargins(android.print.PrintAttributes.Margins);
     method public android.print.PrintAttributes.Builder setMediaSize(android.print.PrintAttributes.MediaSize);
+    method public android.print.PrintAttributes.Builder setMinMargins(android.print.PrintAttributes.Margins);
     method public android.print.PrintAttributes.Builder setResolution(android.print.PrintAttributes.Resolution);
   }
 
@@ -19119,7 +19119,7 @@
     ctor public PrintAttributes.Resolution(java.lang.String, java.lang.String, int, int);
     method public int getHorizontalDpi();
     method public java.lang.String getId();
-    method public java.lang.String getLabel(android.content.pm.PackageManager);
+    method public java.lang.String getLabel();
     method public int getVerticalDpi();
   }
 
@@ -19160,7 +19160,7 @@
 
   public static final class PrintDocumentInfo.Builder {
     ctor public PrintDocumentInfo.Builder(java.lang.String);
-    method public android.print.PrintDocumentInfo create();
+    method public android.print.PrintDocumentInfo build();
     method public android.print.PrintDocumentInfo.Builder setContentType(int);
     method public android.print.PrintDocumentInfo.Builder setPageCount(int);
   }
@@ -19207,7 +19207,7 @@
   public final class PrinterCapabilitiesInfo implements android.os.Parcelable {
     method public int describeContents();
     method public int getColorModes();
-    method public void getDefaults(android.print.PrintAttributes);
+    method public android.print.PrintAttributes getDefaults();
     method public java.util.List<android.print.PrintAttributes.MediaSize> getMediaSizes();
     method public android.print.PrintAttributes.Margins getMinMargins();
     method public java.util.List<android.print.PrintAttributes.Resolution> getResolutions();
@@ -19219,9 +19219,9 @@
     ctor public PrinterCapabilitiesInfo.Builder(android.print.PrinterId);
     method public android.print.PrinterCapabilitiesInfo.Builder addMediaSize(android.print.PrintAttributes.MediaSize, boolean);
     method public android.print.PrinterCapabilitiesInfo.Builder addResolution(android.print.PrintAttributes.Resolution, boolean);
-    method public android.print.PrinterCapabilitiesInfo create();
+    method public android.print.PrinterCapabilitiesInfo build();
     method public android.print.PrinterCapabilitiesInfo.Builder setColorModes(int, int);
-    method public android.print.PrinterCapabilitiesInfo.Builder setMinMargins(android.print.PrintAttributes.Margins, android.print.PrintAttributes.Margins);
+    method public android.print.PrinterCapabilitiesInfo.Builder setMinMargins(android.print.PrintAttributes.Margins);
   }
 
   public final class PrinterId implements android.os.Parcelable {
@@ -19248,7 +19248,7 @@
   public static final class PrinterInfo.Builder {
     ctor public PrinterInfo.Builder(android.print.PrinterId, java.lang.String, int);
     ctor public PrinterInfo.Builder(android.print.PrinterInfo);
-    method public android.print.PrinterInfo create();
+    method public android.print.PrinterInfo build();
     method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo);
     method public android.print.PrinterInfo.Builder setDescription(java.lang.String);
     method public android.print.PrinterInfo.Builder setName(java.lang.String);
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index a1ffa8c..d889353 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -41,7 +41,7 @@
 
     private MediaSize mMediaSize;
     private Resolution mResolution;
-    private Margins mMargins;
+    private Margins mMinMargins;
 
     private int mColorMode;
 
@@ -52,7 +52,7 @@
     private PrintAttributes(Parcel parcel) {
         mMediaSize = (parcel.readInt() ==  1) ? MediaSize.createFromParcel(parcel) : null;
         mResolution = (parcel.readInt() ==  1) ? Resolution.createFromParcel(parcel) : null;
-        mMargins = (parcel.readInt() ==  1) ? Margins.createFromParcel(parcel) : null;
+        mMinMargins = (parcel.readInt() ==  1) ? Margins.createFromParcel(parcel) : null;
         mColorMode = parcel.readInt();
     }
 
@@ -97,23 +97,25 @@
     }
 
     /**
-     * Gets the margins.
+     * Gets the minimal margins. If the content does not fit
+     * these margins it will be clipped.
      *
      * @return The margins or <code>null</code> if not set.
      */
-    public Margins getMargins() {
-        return mMargins;
+    public Margins getMinMargins() {
+        return mMinMargins;
     }
 
     /**
-     * Sets the margins.
+     * Sets the minimal margins. If the content does not fit
+     * these margins it will be clipped.
      *
      * @param The margins.
      *
      * @hide
      */
-    public void setMargins(Margins margins) {
-        mMargins = margins;
+    public void setMinMargins(Margins margins) {
+        mMinMargins = margins;
     }
 
     /**
@@ -157,9 +159,9 @@
         } else {
             parcel.writeInt(0);
         }
-        if (mMargins != null) {
+        if (mMinMargins != null) {
             parcel.writeInt(1);
-            mMargins.writeToParcel(parcel);
+            mMinMargins.writeToParcel(parcel);
         } else {
             parcel.writeInt(0);
         }
@@ -176,7 +178,7 @@
         final int prime = 31;
         int result = 1;
         result = prime * result + mColorMode;
-        result = prime * result + ((mMargins == null) ? 0 : mMargins.hashCode());
+        result = prime * result + ((mMinMargins == null) ? 0 : mMinMargins.hashCode());
         result = prime * result + ((mMediaSize == null) ? 0 : mMediaSize.hashCode());
         result = prime * result + ((mResolution == null) ? 0 : mResolution.hashCode());
         return result;
@@ -197,11 +199,11 @@
         if (mColorMode != other.mColorMode) {
             return false;
         }
-        if (mMargins == null) {
-            if (other.mMargins != null) {
+        if (mMinMargins == null) {
+            if (other.mMinMargins != null) {
                 return false;
             }
-        } else if (!mMargins.equals(other.mMargins)) {
+        } else if (!mMinMargins.equals(other.mMinMargins)) {
             return false;
         }
         if (mMediaSize == null) {
@@ -233,7 +235,7 @@
             builder.append(", orientation: ").append("null");
         }
         builder.append(", resolution: ").append(mResolution);
-        builder.append(", margins: ").append(mMargins);
+        builder.append(", minMargins: ").append(mMinMargins);
         builder.append(", colorMode: ").append(colorModeToString(mColorMode));
         builder.append("}");
         return builder.toString();
@@ -243,7 +245,7 @@
     public void clear() {
         mMediaSize = null;
         mResolution = null;
-        mMargins = null;
+        mMinMargins = null;
         mColorMode = 0;
     }
 
@@ -253,7 +255,7 @@
     public void copyFrom(PrintAttributes other) {
         mMediaSize = other.mMediaSize;
         mResolution = other.mResolution;
-        mMargins = other.mMargins;
+        mMinMargins = other.mMinMargins;
         mColorMode = other.mColorMode;
     }
 
@@ -649,64 +651,12 @@
      * This class specifies a supported resolution in dpi (dots per inch).
      */
     public static final class Resolution {
-        private static final String LOG_TAG = "Resolution";
-
         private final String mId;
-        /**@hide */
-        public final String mLabel;
-        /**@hide */
-        public final String mPackageName;
-        /**@hide */
-        public final int mLabelResId;
+        private final String mLabel;
         private final int mHorizontalDpi;
         private final int mVerticalDpi;
 
         /**
-         * Creates a new instance. This is the preferred constructor since
-         * it enables the resolution label to be shown in a localized fashion
-         * on a locale change.
-         *
-         * @param id The unique resolution id.
-         * @param packageName The name of the creating package.
-         * @param labelResId The resource id of a human readable label.
-         * @param horizontalDpi The horizontal resolution in dpi.
-         * @param verticalDpi The vertical resolution in dpi.
-         *
-         * @throws IllegalArgumentException If the id is empty.
-         * @throws IllegalArgumentException If the label is empty.
-         * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero.
-         * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero.
-         *
-         * @hide
-         */
-        public Resolution(String id, String packageName, int labelResId,
-                int horizontalDpi, int verticalDpi) {
-            if (TextUtils.isEmpty(id)) {
-                throw new IllegalArgumentException("id cannot be empty.");
-            }
-            if (TextUtils.isEmpty(packageName)) {
-                throw new IllegalArgumentException("packageName cannot be empty.");
-            }
-            if (labelResId <= 0) {
-                throw new IllegalArgumentException("labelResId must be greater than zero.");
-            }
-            if (horizontalDpi <= 0) {
-                throw new IllegalArgumentException("horizontalDpi "
-                        + "cannot be less than or equal to zero.");
-            }
-            if (verticalDpi <= 0) {
-                throw new IllegalArgumentException("verticalDpi"
-                       + " cannot be less than or equal to zero.");
-            }
-            mId = id;
-            mPackageName = packageName;
-            mLabelResId = labelResId;
-            mHorizontalDpi = horizontalDpi;
-            mVerticalDpi = verticalDpi;
-            mLabel = null;
-        }
-
-        /**
          * Creates a new instance.
          *
          * @param id The unique resolution id.
@@ -738,19 +688,6 @@
             mLabel = label;
             mHorizontalDpi = horizontalDpi;
             mVerticalDpi = verticalDpi;
-            mPackageName = null;
-            mLabelResId = 0;
-        }
-
-        /** @hide */
-        public Resolution(String id, String label, String packageName,
-                int horizontalDpi, int verticalDpi, int labelResId) {
-            mId = id;
-            mPackageName = packageName;
-            mLabelResId = labelResId;
-            mHorizontalDpi = horizontalDpi;
-            mVerticalDpi = verticalDpi;
-            mLabel = label;
         }
 
         /**
@@ -765,22 +702,9 @@
         /**
          * Gets the resolution human readable label.
          *
-         * @param packageManager The package manager for loading the label.
          * @return The human readable label.
          */
-        public String getLabel(PackageManager packageManager) {
-            if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) {
-                try {
-                    return packageManager.getResourcesForApplication(
-                            mPackageName).getString(mLabelResId);
-                } catch (NotFoundException nfe) {
-                    Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
-                            + " from package " + mPackageName);
-                } catch (NameNotFoundException nnfee) {
-                    Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
-                            + " from package " + mPackageName);
-                }
-            }
+        public String getLabel() {
             return mLabel;
         }
 
@@ -805,18 +729,14 @@
         void writeToParcel(Parcel parcel) {
             parcel.writeString(mId);
             parcel.writeString(mLabel);
-            parcel.writeString(mPackageName);
             parcel.writeInt(mHorizontalDpi);
             parcel.writeInt(mVerticalDpi);
-            parcel.writeInt(mLabelResId);
         }
 
         static Resolution createFromParcel(Parcel parcel) {
             return new Resolution(
                     parcel.readString(),
                     parcel.readString(),
-                    parcel.readString(),
-                    parcel.readInt(),
                     parcel.readInt(),
                     parcel.readInt());
         }
@@ -857,10 +777,8 @@
             builder.append("Resolution{");
             builder.append("id: ").append(mId);
             builder.append(", label: ").append(mLabel);
-            builder.append(", packageName: ").append(mPackageName);
             builder.append(", horizontalDpi: ").append(mHorizontalDpi);
             builder.append(", verticalDpi: ").append(mVerticalDpi);
-            builder.append(", labelResId: ").append(mLabelResId);
             builder.append("}");
             return builder.toString();
         }
@@ -1042,13 +960,14 @@
         }
 
         /**
-         * Sets the margins.
+         * Sets the minimal margins. If the content does not fit
+         * these margins it will be clipped.
          *
          * @param margins The margins.
          * @return This builder.
          */
-        public Builder setMargins(Margins margins) {
-            mAttributes.setMargins(margins);
+        public Builder setMinMargins(Margins margins) {
+            mAttributes.setMinMargins(margins);
             return this;
         }
 
@@ -1074,7 +993,7 @@
          *
          * @return The new instance.
          */
-        public PrintAttributes create() {
+        public PrintAttributes build() {
             return mAttributes;
         }
     }
diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java
index 7a96e69..f094962 100644
--- a/core/java/android/print/PrintDocumentInfo.java
+++ b/core/java/android/print/PrintDocumentInfo.java
@@ -277,7 +277,7 @@
          *
          * @return The new instance.
          */
-        public PrintDocumentInfo create() {
+        public PrintDocumentInfo build() {
             return new PrintDocumentInfo(mPrototype);
         }
     }
diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java
index ea44c87..df51ec1 100644
--- a/core/java/android/print/PrinterCapabilitiesInfo.java
+++ b/core/java/android/print/PrinterCapabilitiesInfo.java
@@ -51,7 +51,6 @@
     private int mColorModes;
 
     private final int[] mDefaults = new int[PROPERTY_COUNT];
-    private Margins mDefaultMargins = DEFAULT_MARGINS;
 
     /**
      * @hide
@@ -71,6 +70,10 @@
      * @hide
      */
     public void copyFrom(PrinterCapabilitiesInfo other) {
+        if (this == other) {
+            return;
+        }
+
         mMinMargins = other.mMinMargins;
 
         if (other.mMediaSizes != null) {
@@ -101,8 +104,6 @@
         for (int i = 0; i < defaultCount; i++) {
             mDefaults[i] = other.mDefaults[i];
         }
-
-        mDefaultMargins = other.mDefaultMargins;
     }
 
     /**
@@ -124,7 +125,8 @@
     }
 
     /**
-     * Gets the minimal supported margins.
+     * Gets the minimal margins. These are the minimal margins
+     * the printer physically supports.
      *
      * @return The minimal margins.
      */
@@ -147,27 +149,29 @@
     /**
      * Gets the default print attributes.
      *
-     * @param outAttributes The attributes to populated.
+     * @return The default attributes.
      */
-    public void getDefaults(PrintAttributes outAttributes) {
-        outAttributes.clear();
+    public PrintAttributes getDefaults() {
+        PrintAttributes.Builder builder = new PrintAttributes.Builder();
 
-        outAttributes.setMargins(mDefaultMargins);
+        builder.setMinMargins(mMinMargins);
 
         final int mediaSizeIndex = mDefaults[PROPERTY_MEDIA_SIZE];
         if (mediaSizeIndex >= 0) {
-            outAttributes.setMediaSize(mMediaSizes.get(mediaSizeIndex));
+            builder.setMediaSize(mMediaSizes.get(mediaSizeIndex));
         }
 
         final int resolutionIndex = mDefaults[PROPERTY_RESOLUTION];
         if (resolutionIndex >= 0) {
-            outAttributes.setResolution(mResolutions.get(resolutionIndex));
+            builder.setResolution(mResolutions.get(resolutionIndex));
         }
 
         final int colorMode = mDefaults[PROPERTY_COLOR_MODE];
         if (colorMode > 0) {
-            outAttributes.setColorMode(colorMode);
+            builder.setColorMode(colorMode);
         }
+
+        return builder.build();
     }
 
     private PrinterCapabilitiesInfo(Parcel parcel) {
@@ -178,7 +182,6 @@
         mColorModes = parcel.readInt();
 
         readDefaults(parcel);
-        mDefaultMargins = readMargins(parcel);
     }
 
     @Override
@@ -195,7 +198,6 @@
         parcel.writeInt(mColorModes);
 
         writeDefaults(parcel);
-        writeMargins(mDefaultMargins, parcel);
     }
 
     @Override
@@ -207,7 +209,6 @@
         result = prime * result + ((mResolutions == null) ? 0 : mResolutions.hashCode());
         result = prime * result + mColorModes;
         result = prime * result + Arrays.hashCode(mDefaults);
-        result = prime * result + ((mDefaultMargins == null) ? 0 : mDefaultMargins.hashCode());
         return result;
     }
 
@@ -250,13 +251,6 @@
         if (!Arrays.equals(mDefaults, other.mDefaults)) {
             return false;
         }
-        if (mDefaultMargins == null) {
-            if (other.mDefaultMargins != null) {
-                return false;
-            }
-        } else if (!mDefaultMargins.equals(other.mDefaultMargins)) {
-            return false;
-        }
         return true;
     }
 
@@ -279,7 +273,7 @@
         while (colorModes != 0) {
             final int colorMode = 1 << Integer.numberOfTrailingZeros(colorModes);
             colorModes &= ~colorMode;
-            if (builder.length() > 0) {
+            if (builder.length() > 1) {
                 builder.append(", ");
             }
             builder.append(PrintAttributes.colorModeToString(colorMode));
@@ -442,27 +436,25 @@
         }
 
         /**
-         * Sets the minimal margins.
+         * Sets the minimal margins. These are the minimal margins
+         * the printer physically supports.
+         *
          * <p>
-         * <strong>Required:</strong> No
+         * <strong>Required:</strong> Yes
          * </p>
          *
          * @param margins The margins.
-         * @param defaultMargins The default margins.
          * @return This builder.
          *
+         * @throws IllegalArgumentException If margins are <code>null</code>.
+         *
          * @see PrintAttributes.Margins
          */
-        public Builder setMinMargins(Margins margins, Margins defaultMargins) {
-            if (margins.getLeftMils() > defaultMargins.getLeftMils()
-                    || margins.getTopMils() > defaultMargins.getTopMils()
-                    || margins.getRightMils() < defaultMargins.getRightMils()
-                    || margins.getBottomMils() < defaultMargins.getBottomMils()) {
-                throw new IllegalArgumentException("Default margins"
-                    + " cannot be outside of the min margins.");
+        public Builder setMinMargins(Margins margins) {
+            if (margins == null) {
+                throw new IllegalArgumentException("margins cannot be null");
             }
             mPrototype.mMinMargins = margins;
-            mPrototype.mDefaultMargins = defaultMargins;
             return this;
         }
 
@@ -507,7 +499,7 @@
          *
          * @throws IllegalStateException If a required attribute was not specified.
          */
-        public PrinterCapabilitiesInfo create() {
+        public PrinterCapabilitiesInfo build() {
             if (mPrototype.mMediaSizes == null || mPrototype.mMediaSizes.isEmpty()) {
                 throw new IllegalStateException("No media size specified.");
             }
@@ -527,10 +519,7 @@
                 throw new IllegalStateException("No default color mode specified.");
             }
             if (mPrototype.mMinMargins == null) {
-                mPrototype.mMinMargins  = new Margins(0, 0, 0, 0);
-            }
-            if (mPrototype.mDefaultMargins == null) {
-                mPrototype.mDefaultMargins = mPrototype.mMinMargins;
+                throw new IllegalArgumentException("margins cannot be null");
             }
             return new PrinterCapabilitiesInfo(mPrototype);
         }
diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java
index 0ea319b..a51e28b 100644
--- a/core/java/android/print/PrinterInfo.java
+++ b/core/java/android/print/PrinterInfo.java
@@ -56,6 +56,9 @@
      * @hide
      */
     public void copyFrom(PrinterInfo other) {
+        if (this == other) {
+            return;
+        }
         mId = other.mId;
         mName = other.mName;
         mStatus = other.mStatus;
@@ -293,7 +296,7 @@
          *
          * @return A new {@link PrinterInfo}.
          */
-        public PrinterInfo create() {
+        public PrinterInfo build() {
             return new PrinterInfo(mPrototype);
         }
 
diff --git a/core/java/android/print/pdf/PrintedPdfDocument.java b/core/java/android/print/pdf/PrintedPdfDocument.java
index bee17ef..1fd4646 100644
--- a/core/java/android/print/pdf/PrintedPdfDocument.java
+++ b/core/java/android/print/pdf/PrintedPdfDocument.java
@@ -77,14 +77,14 @@
         mPageSize.set(0, 0, pageWidth, pageHeight);
 
         // Compute the content size from the attributes.
-        Margins margins = attributes.getMargins();
-        final int marginLeft = (int) (((float) margins.getLeftMils() /MILS_PER_INCH)
+        Margins minMargins = attributes.getMinMargins();
+        final int marginLeft = (int) (((float) minMargins.getLeftMils() /MILS_PER_INCH)
                 * POINTS_IN_INCH);
-        final int marginTop = (int) (((float) margins.getTopMils() / MILS_PER_INCH)
+        final int marginTop = (int) (((float) minMargins.getTopMils() / MILS_PER_INCH)
                 * POINTS_IN_INCH);
-        final int marginRight = (int) (((float) margins.getRightMils() / MILS_PER_INCH)
+        final int marginRight = (int) (((float) minMargins.getRightMils() / MILS_PER_INCH)
                 * POINTS_IN_INCH);
-        final int marginBottom = (int) (((float) margins.getBottomMils() / MILS_PER_INCH)
+        final int marginBottom = (int) (((float) minMargins.getBottomMils() / MILS_PER_INCH)
                 * POINTS_IN_INCH);
         mContentSize.set(mPageSize.left + marginLeft, mPageSize.top + marginTop,
                 mPageSize.right - marginRight, mPageSize.bottom - marginBottom);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 3596daa..6bef78e 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -100,7 +100,7 @@
                     }
                 } break;
             }
-            if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY_IF_DEBUGGABLE_BUILD) {
+            if (CHECK_INTEGRITY_IF_DEBUGGABLE_BUILD && Build.IS_DEBUGGABLE) {
                 checkIntegrity();
             }
         }
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 0d7b37d..bb6526e 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -369,11 +369,10 @@
         }
     }
 
-    bool clipToBoundsNeeded = mClipToBounds;
+    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
     if (mAlpha < 1) {
         if (mCaching) {
             ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha);
-            clipToBoundsNeeded = false; // clipping done by layer
         } else if (!mHasOverlappingRendering) {
             ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha);
         } else {
@@ -422,11 +421,10 @@
             renderer.concatMatrix(mTransformMatrix);
         }
     }
-    bool clipToBoundsNeeded = mClipToBounds;
+    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
     if (mAlpha < 1) {
         if (mCaching) {
             renderer.setOverrideLayerAlpha(mAlpha);
-            clipToBoundsNeeded = false; // clipping done by layer
         } else if (!mHasOverlappingRendering) {
             renderer.scaleAlpha(mAlpha);
         } else {
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 4c91bd3..1ef7bff 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -11,7 +11,7 @@
         <!-- TODO: allow rotation when state saving is in better shape -->
         <activity
             android:name=".DocumentsActivity"
-            android:theme="@android:style/Theme.Holo.Light">
+            android:theme="@style/Theme">
             <intent-filter android:priority="100">
                 <action android:name="android.intent.action.OPEN_DOCUMENT" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -39,8 +39,8 @@
 
         <activity
             android:name=".SettingsActivity"
-            android:title="@string/menu_settings"
-            android:theme="@android:style/Theme.Holo.Light"
+            android:label="@string/menu_settings"
+            android:theme="@android:style/Theme.Holo.Light.DialogWhenLarge"
             android:exported="false" />
 
         <provider
diff --git a/packages/DocumentsUI/res/drawable/item_root.xml b/packages/DocumentsUI/res/drawable/item_root.xml
index 183d273..6f201cc 100644
--- a/packages/DocumentsUI/res/drawable/item_root.xml
+++ b/packages/DocumentsUI/res/drawable/item_root.xml
@@ -18,5 +18,5 @@
     <item android:state_pressed="true" android:drawable="@color/item_root_activated" />
     <item android:state_activated="true" android:drawable="@color/item_root_activated" />
     <item android:state_focused="true" android:drawable="@color/item_root_activated" />
-    <item android:drawable="@android:color/white" />
+    <item android:drawable="@android:color/transparent" />
 </selector>
diff --git a/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml b/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
new file mode 100644
index 0000000..3bea166
--- /dev/null
+++ b/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/item_background"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <FrameLayout
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/icon_size"
+        android:layout_height="@dimen/icon_size"
+        android:layout_marginStart="12dp"
+        android:layout_marginEnd="20dp"
+        android:layout_gravity="center_vertical">
+
+        <ImageView
+            android:id="@+id/icon_mime"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerInside"
+            android:contentDescription="@null" />
+
+        <ImageView
+            android:id="@+id/icon_thumb"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"
+            android:contentDescription="@null" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.5"
+            android:layout_marginEnd="12dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Medium" />
+
+        <ImageView
+            android:id="@android:id/icon1"
+            android:layout_width="@dimen/root_icon_size"
+            android:layout_height="@dimen/root_icon_size"
+            android:layout_marginEnd="8dp"
+            android:scaleType="centerInside"
+            android:contentDescription="@null" />
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.25"
+            android:layout_marginEnd="12dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Small" />
+
+        <TextView
+            android:id="@+id/size"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.125"
+            android:layout_marginEnd="12dp"
+            android:minWidth="70dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewEnd"
+            style="@style/TextAppearance.Small" />
+
+        <TextView
+            android:id="@+id/date"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.125"
+            android:layout_marginEnd="12dp"
+            android:minWidth="70dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewEnd"
+            style="@style/TextAppearance.Small" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout-sw720dp/activity.xml b/packages/DocumentsUI/res/layout-sw720dp/activity.xml
new file mode 100644
index 0000000..584a44d
--- /dev/null
+++ b/packages/DocumentsUI/res/layout-sw720dp/activity.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:id="@+id/dialog_roots">
+
+        <FrameLayout
+            android:id="@+id/container_roots"
+            android:layout_width="250dp"
+            android:layout_height="match_parent" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_gravity="end"
+            android:scaleType="fitXY"
+            android:src="@drawable/ic_drawer_shadow_tablet" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+        <FrameLayout
+            android:id="@+id/container_directory"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1" />
+
+        <FrameLayout
+            android:id="@+id/container_save"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
index eea90b5..3cfae64 100644
--- a/packages/DocumentsUI/res/layout/item_doc_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -121,18 +121,6 @@
                 android:textAlignment="viewStart"
                 style="@style/TextAppearance.Small" />
 
-            <TextView
-                android:id="@android:id/summary"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:layout_gravity="center_vertical"
-                android:layout_marginStart="8dp"
-                android:singleLine="true"
-                android:ellipsize="marquee"
-                android:textAlignment="viewStart"
-                style="@style/TextAppearance.Small" />
-
         </LinearLayout>
 
     </LinearLayout>
diff --git a/packages/DocumentsUI/res/values-sw720dp-land/dimens.xml b/packages/DocumentsUI/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..961608c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="always_show_summary">true</bool>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/dimens.xml b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..3be243a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="show_as_dialog">true</bool>
+
+    <item type="dimen" name="dialog_width">85%</item>
+    <item type="dimen" name="dialog_height">90%</item>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
new file mode 100644
index 0000000..4ff1c60
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="Theme" parent="@android:style/Theme.Holo.Light">
+        <item name="android:windowBackground">@*android:drawable/dialog_full_holo_light</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+</resources>
diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml
index e5b5b4e..25b0f84 100644
--- a/packages/DocumentsUI/res/values/dimens.xml
+++ b/packages/DocumentsUI/res/values/dimens.xml
@@ -19,4 +19,7 @@
     <dimen name="root_icon_size">24dp</dimen>
     <dimen name="grid_width">180dp</dimen>
     <dimen name="grid_height">180dp</dimen>
+
+    <bool name="show_as_dialog">false</bool>
+    <bool name="always_show_summary">false</bool>
 </resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 59fbd6f..945e7ae 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
     <style name="TextAppearance" />
 
     <style name="TextAppearance.Medium">
@@ -26,4 +26,8 @@
         <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
         <item name="android:textColor">?android:attr/textColorTertiary</item>
     </style>
+
+    <!-- Normally just a redirection, but this is used to make ourselves a
+         dialog on large tablets -->
+    <style name="Theme" parent="@android:style/Theme.Holo.Light" />
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index ba5a511..b2981db 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -228,7 +228,9 @@
 
                 // Push latest state up to UI
                 // TODO: if mode change was racing with us, don't overwrite it
-                state.derivedMode = result.mode;
+                if (result.mode != MODE_UNKNOWN) {
+                    state.derivedMode = result.mode;
+                }
                 state.derivedSortOrder = result.sortOrder;
                 ((DocumentsActivity) context).onStateChanged();
 
@@ -254,8 +256,8 @@
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
+    public void onResume() {
+        super.onResume();
         updateDisplayState();
     }
 
@@ -272,18 +274,20 @@
         final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
         final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
 
-        final Uri stateUri = RecentsProvider.buildState(
-                root.authority, root.rootId, doc.documentId);
-        final ContentValues values = new ContentValues();
-        values.put(StateColumns.MODE, state.userMode);
+        if (root != null) {
+            final Uri stateUri = RecentsProvider.buildState(
+                    root.authority, root.rootId, doc.documentId);
+            final ContentValues values = new ContentValues();
+            values.put(StateColumns.MODE, state.userMode);
 
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                resolver.insert(stateUri, values);
-                return null;
-            }
-        }.execute();
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    resolver.insert(stateUri, values);
+                    return null;
+                }
+            }.execute();
+        }
 
         // Mode change is just visual change; no need to kick loader, and
         // deliver change event immediately.
@@ -733,23 +737,35 @@
                 icon1.setVisibility(View.VISIBLE);
                 icon1.setImageDrawable(iconDrawable);
 
-                if (iconDrawable != null && roots.isIconUnique(root)) {
-                    // No summary needed if icon speaks for itself
-                    summary.setVisibility(View.INVISIBLE);
-                } else {
-                    summary.setText(root.getDirectoryString());
-                    summary.setVisibility(View.VISIBLE);
-                    summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
-                    hasLine2 = true;
+                if (summary != null) {
+                    final boolean alwaysShowSummary = getResources()
+                            .getBoolean(R.bool.always_show_summary);
+                    if (alwaysShowSummary) {
+                        summary.setText(root.getDirectoryString());
+                        summary.setVisibility(View.VISIBLE);
+                        hasLine2 = true;
+                    } else {
+                        if (iconDrawable != null && roots.isIconUnique(root)) {
+                            // No summary needed if icon speaks for itself
+                            summary.setVisibility(View.INVISIBLE);
+                        } else {
+                            summary.setText(root.getDirectoryString());
+                            summary.setVisibility(View.VISIBLE);
+                            summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
+                            hasLine2 = true;
+                        }
+                    }
                 }
             } else {
                 icon1.setVisibility(View.GONE);
-                if (docSummary != null) {
-                    summary.setText(docSummary);
-                    summary.setVisibility(View.VISIBLE);
-                    hasLine2 = true;
-                } else {
-                    summary.setVisibility(View.INVISIBLE);
+                if (summary != null) {
+                    if (docSummary != null) {
+                        summary.setText(docSummary);
+                        summary.setVisibility(View.VISIBLE);
+                        hasLine2 = true;
+                    } else {
+                        summary.setVisibility(View.INVISIBLE);
+                    }
                 }
             }
 
@@ -772,7 +788,9 @@
                 size.setVisibility(View.GONE);
             }
 
-            line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE);
+            if (line2 != null) {
+                line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE);
+            }
 
             final boolean enabled = Document.MIME_TYPE_DIR.equals(docMimeType)
                     || MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index e89d388..eb51fb5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -22,7 +22,6 @@
 import static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN;
 import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
 import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
-import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
 
 import android.app.ActionBar;
 import android.app.ActionBar.OnNavigationListener;
@@ -36,8 +35,12 @@
 import android.content.ContentValues;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.database.Cursor;
+import android.graphics.Point;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -51,19 +54,20 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MenuItem.OnActionExpandListener;
+import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.SearchView;
-import android.widget.SearchView.OnCloseListener;
 import android.widget.SearchView.OnQueryTextListener;
 import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.documentsui.RecentsProvider.RecentColumns;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
-import com.android.documentsui.RecentsProvider.StateColumns;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.DurableUtils;
@@ -79,15 +83,18 @@
 public class DocumentsActivity extends Activity {
     public static final String TAG = "Documents";
 
-    private SearchView mSearchView;
-
-    private View mRootsContainer;
-    private DrawerLayout mDrawerLayout;
-    private ActionBarDrawerToggle mDrawerToggle;
-
     private static final String EXTRA_STATE = "state";
 
+    private boolean mShowAsDialog;
+
+    private SearchView mSearchView;
+
+    private DrawerLayout mDrawerLayout;
+    private ActionBarDrawerToggle mDrawerToggle;
+    private View mRootsContainer;
+
     private boolean mIgnoreNextNavigation;
+    private boolean mIgnoreNextClose;
     private boolean mIgnoreNextCollapse;
 
     private RootsCache mRoots;
@@ -102,15 +109,60 @@
         setResult(Activity.RESULT_CANCELED);
         setContentView(R.layout.activity);
 
-        mRootsContainer = findViewById(R.id.container_roots);
+        final Resources res = getResources();
+        mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
 
-        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
+        if (mShowAsDialog) {
+            // backgroundDimAmount from theme isn't applied; do it manually
+            final WindowManager.LayoutParams a = getWindow().getAttributes();
+            a.dimAmount = 0.6f;
+            getWindow().setAttributes(a);
 
-        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
-                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
+            getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
+            getWindow().setFlags(~0, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
 
-        mDrawerLayout.setDrawerListener(mDrawerListener);
-        mDrawerLayout.setDrawerShadow(R.drawable.ic_drawer_shadow, GravityCompat.START);
+            // Inset ourselves to look like a dialog
+            final Point size = new Point();
+            getWindowManager().getDefaultDisplay().getSize(size);
+
+            final int width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
+            final int height = (int) res.getFraction(R.dimen.dialog_height, size.y, size.y);
+            final int insetX = (size.x - width) / 2;
+            final int insetY = (size.y - height) / 2;
+
+            final Drawable before = getWindow().getDecorView().getBackground();
+            final Drawable after = new InsetDrawable(before, insetX, insetY, insetX, insetY);
+            getWindow().getDecorView().setBackground(after);
+
+            // Dismiss when touch down in the dimmed inset area
+            getWindow().getDecorView().setOnTouchListener(new OnTouchListener() {
+                @Override
+                public boolean onTouch(View v, MotionEvent event) {
+                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                        final float x = event.getX();
+                        final float y = event.getY();
+                        if (x < insetX || x > v.getWidth() - insetX || y < insetY
+                                || y > v.getHeight() - insetY) {
+                            finish();
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+            });
+
+        } else {
+            // Non-dialog means we have a drawer
+            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
+
+            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
+                    R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
+
+            mDrawerLayout.setDrawerListener(mDrawerListener);
+            mDrawerLayout.setDrawerShadow(R.drawable.ic_drawer_shadow, GravityCompat.START);
+
+            mRootsContainer = findViewById(R.id.container_roots);
+        }
 
         if (icicle != null) {
             mState = icicle.getParcelable(EXTRA_STATE);
@@ -118,8 +170,13 @@
             buildDefaultState();
         }
 
+        // Hide roots when we're managing a specific root
         if (mState.action == ACTION_MANAGE) {
-            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+            if (mShowAsDialog) {
+                findViewById(R.id.dialog_roots).setVisibility(View.GONE);
+            } else {
+                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+            }
         }
 
         if (mState.action == ACTION_CREATE) {
@@ -210,14 +267,14 @@
 
             // Only open drawer when showing recents
             if (mState.stack.isRecents()) {
-                mDrawerLayout.openDrawer(mRootsContainer);
+                setRootsDrawerOpen(true);
             }
         }
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
+    public void onResume() {
+        super.onResume();
 
         if (mState.action == ACTION_MANAGE) {
             mState.showSize = true;
@@ -255,7 +312,27 @@
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
-        mDrawerToggle.syncState();
+        if (mDrawerToggle != null) {
+            mDrawerToggle.syncState();
+        }
+    }
+
+    public void setRootsDrawerOpen(boolean open) {
+        if (!mShowAsDialog) {
+            if (open) {
+                mDrawerLayout.openDrawer(mRootsContainer);
+            } else {
+                mDrawerLayout.closeDrawer(mRootsContainer);
+            }
+        }
+    }
+
+    private boolean isRootsDrawerOpen() {
+        if (mShowAsDialog) {
+            return false;
+        } else {
+            return mDrawerLayout.isDrawerOpen(mRootsContainer);
+        }
     }
 
     public void updateActionBar() {
@@ -263,15 +340,13 @@
 
         actionBar.setDisplayShowHomeEnabled(true);
 
-        if (mState.action == ACTION_MANAGE) {
-            actionBar.setDisplayHomeAsUpEnabled(false);
-            mDrawerToggle.setDrawerIndicatorEnabled(false);
-        } else {
-            actionBar.setDisplayHomeAsUpEnabled(true);
-            mDrawerToggle.setDrawerIndicatorEnabled(true);
+        final boolean showIndicator = !mShowAsDialog && (mState.action != ACTION_MANAGE);
+        actionBar.setDisplayHomeAsUpEnabled(showIndicator);
+        if (mDrawerToggle != null) {
+            mDrawerToggle.setDrawerIndicatorEnabled(showIndicator);
         }
 
-        if (mDrawerLayout.isDrawerOpen(mRootsContainer)) {
+        if (isRootsDrawerOpen()) {
             actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
             actionBar.setIcon(new ColorDrawable());
 
@@ -302,12 +377,20 @@
         super.onCreateOptionsMenu(menu);
         getMenuInflater().inflate(R.menu.activity, menu);
 
+        // Actions are always visible when showing as dialog
+        if (mShowAsDialog) {
+            for (int i = 0; i < menu.size(); i++) {
+                menu.getItem(i).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+            }
+        }
+
         final MenuItem searchMenu = menu.findItem(R.id.menu_search);
         mSearchView = (SearchView) searchMenu.getActionView();
         mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
             @Override
             public boolean onQueryTextSubmit(String query) {
                 mState.currentSearch = query;
+                mSearchView.clearFocus();
                 onCurrentDirectoryChanged();
                 return true;
             }
@@ -337,6 +420,20 @@
             }
         });
 
+        mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
+            @Override
+            public boolean onClose() {
+                if (mIgnoreNextClose) {
+                    mIgnoreNextClose = false;
+                    return false;
+                }
+
+                mState.currentSearch = null;
+                onCurrentDirectoryChanged();
+                return false;
+            }
+        });
+
         return true;
     }
 
@@ -356,7 +453,7 @@
         final MenuItem settings = menu.findItem(R.id.menu_settings);
 
         // Open drawer means we hide most actions
-        if (mDrawerLayout.isDrawerOpen(mRootsContainer)) {
+        if (isRootsDrawerOpen()) {
             createDir.setVisible(false);
             search.setVisible(false);
             sort.setVisible(false);
@@ -367,23 +464,24 @@
             return true;
         }
 
-        if (cwd != null) {
-            sort.setVisible(true);
-            grid.setVisible(mState.derivedMode != MODE_GRID);
-            list.setVisible(mState.derivedMode != MODE_LIST);
-        } else {
-            sort.setVisible(false);
-            grid.setVisible(false);
-            list.setVisible(false);
-        }
+        sort.setVisible(cwd != null);
+        grid.setVisible(mState.derivedMode != MODE_GRID);
+        list.setVisible(mState.derivedMode != MODE_LIST);
 
         if (mState.currentSearch != null) {
             // Search uses backend ranking; no sorting
             sort.setVisible(false);
 
             search.expandActionView();
+
+            mSearchView.setIconified(false);
+            mSearchView.clearFocus();
             mSearchView.setQuery(mState.currentSearch, false);
         } else {
+            mIgnoreNextClose = true;
+            mSearchView.setIconified(true);
+            mSearchView.clearFocus();
+
             mIgnoreNextCollapse = true;
             search.collapseActionView();
         }
@@ -418,7 +516,7 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if (mDrawerToggle.onOptionsItemSelected(item)) {
+        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
             return true;
         }
 
@@ -488,7 +586,7 @@
         if (size > 1) {
             mState.stack.pop();
             onCurrentDirectoryChanged();
-        } else if (size == 1 && !mDrawerLayout.isDrawerOpen(mRootsContainer)) {
+        } else if (size == 1 && !isRootsDrawerOpen()) {
             // TODO: open root drawer once we can capture back key
             super.onBackPressed();
         } else {
@@ -614,6 +712,12 @@
                 RecentsCreateFragment.show(fm);
             } else {
                 DirectoryFragment.showRecentsOpen(fm);
+
+                // Start recents in relevant mode
+                final boolean acceptImages = MimePredicate.mimeMatches(
+                        "image/*", mState.acceptMimes);
+                mState.userMode = acceptImages ? MODE_GRID : MODE_LIST;
+                mState.derivedMode = mState.userMode;
             }
         } else {
             if (mState.currentSearch != null) {
@@ -666,7 +770,7 @@
         }
 
         if (closeDrawer) {
-            mDrawerLayout.closeDrawers();
+            setRootsDrawerOpen(false);
         }
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
index 57442a0..a7173b6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
@@ -17,8 +17,6 @@
 package com.android.documentsui;
 
 import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
-import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
 import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
 
 import android.content.AsyncTaskLoader;
@@ -194,9 +192,6 @@
         }
 
         final DirectoryResult result = new DirectoryResult();
-
-        final boolean acceptImages = MimePredicate.mimeMatches("image/*", mAcceptMimes);
-        result.mode = acceptImages ? MODE_GRID : MODE_LIST;
         result.sortOrder = SORT_ORDER_LAST_MODIFIED;
 
         if (cursors.size() > 0) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index f3a21c6..54dcf1c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -86,8 +86,8 @@
     }
 
     @Override
-    public void onStart() {
-        super.onStart();
+    public void onResume() {
+        super.onResume();
         updateRootsAdapter();
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java
index ceeaaae..a85f6a9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.documentsui;
 
+import android.app.ActionBar;
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
@@ -39,8 +40,14 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
         getFragmentManager()
                 .beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
+
+        final ActionBar bar = getActionBar();
+        if (bar != null) {
+            bar.setDisplayShowHomeEnabled(false);
+        }
     }
 
     public static class SettingsFragment extends PreferenceFragment {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
index e47bf0c..0431b94 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
@@ -455,7 +455,7 @@
 
                 PrinterInfo.Builder builder = new PrinterInfo.Builder(printerId, name, status);
                 builder.setDescription(description);
-                PrinterInfo printer = builder.create();
+                PrinterInfo printer = builder.build();
 
                 outPrinters.add(printer);
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 514e8ca..5c3d700 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -147,9 +147,8 @@
 
     public static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {PageRange.ALL_PAGES};
 
-    private final PrintAttributes mOldPrintAttributes = new PrintAttributes.Builder().create();
-    private final PrintAttributes mCurrPrintAttributes = new PrintAttributes.Builder().create();
-    private final PrintAttributes mTempPrintAttributes = new PrintAttributes.Builder().create();
+    private final PrintAttributes mOldPrintAttributes = new PrintAttributes.Builder().build();
+    private final PrintAttributes mCurrPrintAttributes = new PrintAttributes.Builder().build();
 
     private final DeathRecipient mDeathRecipient = new DeathRecipient() {
         @Override
@@ -851,19 +850,19 @@
                     Resolution oldResolution = mCurrPrintAttributes.getResolution();
                     Resolution newResolution = new Resolution(
                             oldResolution.getId(),
-                            oldResolution.getLabel(getPackageManager()),
+                            oldResolution.getLabel(),
                             oldResolution.getVerticalDpi(),
                             oldResolution.getHorizontalDpi());
                     mCurrPrintAttributes.setResolution(newResolution);
 
                     // Rotate the physical margins.
-                    Margins oldMargins = mCurrPrintAttributes.getMargins();
-                    Margins newMargins = new Margins(
-                            oldMargins.getBottomMils(),
-                            oldMargins.getLeftMils(),
-                            oldMargins.getTopMils(),
-                            oldMargins.getRightMils());
-                    mCurrPrintAttributes.setMargins(newMargins);
+                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
+                    Margins newMinMargins = new Margins(
+                            oldMinMargins.getBottomMils(),
+                            oldMinMargins.getLeftMils(),
+                            oldMinMargins.getTopMils(),
+                            oldMinMargins.getRightMils());
+                    mCurrPrintAttributes.setMinMargins(newMinMargins);
                 }
             } else {
                 if (mediaSize.isPortrait()) {
@@ -874,26 +873,25 @@
                     Resolution oldResolution = mCurrPrintAttributes.getResolution();
                     Resolution newResolution = new Resolution(
                             oldResolution.getId(),
-                            oldResolution.getLabel(getPackageManager()),
+                            oldResolution.getLabel(),
                             oldResolution.getVerticalDpi(),
                             oldResolution.getHorizontalDpi());
                     mCurrPrintAttributes.setResolution(newResolution);
 
                     // Rotate the physical margins.
-                    Margins oldMargins = mCurrPrintAttributes.getMargins();
+                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
                     Margins newMargins = new Margins(
-                            oldMargins.getTopMils(),
-                            oldMargins.getRightMils(),
-                            oldMargins.getBottomMils(),
-                            oldMargins.getLeftMils());
-                    mCurrPrintAttributes.setMargins(newMargins);
+                            oldMinMargins.getTopMils(),
+                            oldMinMargins.getRightMils(),
+                            oldMinMargins.getBottomMils(),
+                            oldMinMargins.getLeftMils());
+                    mCurrPrintAttributes.setMinMargins(newMargins);
                 }
             }
         }
 
         private void updatePrintAttributes(PrinterCapabilitiesInfo capabilities) {
-            PrintAttributes defaults = mTempPrintAttributes;
-            capabilities.getDefaults(defaults);
+            PrintAttributes defaults = capabilities.getDefaults();
 
             // Media size.
             MediaSize currMediaSize = mCurrPrintAttributes.getMediaSize();
@@ -925,16 +923,16 @@
             }
 
             // Margins.
-            Margins margins = mCurrPrintAttributes.getMargins();
+            Margins margins = mCurrPrintAttributes.getMinMargins();
             if (margins == null) {
-                mCurrPrintAttributes.setMargins(defaults.getMargins());
+                mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
             } else {
                 Margins minMargins = capabilities.getMinMargins();
                 if (margins.getLeftMils() < minMargins.getLeftMils()
                         || margins.getTopMils() < minMargins.getTopMils()
                         || margins.getRightMils() > minMargins.getRightMils()
                         || margins.getBottomMils() > minMargins.getBottomMils()) {
-                    mCurrPrintAttributes.setMargins(defaults.getMargins());
+                    mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
                 }
             }
         }
@@ -1633,8 +1631,7 @@
 
                 PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
                 PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
-                PrintAttributes defaultAttributes = mTempPrintAttributes;
-                printer.getCapabilities().getDefaults(defaultAttributes);
+                PrintAttributes defaultAttributes = printer.getCapabilities().getDefaults();
 
                 // Media size.
                 List<MediaSize> mediaSizes = capabilities.getMediaSizes();
@@ -2069,12 +2066,12 @@
                     .setColorModes(PrintAttributes.COLOR_MODE_COLOR
                             | PrintAttributes.COLOR_MODE_MONOCHROME,
                             PrintAttributes.COLOR_MODE_COLOR)
-                    .create();
+                    .build();
 
                 return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf),
                         PrinterInfo.STATUS_IDLE)
                     .setCapabilities(capabilities)
-                    .create();
+                    .build();
             }
         }
     }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
index 76e548a..8580fcd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
@@ -839,11 +839,11 @@
                             serializer.attribute(null, ATTR_VERTICAL_DPI, String.valueOf(
                                     resolution.getVerticalDpi()));
                             serializer.attribute(null, ATTR_LABEL,
-                                    resolution.getLabel(getPackageManager()));
+                                    resolution.getLabel());
                             serializer.endTag(null, TAG_RESOLUTION);
                         }
 
-                        Margins margins = attributes.getMargins();
+                        Margins margins = attributes.getMinMargins();
                         if (margins != null) {
                             serializer.startTag(null, TAG_MARGINS);
                             serializer.attribute(null, ATTR_LEFT_MILS, String.valueOf(
@@ -1056,14 +1056,14 @@
                     final int bottomMils = Integer.parseInt(parser.getAttributeValue(null,
                             ATTR_BOTTOM_MILS));
                     Margins margins = new Margins(leftMils, topMils, rightMils, bottomMils);
-                    builder.setMargins(margins);
+                    builder.setMinMargins(margins);
                     parser.next();
                     skipEmptyTextTags(parser);
                     expect(parser, XmlPullParser.END_TAG, TAG_MARGINS);
                     parser.next();
                 }
 
-                printJob.setAttributes(builder.create());
+                printJob.setAttributes(builder.build());
 
                 skipEmptyTextTags(parser);
                 expect(parser, XmlPullParser.END_TAG, TAG_ATTRIBUTES);
@@ -1079,7 +1079,7 @@
                         ATTR_CONTENT_TYPE));
                 PrintDocumentInfo info = new PrintDocumentInfo.Builder(name)
                         .setPageCount(pageCount)
-                        .setContentType(contentType).create();
+                        .setContentType(contentType).build();
                 printJob.setDocumentInfo(info);
                 parser.next();
                 skipEmptyTextTags(parser);
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index 70fe370..86a5aed 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -433,7 +433,6 @@
         return false;
     }
 
-
     private boolean readEnabledPrintServicesLocked() {
         Set<ComponentName> tempEnabledServiceNameSet = new HashSet<ComponentName>();
         readPrintServicesFromSettingLocked(Settings.Secure.ENABLED_PRINT_SERVICES,