summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/print/IPrintDocumentAdapter.aidl1
-rw-r--r--core/java/android/print/PrintManager.java21
-rw-r--r--core/jni/android/graphics/pdf/PdfEditor.cpp13
-rw-r--r--core/jni/android/graphics/pdf/PdfRenderer.cpp13
-rw-r--r--graphics/java/android/graphics/pdf/PdfEditor.java4
-rw-r--r--graphics/java/android/graphics/pdf/PdfRenderer.java4
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java37
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java47
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java12
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java10
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java29
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java13
12 files changed, 165 insertions, 39 deletions
diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl
index 9d384fb..8f33e0b 100644
--- a/core/java/android/print/IPrintDocumentAdapter.aidl
+++ b/core/java/android/print/IPrintDocumentAdapter.aidl
@@ -37,4 +37,5 @@ oneway interface IPrintDocumentAdapter {
void write(in PageRange[] pages, in ParcelFileDescriptor fd,
IWriteResultCallback callback, int sequence);
void finish();
+ void kill(String reason);
}
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index bf8ac65..3fb812e 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -634,6 +634,17 @@ public final class PrintManager {
}
@Override
+ public void kill(String reason) {
+ synchronized (mLock) {
+ // If destroyed the handler is null.
+ if (!isDestroyedLocked()) {
+ mHandler.obtainMessage(MyHandler.MSG_ON_KILL,
+ reason).sendToTarget();
+ }
+ }
+ }
+
+ @Override
public void onActivityPaused(Activity activity) {
/* do nothing */
}
@@ -719,6 +730,7 @@ public final class PrintManager {
public static final int MSG_ON_LAYOUT = 2;
public static final int MSG_ON_WRITE = 3;
public static final int MSG_ON_FINISH = 4;
+ public static final int MSG_ON_KILL = 5;
public MyHandler(Looper looper) {
super(looper, null, true);
@@ -794,6 +806,15 @@ public final class PrintManager {
}
} break;
+ case MSG_ON_KILL: {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "onKill()");
+ }
+
+ String reason = (String) message.obj;
+ throw new RuntimeException(reason);
+ }
+
default: {
throw new IllegalArgumentException("Unknown message: "
+ message.what);
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index 2b756e2..ed6f1d6 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -89,8 +89,17 @@ static jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) {
if (!document) {
const long error = FPDF_GetLastError();
- jniThrowException(env, "java/io/IOException",
- "cannot create document. Error:" + error);
+ switch (error) {
+ case FPDF_ERR_PASSWORD:
+ case FPDF_ERR_SECURITY: {
+ jniThrowException(env, "java/lang/SecurityException",
+ "cannot create document. Error:" + error);
+ } break;
+ default: {
+ jniThrowException(env, "java/io/IOException",
+ "cannot create document. Error:" + error);
+ } break;
+ }
destroyLibraryIfNeeded();
return -1;
}
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index 303ddea..357d3c0 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -82,8 +82,17 @@ static jlong nativeCreate(JNIEnv* env, jclass thiz, jint fd, jlong size) {
if (!document) {
const long error = FPDF_GetLastError();
- jniThrowException(env, "java/io/IOException",
- "cannot create document. Error:" + error);
+ switch (error) {
+ case FPDF_ERR_PASSWORD:
+ case FPDF_ERR_SECURITY: {
+ jniThrowException(env, "java/lang/SecurityException",
+ "cannot create document. Error:" + error);
+ } break;
+ default: {
+ jniThrowException(env, "java/io/IOException",
+ "cannot create document. Error:" + error);
+ } break;
+ }
destroyLibraryIfNeeded();
return -1;
}
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index 0b84d29..2b70b6a 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -59,6 +59,10 @@ public final class PdfEditor {
*
* @param input Seekable file descriptor to read from.
*
+ * @throws java.io.IOException If an error occurs while reading the file.
+ * @throws java.lang.SecurityException If the file requires a password or
+ * the security scheme is not supported.
+ *
* @see #close()
*/
public PdfEditor(@NonNull ParcelFileDescriptor input) throws IOException {
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 359c294..79934da 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -131,6 +131,10 @@ public final class PdfRenderer implements AutoCloseable {
* </p>
*
* @param input Seekable file descriptor to read from.
+ *
+ * @throws java.io.IOException If an error occurs while reading the file.
+ * @throws java.lang.SecurityException If the file requires a password or
+ * the security scheme is not supported.
*/
public PdfRenderer(@NonNull ParcelFileDescriptor input) throws IOException {
if (input == null) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java b/packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java
new file mode 100644
index 0000000..50f424a
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/OpenDocumentCallback.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printspooler.model;
+
+/**
+ * Callbacks interface for opening a file.
+ */
+public interface OpenDocumentCallback {
+ public static final int ERROR_MALFORMED_PDF_FILE = -1;
+ public static final int ERROR_SECURE_PDF_FILE = -2;
+
+ /**
+ * Called after the file is opened.
+ */
+ public void onSuccess();
+
+ /**
+ * Called after opening the file failed.
+ *
+ * @param error The error.
+ */
+ public void onFailure(int error);
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index 35930cd..882b364 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -78,13 +78,8 @@ public final class PageContentRepository {
public void onPageContentAvailable(BitmapDrawable content);
}
- public interface OnMalformedPdfFileListener {
- public void onMalformedPdfFile();
- }
-
- public PageContentRepository(Context context,
- OnMalformedPdfFileListener malformedPdfFileListener) {
- mRenderer = new AsyncRenderer(context, malformedPdfFileListener);
+ public PageContentRepository(Context context) {
+ mRenderer = new AsyncRenderer(context);
mState = STATE_CLOSED;
if (DEBUG) {
Log.i(LOG_TAG, "STATE_CLOSED");
@@ -92,7 +87,7 @@ public final class PageContentRepository {
mCloseGuard.open("destroy");
}
- public void open(ParcelFileDescriptor source, final Runnable callback) {
+ public void open(ParcelFileDescriptor source, final OpenDocumentCallback callback) {
throwIfNotClosed();
mState = STATE_OPENED;
if (DEBUG) {
@@ -412,8 +407,6 @@ public final class PageContentRepository {
private final ArrayMap<Integer, RenderPageTask> mPageToRenderTaskMap = new ArrayMap<>();
- private final OnMalformedPdfFileListener mOnMalformedPdfFileListener;
-
private int mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
@GuardedBy("mLock")
@@ -422,9 +415,8 @@ public final class PageContentRepository {
private boolean mBoundToService;
private boolean mDestroyed;
- public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) {
+ public AsyncRenderer(Context context) {
mContext = context;
- mOnMalformedPdfFileListener = malformedPdfFileListener;
ActivityManager activityManager = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -447,7 +439,7 @@ public final class PageContentRepository {
}
}
- public void open(final ParcelFileDescriptor source, final Runnable callback) {
+ public void open(final ParcelFileDescriptor source, final OpenDocumentCallback callback) {
// Opening a new document invalidates the cache as it has pages
// from the last document. We keep the cache even when the document
// is closed to show pages while the other side is writing the new
@@ -483,7 +475,7 @@ public final class PageContentRepository {
return mRenderer.openDocument(source);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Cannot open PDF document");
- return PdfManipulationService.MALFORMED_PDF_FILE_ERROR;
+ return PdfManipulationService.ERROR_MALFORMED_PDF_FILE;
} finally {
// Close the fd as we passed it to another process
// which took ownership.
@@ -494,14 +486,25 @@ public final class PageContentRepository {
@Override
public void onPostExecute(Integer pageCount) {
- if (pageCount == PdfManipulationService.MALFORMED_PDF_FILE_ERROR) {
- mOnMalformedPdfFileListener.onMalformedPdfFile();
- mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
- } else {
- mPageCount = pageCount;
- }
- if (callback != null) {
- callback.run();
+ switch (pageCount) {
+ case PdfManipulationService.ERROR_MALFORMED_PDF_FILE: {
+ mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
+ if (callback != null) {
+ callback.onFailure(OpenDocumentCallback.ERROR_MALFORMED_PDF_FILE);
+ }
+ } break;
+ case PdfManipulationService.ERROR_SECURE_PDF_FILE: {
+ mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
+ if (callback != null) {
+ callback.onFailure(OpenDocumentCallback.ERROR_SECURE_PDF_FILE);
+ }
+ } break;
+ default: {
+ mPageCount = pageCount;
+ if (callback != null) {
+ callback.onSuccess();
+ }
+ } break;
}
}
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index f6ace41..1b6e9ce 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -304,6 +304,18 @@ public final class RemotePrintDocument {
disconnectFromRemoteDocument();
}
+ public void kill(String reason) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "[CALLED] kill()");
+ }
+
+ try {
+ mPrintDocumentAdapter.kill(reason);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling kill()", re);
+ }
+ }
+
public boolean isUpdating() {
return mState == STATE_UPDATING || mState == STATE_CANCELING;
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
index 0462e4d..7db2074 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
@@ -47,7 +47,9 @@ public final class PdfManipulationService extends Service {
public static final String ACTION_GET_EDITOR =
"com.android.printspooler.renderer.ACTION_GET_EDITOR";
- public static final int MALFORMED_PDF_FILE_ERROR = -2;
+ public static final int ERROR_MALFORMED_PDF_FILE = -2;
+
+ public static final int ERROR_SECURE_PDF_FILE = -3;
private static final String LOG_TAG = "PdfManipulationService";
private static final boolean DEBUG = false;
@@ -90,7 +92,11 @@ public final class PdfManipulationService extends Service {
} catch (IOException | IllegalStateException e) {
IoUtils.closeQuietly(source);
Log.e(LOG_TAG, "Cannot open file", e);
- return MALFORMED_PDF_FILE_ERROR;
+ return ERROR_MALFORMED_PDF_FILE;
+ } catch (SecurityException e) {
+ IoUtils.closeQuietly(source);
+ Log.e(LOG_TAG, "Cannot open file", e);
+ return ERROR_SECURE_PDF_FILE;
}
}
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index aa79568..0d2e736 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -37,6 +37,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.View.MeasureSpec;
import android.widget.TextView;
import com.android.printspooler.R;
+import com.android.printspooler.model.OpenDocumentCallback;
import com.android.printspooler.model.PageContentRepository;
import com.android.printspooler.model.PageContentRepository.PageContentProvider;
import com.android.printspooler.util.PageRangeUtils;
@@ -51,8 +52,7 @@ import java.util.List;
/**
* This class represents the adapter for the pages in the print preview list.
*/
-public final class PageAdapter extends Adapter implements
- PageContentRepository.OnMalformedPdfFileListener {
+public final class PageAdapter extends Adapter {
private static final String LOG_TAG = "PageAdapter";
private static final int MAX_PREVIEW_PAGES_BATCH = 50;
@@ -113,6 +113,7 @@ public final class PageAdapter extends Adapter implements
public interface ContentCallbacks {
public void onRequestContentUpdate();
public void onMalformedPdfFile();
+ public void onSecurePdfFile();
}
public interface PreviewArea {
@@ -127,7 +128,7 @@ public final class PageAdapter extends Adapter implements
mCallbacks = callbacks;
mLayoutInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- mPageContentRepository = new PageContentRepository(context, this);
+ mPageContentRepository = new PageContentRepository(context);
mPreviewPageMargin = mContext.getResources().getDimensionPixelSize(
R.dimen.preview_page_margin);
@@ -156,11 +157,6 @@ public final class PageAdapter extends Adapter implements
}
}
- @Override
- public void onMalformedPdfFile() {
- mCallbacks.onMalformedPdfFile();
- }
-
public void onOrientationChanged() {
mColumnCount = mContext.getResources().getInteger(
R.integer.preview_page_per_row_count);
@@ -181,12 +177,25 @@ public final class PageAdapter extends Adapter implements
if (DEBUG) {
Log.i(LOG_TAG, "STATE_OPENED");
}
- mPageContentRepository.open(source, new Runnable() {
+ mPageContentRepository.open(source, new OpenDocumentCallback() {
@Override
- public void run() {
+ public void onSuccess() {
notifyDataSetChanged();
callback.run();
}
+
+ @Override
+ public void onFailure(int error) {
+ switch (error) {
+ case OpenDocumentCallback.ERROR_MALFORMED_PDF_FILE: {
+ mCallbacks.onMalformedPdfFile();
+ } break;
+
+ case OpenDocumentCallback.ERROR_SECURE_PDF_FILE: {
+ mCallbacks.onSecurePdfFile();
+ } break;
+ }
+ }
});
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index f361884..b76a9cd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -378,7 +378,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
return true;
}
- if (mState == STATE_PRINT_CANCELED ||mState == STATE_PRINT_CONFIRMED
+ if (mState == STATE_PRINT_CANCELED || mState == STATE_PRINT_CONFIRMED
|| mState == STATE_PRINT_COMPLETED) {
return true;
}
@@ -405,12 +405,23 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
@Override
public void onMalformedPdfFile() {
+ onPrintDocumentError("Cannot print a malformed PDF file");
+ }
+
+ @Override
+ public void onSecurePdfFile() {
+ onPrintDocumentError("Cannot print a password protected PDF file");
+ }
+
+ private void onPrintDocumentError(String message) {
mProgressMessageController.cancel();
ensureErrorUiShown(null, PrintErrorFragment.ACTION_RETRY);
setState(STATE_UPDATE_FAILED);
updateOptionsUi();
+
+ mPrintedDocument.kill(message);
}
@Override