Tweak the print APIs.

1. Adding bundle with metadata to PrintDocumentAdapter#onLayout
   with one key for now to specify whether this is for a preview.

2. Cleaned up docs.

Change-Id: I89380781bf3ae41aa89f8a0347d74516a210394c
diff --git a/api/current.txt b/api/current.txt
index e0025ea..53b2258 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18562,9 +18562,10 @@
   public abstract class PrintDocumentAdapter {
     ctor public PrintDocumentAdapter();
     method public void onFinish();
-    method public abstract void onLayout(android.print.PrintAttributes, android.print.PrintAttributes, android.os.CancellationSignal, android.print.PrintDocumentAdapter.LayoutResultCallback);
+    method public abstract void onLayout(android.print.PrintAttributes, android.print.PrintAttributes, android.os.CancellationSignal, android.print.PrintDocumentAdapter.LayoutResultCallback, android.os.Bundle);
     method public void onStart();
     method public abstract void onWrite(java.util.List<android.print.PageRange>, java.io.FileDescriptor, android.os.CancellationSignal, android.print.PrintDocumentAdapter.WriteResultCallback);
+    field public static final java.lang.String METADATA_KEY_PRINT_PREVIEW = "KEY_METADATA_PRINT_PREVIEW";
   }
 
   public static abstract class PrintDocumentAdapter.LayoutResultCallback {
diff --git a/core/java/android/print/FileDocumentAdapter.java b/core/java/android/print/FileDocumentAdapter.java
index 2871d45..c7011f4 100644
--- a/core/java/android/print/FileDocumentAdapter.java
+++ b/core/java/android/print/FileDocumentAdapter.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.AsyncTask;
+import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.CancellationSignal.OnCancelListener;
 import android.util.Log;
@@ -59,7 +60,8 @@
 
     @Override
     public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
-            CancellationSignal cancellationSignal, LayoutResultCallback callback) {
+            CancellationSignal cancellationSignal, LayoutResultCallback callback,
+            Bundle metadata) {
         // TODO: When we have a PDF rendering library we should query the page count.
         PrintDocumentInfo info =  new PrintDocumentInfo.Builder()
         .setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN).create();
diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl
index 36938e3..04da157 100644
--- a/core/java/android/print/IPrintDocumentAdapter.aidl
+++ b/core/java/android/print/IPrintDocumentAdapter.aidl
@@ -16,6 +16,7 @@
 
 package android.print;
 
+import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.print.ILayoutResultCallback;
 import android.print.IWriteResultCallback;
@@ -30,7 +31,7 @@
 oneway interface IPrintDocumentAdapter {
     void start();
     void layout(in PrintAttributes oldAttributes, in PrintAttributes newAttributes,
-            ILayoutResultCallback callback);
+            ILayoutResultCallback callback, in Bundle metadata);
     void write(in List<PageRange> pages, in ParcelFileDescriptor fd,
             IWriteResultCallback callback);
     void finish();
diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java
index ef69400..1f83a45 100644
--- a/core/java/android/print/PrintDocumentAdapter.java
+++ b/core/java/android/print/PrintDocumentAdapter.java
@@ -16,6 +16,7 @@
 
 package android.print;
 
+import android.os.Bundle;
 import android.os.CancellationSignal;
 
 import java.io.FileDescriptor;
