Merge "Crash in print spooler if printing app killed from recents." into lmp-mr1-dev automerge: 7cf7c36
automerge: fb7c62c

* commit 'fb7c62c143d210b9ecd01c3054ae2dfbd0dda2b6':
  Crash in print spooler if printing app killed from recents.
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index 85b2490..acc2b69 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -110,13 +110,12 @@
         mRenderer.close(callback);
     }
 
-    public void destroy(Runnable callback) {
-        throwIfNotClosed();
+    public void destroy() {
         mState = STATE_DESTROYED;
         if (DEBUG) {
             Log.i(LOG_TAG, "STATE_DESTROYED");
         }
-        doDestroy(callback);
+        mRenderer.destroy();
     }
 
     public void startPreload(int firstShownPage, int lastShownPage) {
@@ -163,21 +162,13 @@
         try {
             if (mState != STATE_DESTROYED) {
                 mCloseGuard.warnIfOpen();
-                doDestroy(null);
+                destroy();
             }
         } finally {
             super.finalize();
         }
     }
 
-    private void doDestroy(Runnable callback) {
-        mState = STATE_DESTROYED;
-        if (DEBUG) {
-            Log.i(LOG_TAG, "STATE_DESTROYED");
-        }
-        mRenderer.destroy(callback);
-    }
-
     private void throwIfNotOpened() {
         if (mState != STATE_OPENED) {
             throw new IllegalStateException("Not opened");
@@ -428,6 +419,7 @@
         private IPdfRenderer mRenderer;
 
         private boolean mBoundToService;
+        private boolean mDestroyed;
 
         public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) {
             mContext = context;
@@ -441,7 +433,6 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            mBoundToService = true;
             synchronized (mLock) {
                 mRenderer = IPdfRenderer.Stub.asInterface(service);
                 mLock.notifyAll();
@@ -465,9 +456,14 @@
             new AsyncTask<Void, Void, Integer>() {
                 @Override
                 protected void onPreExecute() {
+                    if (mDestroyed) {
+                        cancel(true);
+                        return;
+                    }
                     Intent intent = new Intent(PdfManipulationService.ACTION_GET_RENDERER);
                     intent.setClass(mContext, PdfManipulationService.class);
                     mContext.bindService(intent, AsyncRenderer.this, Context.BIND_AUTO_CREATE);
+                    mBoundToService = true;
                 }
 
                 @Override
@@ -513,6 +509,14 @@
 
             new AsyncTask<Void, Void, Void>() {
                 @Override
+                protected void onPreExecute() {
+                    if (mDestroyed) {
+                        cancel(true);
+                        return;
+                    }
+                }
+
+                @Override
                 protected Void doInBackground(Void... params) {
                     synchronized (mLock) {
                         try {
@@ -534,27 +538,14 @@
             }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
         }
 
-        public void destroy(final Runnable callback) {
-            new AsyncTask<Void, Void, Void>() {
-                @Override
-                protected Void doInBackground(Void... params) {
-                    return null;
-                }
-
-                @Override
-                public void onPostExecute(Void result) {
-                    if (mBoundToService) {
-                        mBoundToService = false;
-                        mContext.unbindService(AsyncRenderer.this);
-                    }
-                    mPageContentCache.invalidate();
-                    mPageContentCache.clear();
-                    if (callback != null) {
-                        callback.run();
-                    }
-
-                }
-            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+        public void destroy() {
+            if (mBoundToService) {
+                mBoundToService = false;
+                mContext.unbindService(AsyncRenderer.this);
+            }
+            mPageContentCache.invalidate();
+            mPageContentCache.clear();
+            mDestroyed = true;
         }
 
         public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 045a2f9..2cc5e04 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -78,7 +78,7 @@
 
     private static final boolean DEBUG_PERSISTENCE = false;
 
-    private static final boolean PERSISTNECE_MANAGER_ENABLED = true;
+    private static final boolean PERSISTENCE_MANAGER_ENABLED = true;
 
     private static final long CHECK_ALL_PRINTJOBS_HANDLED_DELAY = 5000;
 
@@ -728,7 +728,7 @@
         }
 
         public void writeStateLocked() {
-            if (!PERSISTNECE_MANAGER_ENABLED) {
+            if (!PERSISTENCE_MANAGER_ENABLED) {
                 return;
             }
             if (mWriteStateScheduled) {
@@ -935,7 +935,7 @@
         }
 
         public void readStateLocked() {
-            if (!PERSISTNECE_MANAGER_ENABLED) {
+            if (!PERSISTENCE_MANAGER_ENABLED) {
                 return;
             }
             FileInputStream in = null;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index c53fcad..f6ace41 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -137,7 +137,7 @@
     private final DeathRecipient mDeathRecipient = new DeathRecipient() {
         @Override
         public void binderDied() {
-            notifyPrintingAppDied();
+            onPrintingAppDied();
         }
     };
 
@@ -268,7 +268,7 @@
             mPrintDocumentAdapter.finish();
             mState = STATE_FINISHED;
         } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error calling finish()", re);
+            Log.e(LOG_TAG, "Error calling finish()");
             mState = STATE_FAILED;
         }
     }
@@ -1108,7 +1108,8 @@
         }
     }
 
-    private void notifyPrintingAppDied() {
+    private void onPrintingAppDied() {
+        mState = STATE_FAILED;
         new Handler(mLooper).post(new Runnable() {
             @Override
             public void run() {
@@ -1129,7 +1130,7 @@
         public void onDestroy() {
             final RemotePrintDocument document = mWeakDocument.get();
             if (document != null) {
-                document.notifyPrintingAppDied();
+                document.onPrintingAppDied();
             }
         }
     }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index fbf7204..aa79568 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -484,9 +484,13 @@
         return selectedPages;
     }
 
-    public void destroy(Runnable callback) {
-        throwIfNotClosed();
-        doDestroy(callback);
+    public void destroy() {
+        mPageContentRepository.destroy();
+        mCloseGuard.close();
+        mState = STATE_DESTROYED;
+        if (DEBUG) {
+            Log.i(LOG_TAG, "STATE_DESTROYED");
+        }
     }
 
     @Override
@@ -494,7 +498,7 @@
         try {
             if (mState != STATE_DESTROYED) {
                 mCloseGuard.warnIfOpen();
-                doDestroy(null);
+                destroy();
             }
         } finally {
             super.finalize();
@@ -741,15 +745,6 @@
         mPageContentRepository.stopPreload();
     }
 
-    private void doDestroy(Runnable callback) {
-        mPageContentRepository.destroy(callback);
-        mCloseGuard.close();
-        mState = STATE_DESTROYED;
-        if (DEBUG) {
-            Log.i(LOG_TAG, "STATE_DESTROYED");
-        }
-    }
-
     private void throwIfNotOpened() {
         if (mState != STATE_OPENED) {
             throw new IllegalStateException("Not opened");
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 21c8b83..15ea9a7 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -1616,15 +1616,9 @@
             mSpoolerProvider.destroy();
             mPrintedDocument.finish();
             mPrintedDocument.destroy();
-            mPrintPreviewController.destroy(new Runnable() {
-                @Override
-                public void run() {
-                    finish();
-                }
-            });
-        } else {
-            finish();
+            mPrintPreviewController.destroy();
         }
+        finish();
     }
 
     private final class SpinnerItem<T> {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
index e4eab10..15342ae 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
@@ -192,15 +192,10 @@
         });
     }
 
-    public void destroy(Runnable callback) {
-        if (mPageAdapter.isOpened()) {
-            Message operation = mHandler.obtainMessage(MyHandler.MSG_CLOSE);
-            mHandler.enqueueOperation(operation);
-        }
-
-        Message operation = mHandler.obtainMessage(MyHandler.MSG_DESTROY);
-        operation.obj = callback;
-        mHandler.enqueueOperation(operation);
+    public void destroy() {
+        mHandler.cancelQueuedOperations();
+        mRecyclerView.setAdapter(null);
+        mPageAdapter.destroy();
     }
 
     @Override
@@ -226,7 +221,6 @@
     private final class MyHandler extends Handler {
         public static final int MSG_OPEN = 1;
         public static final int MSG_CLOSE = 2;
-        public static final int MSG_DESTROY = 3;
         public static final int MSG_UPDATE = 4;
         public static final int MSG_START_PRELOAD = 5;
 
@@ -246,6 +240,10 @@
             super(looper, null, false);
         }
 
+        public void cancelQueuedOperations() {
+            mPendingOperations.clear();
+        }
+
         public void enqueueOperation(Message message) {
             mPendingOperations.add(message);
             handleNextOperation();
@@ -294,13 +292,6 @@
                     });
                 } break;
 
-                case MSG_DESTROY: {
-                    Runnable callback = (Runnable) message.obj;
-                    mRecyclerView.setAdapter(null);
-                    mPageAdapter.destroy(callback);
-                    handleNextOperation();
-                } break;
-
                 case MSG_UPDATE: {
                     SomeArgs args = (SomeArgs) message.obj;
                     PageRange[] writtenPages = (PageRange[]) args.arg1;