Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4237c92d authored by Svet Ganov's avatar Svet Ganov
Browse files

Crash in print spooler if printing app killed from recents.

If the printing app with the print UI on top is killed from recents we get
a crash because: 1) the remote print document was not transitioned to a
failed state if the printing app dies (this is an unrecoverable failure);
2) the print preview controller was destroyed asyncronosly during which it
also asynchronously disconnects from the rendering service which however
happens after the system has already cleaned up all connections of the print
UI activity as it is being destoryed.

bug:18109386

Change-Id: If6200b14a8aa90622228bbb659e9c4962226f561
parent bd6fabe2
Loading
Loading
Loading
Loading
+25 −34
Original line number Diff line number Diff line
@@ -110,13 +110,12 @@ public final class PageContentRepository {
        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 @@ public final class PageContentRepository {
        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 @@ public final class PageContentRepository {
        private IPdfRenderer mRenderer;

        private boolean mBoundToService;
        private boolean mDestroyed;

        public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) {
            mContext = context;
@@ -441,7 +433,6 @@ public final class PageContentRepository {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBoundToService = true;
            synchronized (mLock) {
                mRenderer = IPdfRenderer.Stub.asInterface(service);
                mLock.notifyAll();
@@ -465,9 +456,14 @@ public final class PageContentRepository {
            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
@@ -512,6 +508,14 @@ public final class PageContentRepository {
            cancelAllRendering();

            new AsyncTask<Void, Void, Void>() {
                @Override
                protected void onPreExecute() {
                    if (mDestroyed) {
                        cancel(true);
                        return;
                    }
                }

                @Override
                protected Void doInBackground(Void... params) {
                    synchronized (mLock) {
@@ -534,27 +538,14 @@ public final class PageContentRepository {
            }.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) {
        public void destroy() {
            if (mBoundToService) {
                mBoundToService = false;
                mContext.unbindService(AsyncRenderer.this);
            }
            mPageContentCache.invalidate();
            mPageContentCache.clear();
                    if (callback != null) {
                        callback.run();
                    }

                }
            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
            mDestroyed = true;
        }

        public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) {
+3 −3
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public final class PrintSpoolerService extends Service {

    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 final class PrintSpoolerService extends Service {
        }

        public void writeStateLocked() {
            if (!PERSISTNECE_MANAGER_ENABLED) {
            if (!PERSISTENCE_MANAGER_ENABLED) {
                return;
            }
            if (mWriteStateScheduled) {
@@ -935,7 +935,7 @@ public final class PrintSpoolerService extends Service {
        }

        public void readStateLocked() {
            if (!PERSISTNECE_MANAGER_ENABLED) {
            if (!PERSISTENCE_MANAGER_ENABLED) {
                return;
            }
            FileInputStream in = null;
+5 −4
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ public final class RemotePrintDocument {
    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
        @Override
        public void binderDied() {
            notifyPrintingAppDied();
            onPrintingAppDied();
        }
    };

@@ -268,7 +268,7 @@ public final class RemotePrintDocument {
            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 @@ public final class RemotePrintDocument {
        }
    }

    private void notifyPrintingAppDied() {
    private void onPrintingAppDied() {
        mState = STATE_FAILED;
        new Handler(mLooper).post(new Runnable() {
            @Override
            public void run() {
@@ -1129,7 +1130,7 @@ public final class RemotePrintDocument {
        public void onDestroy() {
            final RemotePrintDocument document = mWeakDocument.get();
            if (document != null) {
                document.notifyPrintingAppDied();
                document.onPrintingAppDied();
            }
        }
    }
+8 −13
Original line number Diff line number Diff line
@@ -484,9 +484,13 @@ public final class PageAdapter extends Adapter implements
        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 @@ public final class PageAdapter extends Adapter implements
        try {
            if (mState != STATE_DESTROYED) {
                mCloseGuard.warnIfOpen();
                doDestroy(null);
                destroy();
            }
        } finally {
            super.finalize();
@@ -741,15 +745,6 @@ public final class PageAdapter extends Adapter implements
        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");
+2 −8
Original line number Diff line number Diff line
@@ -1616,16 +1616,10 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
            mSpoolerProvider.destroy();
            mPrintedDocument.finish();
            mPrintedDocument.destroy();
            mPrintPreviewController.destroy(new Runnable() {
                @Override
                public void run() {
                    finish();
            mPrintPreviewController.destroy();
        }
            });
        } else {
        finish();
    }
    }

    private final class SpinnerItem<T> {
        final T value;
Loading