@@ -33,14 +34,14 @@
  * </li>
  * <li>
  * Next, you will get one or more calls to {@link #onLayout(PrintAttributes,
- * PrintAttributes, CancellationSignal, LayoutResultCallback)} to inform you
- * that the print attributes (page size, density, etc) changed giving you an
- * opportunity to layout the content to match the new constraints.
+ * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} to
+ * inform you that the print attributes (page size, density, etc) changed
+ * giving you an opportunity to layout the content to match the new constraints.
  * </li>
  * <li>
  * After every call to {@link #onLayout(PrintAttributes, PrintAttributes,
- * CancellationSignal, LayoutResultCallback)}, you may get a call to {@link
- * #onWrite(List, FileDescriptor, CancellationSignal, WriteResultCallback)}
+ * CancellationSignal, LayoutResultCallback, Bundle)}, you may get a call to
+ * {@link #onWrite(List, FileDescriptor, CancellationSignal, WriteResultCallback)}
  * asking you to write a PDF file with the content for specific pages.
  * </li>
  * <li>
@@ -49,10 +50,38 @@
  * </li>
  * </ul>
  * </p>
+ * <h3>Implementation</h3>
+ * <p>
+ * The APIs defined in this class are designed to enable doing part or all
+ * of the work on an arbitrary thread. For example, if the printed content
+ * does not depend on the UI state, i.e. on what is shown on the screen, then
+ * you can off load the entire work on a dedicated thread, thus making your
+ * application interactive while the print work is being performed.
+ * </p>
+ * <p>
+ * You can also do work on different threads, for example if you print UI
+ * content, you can handle {@link #onStart()} and {@link #onLayout(PrintAttributes,
+ * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} on
+ * the UI thread (assuming onStart initializes resources needed for layout).
+ * This will ensure that the UI does not change while you are laying out the
+ * printed content. Then you can handle {@link #onWrite(List, FileDescriptor,
+ * CancellationSignal, WriteResultCallback)} and {@link #onFinish()} on another
+ * thread. This will ensure that the UI is frozen for the minimal amount of
+ * time. Also this assumes that you will generate the printed content in
+ * {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
+ * LayoutResultCallback, Bundle)} which is not mandatory. If you use multiple
+ * threads, you are responsible for proper synchronization.
+ * </p>
  */
 public abstract class PrintDocumentAdapter {
 
     /**
+     * Meta-data key: mapped to a boolean value that is <code>true</code> if
+     * the current layout is for a print preview, <code>false</code> otherwise.
+     */
+    public static final String METADATA_KEY_PRINT_PREVIEW = "KEY_METADATA_PRINT_PREVIEW";
+
+    /**
      * Called when printing starts. You can use this callback to allocate
      * resources. This method is invoked on the main thread.
      */
@@ -65,11 +94,11 @@
      * giving you a chance to layout the content such that it matches the
      * new constraints. This method is invoked on the main thread.
      * <p>
-     * After you are done laying out, you must invoke: {@link LayoutResultCallback
-     * #onLayoutFinished(PrintDocumentInfo, boolean)} with the last argument <code>true
-     * </code> or <code>false</code> depending on whether the layout changed the
-     * content or not, respectively; and {@link LayoutResultCallback#onLayoutFailed(
-     * CharSequence), if an error occurred.
+     * After you are done laying out, you <strong>must</strong> invoke: {@link
+     * LayoutResultCallback#onLayoutFinished(PrintDocumentInfo, boolean)} with
+     * the last argument <code>true</code> or <code>false</code> depending on
+     * whether the layout changed the content or not, respectively; and {@link
+     * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred.
      * </p>
      * <p>
      * <strong>Note:</strong> If the content is large and a layout will be
@@ -84,12 +113,15 @@
      * @param newAttributes The new print attributes.
      * @param cancellationSignal Signal for observing cancel layout requests.
      * @param callback Callback to inform the system for the layout result.
+     * @param metadata Additional information about how layout the content.
      *
      * @see LayoutResultCallback
      * @see CancellationSignal
+     * @see #METADATA_KEY_PRINT_PREVIEW
      */
     public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
-            CancellationSignal cancellationSignal, LayoutResultCallback callback);
+            CancellationSignal cancellationSignal, LayoutResultCallback callback,
+            Bundle metadata);
 
     /**
      * Called when specific pages of the content should be written in the
@@ -98,7 +130,7 @@
      *<p>
      * After you are done writing, you should <strong>not</strong> close the
      * file descriptor, rather you must invoke: {@link WriteResultCallback
-     * #onWriteFinished()}, if writing completed successfully; or {@link
+     * #onWriteFinished(List)}, if writing completed successfully; or {@link
      * WriteResultCallback#onWriteFailed(CharSequence)}, if an error occurred.
      * </p>
      * <p>
@@ -165,7 +197,7 @@
     /**
      * Base class for implementing a callback for the result of {@link
      * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes,
-     * CancellationSignal, LayoutResultCallback)}.
+     * CancellationSignal, LayoutResultCallback, Bundle)}.
      */
     public static abstract class LayoutResultCallback {
 
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 5ca19d4..58f45fa 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.IntentSender;
 import android.content.IntentSender.SendIntentException;
+import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.ICancellationSignal;
@@ -233,12 +234,13 @@
         }
 
         @Override
-        public void layout(PrintAttributes oldAttributes,
-            PrintAttributes newAttributes, ILayoutResultCallback callback) {
+        public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+                ILayoutResultCallback callback, Bundle metadata) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = oldAttributes;
             args.arg2 = newAttributes;
             args.arg3 = callback;
+            args.arg4 = metadata;
             mHandler.obtainMessage(MyHandler.MSG_LAYOUT, args).sendToTarget();
         }
 
@@ -292,6 +294,7 @@
                         PrintAttributes oldAttributes = (PrintAttributes) args.arg1;
                         PrintAttributes newAttributes = (PrintAttributes) args.arg2;
                         ILayoutResultCallback callback = (ILayoutResultCallback) args.arg3;
+                        Bundle metadata = (Bundle) args.arg4;
                         args.recycle();
 
                         try {
@@ -300,7 +303,7 @@
 
                             mDocumentAdapter.onLayout(oldAttributes, newAttributes,
                                     CancellationSignal.fromTransport(remoteSignal),
-                                    new LayoutResultCallbackWrapper(callback));
+                                    new LayoutResultCallbackWrapper(callback), metadata);
                         } catch (RemoteException re) {
                             Log.e(LOG_TAG, "Error printing", re);
                         }
