summaryrefslogtreecommitdiffstats
path: root/core/java/android/print/PrintManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/print/PrintManager.java')
-rw-r--r--core/java/android/print/PrintManager.java399
1 files changed, 399 insertions, 0 deletions
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
new file mode 100644
index 0000000..df14a5c
--- /dev/null
+++ b/core/java/android/print/PrintManager.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2013 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 android.print;
+
+import android.content.Context;
+import android.content.IntentSender;
+import android.content.IntentSender.SendIntentException;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.ICancellationSignal;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.PrintAdapter.PrintProgressCallback;
+import android.util.Log;
+
+import com.android.internal.os.SomeArgs;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * System level service for accessing the printing capabilities of the platform.
+ * <p>
+ * To obtain a handle to the print manager do the following:
+ * </p>
+ * <pre>
+ * PrintManager printManager =
+ * (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
+ * </pre>
+ */
+public final class PrintManager {
+
+ private static final String LOG_TAG = "PrintManager";
+
+ /** @hide */
+ public static final int APP_ID_ANY = -2;
+
+ private final Context mContext;
+
+ private final IPrintManager mService;
+
+ private final int mUserId;
+
+ private final int mAppId;
+
+ private final PrintClient mPrintClient;
+
+ private final Handler mHandler;
+
+ /**
+ * Listener for the state of a print job.
+ */
+ public static interface PrintJobStateListener {
+ public void onStateChanged(int state);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param context The current context in which to operate.
+ * @param service The backing system service.
+ *
+ * @hide
+ */
+ public PrintManager(Context context, IPrintManager service, int userId, int appId) {
+ mContext = context;
+ mService = service;
+ mUserId = userId;
+ mAppId = appId;
+ mPrintClient = new PrintClient(this);
+ mHandler = new Handler(context.getMainLooper(), null, false) {
+ @Override
+ public void handleMessage(Message message) {
+ SomeArgs args = (SomeArgs) message.obj;
+ Context context = (Context) args.arg1;
+ IntentSender intent = (IntentSender) args.arg2;
+ args.recycle();
+ try {
+ context.startIntentSender(intent, null, 0, 0, 0);
+ } catch (SendIntentException sie) {
+ Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
+ }
+ }
+ };
+ }
+
+ /**
+ * Creates an instance that can access all print jobs.
+ *
+ * @param userId The user id for which to get all print jobs.
+ * @return An instance of the caller has the permission to access
+ * all print jobs, null otherwise.
+ *
+ * @hide
+ */
+ public PrintManager getGlobalPrintManagerForUser(int userId) {
+ return new PrintManager(mContext, mService, userId, APP_ID_ANY);
+ }
+
+ PrintJobInfo getPrintJob(int printJobId) {
+ try {
+ return mService.getPrintJob(printJobId, mAppId, mUserId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error getting print job:" + printJobId, re);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the print jobs for this application.
+ *
+ * @return The print job list.
+ *
+ * @see PrintJob
+ */
+ public List<PrintJob> getPrintJobs() {
+ try {
+ List<PrintJobInfo> printJobInfos = mService.getPrintJobs(mAppId, mUserId);
+ if (printJobInfos == null) {
+ return Collections.emptyList();
+ }
+ final int printJobCount = printJobInfos.size();
+ List<PrintJob> printJobs = new ArrayList<PrintJob>(printJobCount);
+ for (int i = 0; i < printJobCount; i++) {
+ printJobs.add(new PrintJob(printJobInfos.get(i), this));
+ }
+ return printJobs;
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error getting print jobs!", re);
+ }
+ return Collections.emptyList();
+ }
+
+ ICancellationSignal cancelPrintJob(int printJobId) {
+ try {
+ mService.cancelPrintJob(printJobId, mAppId, mUserId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error cancleing a print job:" + printJobId, re);
+ }
+ return null;
+ }
+
+ /**
+ * Creates a print job for printing a file with default print attributes.
+ *
+ * @param printJobName A name for the new print job.
+ * @param pdfFile The PDF file to print.
+ * @param attributes The default print job attributes.
+ * @return The created print job.
+ */
+ public PrintJob print(String printJobName, File pdfFile, PrintAttributes attributes) {
+ PrintFileAdapter printable = new PrintFileAdapter(pdfFile);
+ return print(printJobName, printable, attributes);
+ }
+
+ /**
+ * Creates a print job for printing a {@link PrintAdapter} with default print
+ * attributes.
+ *
+ * @param printJobName A name for the new print job.
+ * @param printAdapter The printable adapter to print.
+ * @param attributes The default print job attributes.
+ * @return The created print job.
+ */
+ public PrintJob print(String printJobName, PrintAdapter printAdapter,
+ PrintAttributes attributes) {
+ PrintAdapterDelegate delegate = new PrintAdapterDelegate(printAdapter,
+ mContext.getMainLooper());
+ try {
+ PrintJobInfo printJob = mService.print(printJobName, mPrintClient, delegate,
+ attributes, mAppId, mUserId);
+ if (printJob != null) {
+ return new PrintJob(printJob, this);
+ }
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error creating a print job", re);
+ }
+ return null;
+ }
+
+ private static final class PrintClient extends IPrintClient.Stub {
+
+ private final WeakReference<PrintManager> mWeakPrintManager;
+
+ public PrintClient(PrintManager manager) {
+ mWeakPrintManager = new WeakReference<PrintManager>(manager);
+ }
+
+ @Override
+ public void startPrintJobConfigActivity(IntentSender intent) {
+ PrintManager manager = mWeakPrintManager.get();
+ if (manager != null) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = manager.mContext;
+ args.arg2 = intent;
+ manager.mHandler.obtainMessage(0, args).sendToTarget();
+ }
+ }
+ }
+
+ private static final class PrintAdapterDelegate extends IPrintAdapter.Stub {
+ private final Object mLock = new Object();
+
+ private PrintAdapter mPrintAdapter;
+
+ private Handler mHandler;
+
+ public PrintAdapterDelegate(PrintAdapter printAdapter, Looper looper) {
+ mPrintAdapter = printAdapter;
+ mHandler = new MyHandler(looper);
+ }
+
+ @Override
+ public void start() {
+ synchronized (mLock) {
+ if (isFinishedLocked()) {
+ return;
+ }
+ mHandler.obtainMessage(MyHandler.MESSAGE_START,
+ mPrintAdapter).sendToTarget();
+ }
+ }
+
+ @Override
+ public void printAttributesChanged(PrintAttributes attributes) {
+ synchronized (mLock) {
+ if (isFinishedLocked()) {
+ return;
+ }
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = mPrintAdapter;
+ args.arg2 = attributes;
+ mHandler.obtainMessage(MyHandler.MESSAGE_PRINT_ATTRIBUTES_CHANGED,
+ args).sendToTarget();
+ }
+ }
+
+ @Override
+ public void print(List<PageRange> pages, ParcelFileDescriptor fd,
+ IPrintProgressListener progressListener) {
+ synchronized (mLock) {
+ if (isFinishedLocked()) {
+ return;
+ }
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = mPrintAdapter;
+ args.arg2 = pages;
+ args.arg3 = fd.getFileDescriptor();
+ args.arg4 = progressListener;
+ mHandler.obtainMessage(MyHandler.MESSAGE_PRINT, args).sendToTarget();
+ }
+ }
+
+ @Override
+ public void finish() {
+ synchronized (mLock) {
+ if (isFinishedLocked()) {
+ return;
+ }
+ mHandler.obtainMessage(MyHandler.MESSAGE_FINIS,
+ mPrintAdapter).sendToTarget();
+ }
+ }
+
+ private boolean isFinishedLocked() {
+ return mPrintAdapter == null;
+ }
+
+ private void finishLocked() {
+ mPrintAdapter = null;
+ mHandler = null;
+ }
+
+ private final class MyHandler extends Handler {
+ public static final int MESSAGE_START = 1;
+ public static final int MESSAGE_PRINT_ATTRIBUTES_CHANGED = 2;
+ public static final int MESSAGE_PRINT = 3;
+ public static final int MESSAGE_FINIS = 4;
+
+ public MyHandler(Looper looper) {
+ super(looper, null, true);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ switch (message.what) {
+ case MESSAGE_START: {
+ PrintAdapter adapter = (PrintAdapter) message.obj;
+ adapter.onStart();
+ } break;
+
+ case MESSAGE_PRINT_ATTRIBUTES_CHANGED: {
+ SomeArgs args = (SomeArgs) message.obj;
+ PrintAdapter adapter = (PrintAdapter) args.arg1;
+ PrintAttributes attributes = (PrintAttributes) args.arg2;
+ args.recycle();
+ adapter.onPrintAttributesChanged(attributes);
+ } break;
+
+ case MESSAGE_PRINT: {
+ SomeArgs args = (SomeArgs) message.obj;
+ PrintAdapter adapter = (PrintAdapter) args.arg1;
+ @SuppressWarnings("unchecked")
+ List<PageRange> pages = (List<PageRange>) args.arg2;
+ final FileDescriptor fd = (FileDescriptor) args.arg3;
+ IPrintProgressListener listener = (IPrintProgressListener) args.arg4;
+ args.recycle();
+ try {
+ ICancellationSignal remoteSignal = CancellationSignal.createTransport();
+ listener.onWriteStarted(adapter.getInfo(), remoteSignal);
+
+ CancellationSignal localSignal = CancellationSignal.fromTransport(
+ remoteSignal);
+ adapter.onPrint(pages, fd, localSignal,
+ new PrintProgressListenerWrapper(listener) {
+ @Override
+ public void onPrintFinished(List<PageRange> pages) {
+ IoUtils.closeQuietly(fd);
+ super.onPrintFinished(pages);
+ }
+
+ @Override
+ public void onPrintFailed(CharSequence error) {
+ IoUtils.closeQuietly(fd);
+ super.onPrintFailed(error);
+ }
+ });
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error printing", re);
+ IoUtils.closeQuietly(fd);
+ }
+ } break;
+
+ case MESSAGE_FINIS: {
+ PrintAdapter adapter = (PrintAdapter) message.obj;
+ adapter.onFinish();
+ synchronized (mLock) {
+ finishLocked();
+ }
+ } break;
+
+ default: {
+ throw new IllegalArgumentException("Unknown message: "
+ + message.what);
+ }
+ }
+ }
+ }
+ }
+
+ private static abstract class PrintProgressListenerWrapper extends PrintProgressCallback {
+
+ private final IPrintProgressListener mWrappedListener;
+
+ public PrintProgressListenerWrapper(IPrintProgressListener listener) {
+ mWrappedListener = listener;
+ }
+
+ @Override
+ public void onPrintFinished(List<PageRange> pages) {
+ try {
+ mWrappedListener.onWriteFinished(pages);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling onWriteFinished", re);
+ }
+ }
+
+ @Override
+ public void onPrintFailed(CharSequence error) {
+ try {
+ mWrappedListener.onWriteFailed(error);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error calling onWriteFailed", re);
+ }
+ }
+ }
+}