summaryrefslogtreecommitdiffstats
path: root/packages/PrintSpooler/src
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2013-10-17 22:20:40 -0700
committerSvetoslav Ganov <svetoslavganov@google.com>2013-10-18 13:12:06 -0700
commit858a1850e2e1c4516129d27ecdf54aaeade606ca (patch)
tree2f5d1c2a61b5e131e842f148dba7bd90d2a7845c /packages/PrintSpooler/src
parentb346270dde839029f9d4994cf2c3fc670a4249a6 (diff)
downloadframeworks_base-858a1850e2e1c4516129d27ecdf54aaeade606ca.zip
frameworks_base-858a1850e2e1c4516129d27ecdf54aaeade606ca.tar.gz
frameworks_base-858a1850e2e1c4516129d27ecdf54aaeade606ca.tar.bz2
Hide the print dialog if the printing activity is destroyed.
1. For an app to print it creates a PrintDocumentAdapter implementation which is passed to the print dialog activity. If the activity that created the adapter is destroyed then the adapter, which may rely on the activity state, may be in an invalid state. For example, an app creates an adapter and calls print resuting in the app activity and the print dialog activity being stacked. Now the user rotates the device which triggers the recreating of the activity stack (assume the app does not handle rotation). The recreated print dialog activity receives the intent that originally created it with containing the adapter that was constructed in the context of the old, now destroyed, app activity instance. To handle this we are limiting an app to be able to print only from and activity and when this activity is destroyed we mark the adapter as invalid which will result in hiding the print dialog activity. Note that if the app process is killed we already handle this in the print dialog activiy by registering a death recipient on the adapter binder. 2. In the PrintManager.PrintDocumentAdapterDelegate some of the state is accessed only on the main thread and some from miltiple threads. The code was trying to avoid locking for state that is not accessed by multiple threads but this is error prone and the benefit does not justify the complexity and added fragility. Now grabbing a lock all the time. 3. The PrintJobConfigActivity waits for it to bind to the print spooler service before instantiating its print controller and editor. However, these can be accessed by invoking some of the activity cycle callbacks. This change is adding null checks for the case where the activity callbacks are called before the binding to the spooler is completed. bug:11242661 Change-Id: Id906b3170e4f0a0553772dfa62686f06fdca0eaf
Diffstat (limited to 'packages/PrintSpooler/src')
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java71
1 files changed, 56 insertions, 15 deletions
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 2997707..c90cb1f 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -40,6 +40,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.print.ILayoutResultCallback;
import android.print.IPrintDocumentAdapter;
+import android.print.IPrintDocumentAdapterObserver;
import android.print.IWriteResultCallback;
import android.print.PageRange;
import android.print.PrintAttributes;
@@ -201,6 +202,14 @@ public class PrintJobConfigActivity extends Activity {
throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
}
+ try {
+ IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter)
+ .setObserver(new PrintDocumentAdapterObserver(this));
+ } catch (RemoteException re) {
+ finish();
+ return;
+ }
+
PrintAttributes attributes = printJob.getAttributes();
if (attributes != null) {
mCurrPrintAttributes.copyFrom(attributes);
@@ -249,27 +258,29 @@ public class PrintJobConfigActivity extends Activity {
// We can safely do the work in here since at this point
// the system is bound to our (spooler) process which
// guarantees that this process will not be killed.
- if (mController.hasStarted()) {
+ if (mController != null && mController.hasStarted()) {
mController.finish();
}
- if (mEditor.isPrintConfirmed() && mController.isFinished()) {
- mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
- PrintJobInfo.STATE_QUEUED, null);
+ if (mEditor != null && mEditor.isPrintConfirmed()
+ && mController != null && mController.isFinished()) {
+ mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
+ PrintJobInfo.STATE_QUEUED, null);
} else {
mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId,
PrintJobInfo.STATE_CANCELED, null);
}
- mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0);
if (mGeneratingPrintJobDialog != null) {
mGeneratingPrintJobDialog.dismiss();
mGeneratingPrintJobDialog = null;
}
+ mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0);
mSpoolerProvider.destroy();
super.onDestroy();
}
public boolean onTouchEvent(MotionEvent event) {
- if (!mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) {
+ if (mController != null && mEditor != null &&
+ !mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) {
if (!mController.isWorking()) {
PrintJobConfigActivity.this.finish();
}
@@ -287,17 +298,19 @@ public class PrintJobConfigActivity extends Activity {
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- if (mEditor.isShwoingGeneratingPrintJobUi()) {
- return true;
- }
- if (event.isTracking() && !event.isCanceled()) {
- if (!mController.isWorking()) {
- PrintJobConfigActivity.this.finish();
+ if (mController != null && mEditor != null) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (mEditor.isShwoingGeneratingPrintJobUi()) {
+ return true;
+ }
+ if (event.isTracking() && !event.isCanceled()) {
+ if (!mController.isWorking()) {
+ PrintJobConfigActivity.this.finish();
+ }
}
+ mEditor.cancel();
+ return true;
}
- mEditor.cancel();
- return true;
}
return super.onKeyUp(keyCode, event);
}
@@ -2703,4 +2716,32 @@ public class PrintJobConfigActivity extends Activity {
/* do noting - we are in the same process */
}
}
+
+ private static final class PrintDocumentAdapterObserver
+ extends IPrintDocumentAdapterObserver.Stub {
+ private final WeakReference<PrintJobConfigActivity> mWeakActvity;
+
+ public PrintDocumentAdapterObserver(PrintJobConfigActivity activity) {
+ mWeakActvity = new WeakReference<PrintJobConfigActivity>(activity);
+ }
+
+ @Override
+ public void onDestroy() {
+ final PrintJobConfigActivity activity = mWeakActvity.get();
+ if (activity != null) {
+ activity.mController.mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (activity.mController != null) {
+ activity.mController.cancel();
+ }
+ if (activity.mEditor != null) {
+ activity.mEditor.cancel();
+ }
+ activity.finish();
+ }
+ });
+ }
+ }
+ }
}