diff --git a/core/java/android/print/pdf/PdfDocument.java b/core/java/android/print/pdf/PdfDocument.java
index 7ce036d..cfeb975 100644
--- a/core/java/android/print/pdf/PdfDocument.java
+++ b/core/java/android/print/pdf/PdfDocument.java
@@ -56,7 +56,7 @@
  * // finish the page
  * document.finishPage(page);
  * . . .
- * add more pages
+ * // add more pages
  * . . .
  * // write the document content
  * document.writeTo(getOutputStream());
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 659102c..c0faed8 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -536,6 +536,7 @@
         // TODO: Implement old attributes tracking
         mPrintSpooler.setPrintJobAttributes(mPrintJobId, mPrintAttributes);
 
+        // TODO: Implement setting the print preview attribute
         mRemotePrintAdapter.layout(new PrintAttributes.Builder().create(),
                 mPrintAttributes, new LayoutResultCallback() {
             @Override
@@ -566,7 +567,7 @@
                 Log.e(LOG_TAG, "Error during layout: " + error);
                 finishActivity(Activity.RESULT_CANCELED);
             }
-        });
+        }, new Bundle());
     }
 
     private void notifyPrintableFinishIfNeeded() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
index 912dd95..7186932 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
@@ -17,6 +17,7 @@
 package com.android.printspooler;
 
 import android.os.AsyncTask;
+import android.os.Bundle;
 import android.os.ICancellationSignal;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -31,8 +32,6 @@
 import android.util.Log;
 import android.util.Slog;
 
-import libcore.io.IoUtils;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -42,6 +41,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import libcore.io.IoUtils;
+
 /**
  * This class represents a remote print document adapter instance.
  */
@@ -122,8 +123,9 @@
     }
 
     public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
-            LayoutResultCallback callback) {
-        LayoutAsyncTask task = new LayoutAsyncTask(oldAttributes, newAttributes, callback);
+            LayoutResultCallback callback, Bundle metadata) {
+        LayoutAsyncTask task = new LayoutAsyncTask(oldAttributes, newAttributes, callback,
+                metadata);
         synchronized (mLock) {
             mTaskQueue.add(task);
             task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
@@ -181,6 +183,8 @@
 
         private final LayoutResultCallback mCallback;
 
+        private final Bundle mMetadata;
+
         private final ILayoutResultCallback mILayoutResultCallback =
                 new ILayoutResultCallback.Stub() {
             @Override
@@ -219,11 +223,12 @@
 
         private boolean mCompleted;
 
-        public LayoutAsyncTask(PrintAttributes oldAttributes,
-                PrintAttributes newAttributes, LayoutResultCallback callback) {
+        public LayoutAsyncTask(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+                LayoutResultCallback callback, Bundle metadata) {
             mOldAttributes = oldAttributes;
             mNewAttributes = newAttributes;
             mCallback = callback;
+            mMetadata = metadata;
         }
 
         @Override
@@ -246,7 +251,7 @@
             }
             try {
                 mRemoteInterface.layout(mOldAttributes, mNewAttributes,
-                        mILayoutResultCallback);
+                        mILayoutResultCallback, mMetadata);
                 synchronized (mLock) {
                     while (true) {
                         if (isCancelled()) {