summaryrefslogtreecommitdiff
path: root/packages/PrintSpooler/src
diff options
context:
space:
mode:
author Nathan Muggli <nmuggli@google.com> 2025-01-07 15:42:39 -0700
committer Nathan Muggli <nmuggli@google.com> 2025-01-24 11:06:00 -0700
commit97540c5405df864771163386a1e651a70bbcfe6f (patch)
tree9f6826ffc6deef89b241167bd62e9194eaeb48e9 /packages/PrintSpooler/src
parent732153ffe93f9b8d5ab68dfa64a90e70d84e3a6e (diff)
Add new invalid state to print spooler
When a PDF file is invalid (corrupt PDF file, password-protected, etc) and can't be rendered, switch to an invalid state. No further updates happen when the file is known to be invalid and the spooler is in an invalid state. This prevents a crash where an update was trying to be performed when in the finished state. Additionally, don't allow the user to attempt to restart a print job with an invalid file since it will simply fail again. Bug: 389956791 Flag: EXEMPT bug fix Test: Manual test on akita and brya with password-protected file Change-Id: I8217463ba3d43a7b898019bdc84443cc43f9d042
Diffstat (limited to 'packages/PrintSpooler/src')
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java5
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java17
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java43
3 files changed, 57 insertions, 8 deletions
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index fe27cee7ba2d..acead8e2a0eb 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -510,7 +510,10 @@ public final class PageContentRepository {
protected Void doInBackground(Void... params) {
synchronized (mLock) {
try {
- if (mRenderer != null) {
+ // A page count < 0 indicates there was an error
+ // opening the document, in which case it doesn't
+ // need to be closed.
+ if (mRenderer != null && mPageCount >= 0) {
mRenderer.closeDocument();
}
} catch (RemoteException re) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index b48c55ddfef0..a9d00e9a77eb 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -70,6 +70,7 @@ public final class RemotePrintDocument {
private static final int STATE_CANCELING = 6;
private static final int STATE_CANCELED = 7;
private static final int STATE_DESTROYED = 8;
+ private static final int STATE_INVALID = 9;
private final Context mContext;
@@ -287,7 +288,8 @@ public final class RemotePrintDocument {
}
if (mState != STATE_STARTED && mState != STATE_UPDATED
&& mState != STATE_FAILED && mState != STATE_CANCELING
- && mState != STATE_CANCELED && mState != STATE_DESTROYED) {
+ && mState != STATE_CANCELED && mState != STATE_DESTROYED
+ && mState != STATE_INVALID) {
throw new IllegalStateException("Cannot finish in state:"
+ stateToString(mState));
}
@@ -300,6 +302,16 @@ public final class RemotePrintDocument {
}
}
+ /**
+ * Mark this document as invalid.
+ */
+ public void invalid() {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "[CALLED] invalid()");
+ }
+ mState = STATE_INVALID;
+ }
+
public void cancel(boolean force) {
if (DEBUG) {
Log.i(LOG_TAG, "[CALLED] cancel(" + force + ")");
@@ -491,6 +503,9 @@ public final class RemotePrintDocument {
case STATE_DESTROYED: {
return "STATE_DESTROYED";
}
+ case STATE_INVALID: {
+ return "STATE_INVALID";
+ }
default: {
return "STATE_UNKNOWN";
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 4a3a6d248254..2e3234e6e622 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -167,6 +167,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
private static final int STATE_PRINTER_UNAVAILABLE = 6;
private static final int STATE_UPDATE_SLOW = 7;
private static final int STATE_PRINT_COMPLETED = 8;
+ private static final int STATE_FILE_INVALID = 9;
private static final int UI_STATE_PREVIEW = 0;
private static final int UI_STATE_ERROR = 1;
@@ -404,6 +405,11 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
public void onPause() {
PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
+ if (isInvalid()) {
+ super.onPause();
+ return;
+ }
+
if (mState == STATE_INITIALIZING) {
if (isFinishing()) {
if (spooler != null) {
@@ -478,7 +484,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
if (mState == STATE_PRINT_CANCELED || mState == STATE_PRINT_CONFIRMED
- || mState == STATE_PRINT_COMPLETED) {
+ || mState == STATE_PRINT_COMPLETED
+ || mState == STATE_FILE_INVALID) {
return true;
}
@@ -509,23 +516,32 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
@Override
public void onMalformedPdfFile() {
onPrintDocumentError("Cannot print a malformed PDF file");
+ mPrintedDocument.invalid();
+ setState(STATE_FILE_INVALID);
}
@Override
public void onSecurePdfFile() {
onPrintDocumentError("Cannot print a password protected PDF file");
+ mPrintedDocument.invalid();
+ setState(STATE_FILE_INVALID);
}
private void onPrintDocumentError(String message) {
setState(mProgressMessageController.cancel());
- ensureErrorUiShown(null, PrintErrorFragment.ACTION_RETRY);
+ ensureErrorUiShown(
+ getString(R.string.print_cannot_load_page), PrintErrorFragment.ACTION_NONE);
setState(STATE_UPDATE_FAILED);
if (DEBUG) {
Log.i(LOG_TAG, "PrintJob state[" + PrintJobInfo.STATE_FAILED + "] reason: " + message);
}
PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
- spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_FAILED, message);
+ // Use a cancel state for the spooler. This will prevent the notification from getting
+ // displayed and will remove the job. The notification (which displays the cancel and
+ // restart options) doesn't make sense for an invalid document since it will just fail
+ // again.
+ spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, message);
mPrintedDocument.finish();
}
@@ -995,6 +1011,9 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
private void setState(int state) {
+ if (isInvalid()) {
+ return;
+ }
if (isFinalState(mState)) {
if (isFinalState(state)) {
if (DEBUG) {
@@ -1015,7 +1034,12 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
private static boolean isFinalState(int state) {
return state == STATE_PRINT_CANCELED
|| state == STATE_PRINT_COMPLETED
- || state == STATE_CREATE_FILE_FAILED;
+ || state == STATE_CREATE_FILE_FAILED
+ || state == STATE_FILE_INVALID;
+ }
+
+ private boolean isInvalid() {
+ return mState == STATE_FILE_INVALID;
}
private void updateSelectedPagesFromPreview() {
@@ -1100,7 +1124,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
private void ensurePreviewUiShown() {
- if (isFinishing() || isDestroyed()) {
+ if (isFinishing() || isDestroyed() || isInvalid()) {
return;
}
if (mUiState != UI_STATE_PREVIEW) {
@@ -1257,6 +1281,9 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
private boolean updateDocument(boolean clearLastError) {
+ if (isInvalid()) {
+ return false;
+ }
if (!clearLastError && mPrintedDocument.hasUpdateError()) {
return false;
}
@@ -1676,7 +1703,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
|| mState == STATE_UPDATE_FAILED
|| mState == STATE_CREATE_FILE_FAILED
|| mState == STATE_PRINTER_UNAVAILABLE
- || mState == STATE_UPDATE_SLOW) {
+ || mState == STATE_UPDATE_SLOW
+ || mState == STATE_FILE_INVALID) {
disableOptionsUi(isFinalState(mState));
return;
}
@@ -2100,6 +2128,9 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
}
private boolean canUpdateDocument() {
+ if (isInvalid()) {
+ return false;
+ }
if (mPrintedDocument.isDestroyed()) {
return false;
}