14b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/* 24b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project 34b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 44b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 54b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * you may not use this file except in compliance with the License. 64b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * You may obtain a copy of the License at 74b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 84b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 94b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software 114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * See the License for the specific language governing permissions and 144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * limitations under the License. 154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpackage android.print; 184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.Context; 204b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.IntentSender; 214b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.IntentSender.SendIntentException; 226283608e0bd40548742839f5a8b02f7e5c9c5c7cSvetoslavimport android.os.Bundle; 234b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.CancellationSignal; 244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Handler; 254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Looper; 264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Message; 274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.ParcelFileDescriptor; 284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.RemoteException; 29a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.PrintDocumentAdapter.LayoutResultCallback; 30a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.PrintDocumentAdapter.WriteResultCallback; 31860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganovimport android.printservice.PrintServiceInfo; 3288d199130d44c6bacb383a7757e782cf97483c68Svetoslav Ganovimport android.text.TextUtils; 33704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport android.util.ArrayMap; 344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.util.Log; 354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 364b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport com.android.internal.os.SomeArgs; 374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport libcore.io.IoUtils; 394b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 404b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.lang.ref.WeakReference; 414b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.ArrayList; 424b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.Collections; 434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.List; 44704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport java.util.Map; 454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 464b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/** 474b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * System level service for accessing the printing capabilities of the platform. 484b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * <p> 494b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * To obtain a handle to the print manager do the following: 504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * </p> 51a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 524b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * <pre> 534b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * PrintManager printManager = 544b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * (PrintManager) context.getSystemService(Context.PRINT_SERVICE); 554b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * </pre> 564b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpublic final class PrintManager { 584b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 594b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private static final String LOG_TAG = "PrintManager"; 604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 61db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private static final boolean DEBUG = false; 62db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 637bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 1; 647bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 657bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav /** 667bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * The action for launching the print dialog activity. 677bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * 687bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * @hide 697bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav */ 707bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final String ACTION_PRINT_DIALOG = "android.print.PRINT_DIALOG"; 717bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 727bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav /** 737bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * Extra with the intent for starting the print dialog. 747bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * <p> 757bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * <strong>Type:</strong> {@link android.content.IntentSender} 767bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * </p> 777bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * 787bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * @hide 797bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav */ 807bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final String EXTRA_PRINT_DIALOG_INTENT = 817bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav "android.print.intent.extra.EXTRA_PRINT_DIALOG_INTENT"; 827bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 837bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav /** 847bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * Extra with a print job. 857bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * <p> 867bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * <strong>Type:</strong> {@link android.print.PrintJobInfo} 877bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * </p> 887bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * 897bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * @hide 907bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav */ 917bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final String EXTRA_PRINT_JOB = 927bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav "android.print.intent.extra.EXTRA_PRINT_JOB"; 937bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 947bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav /** 957bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * Extra with the print document adapter to be printed. 967bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * <p> 977bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * <strong>Type:</strong> {@link android.print.IPrintDocumentAdapter} 987bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * </p> 997bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * 1007bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav * @hide 1017bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav */ 1027bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final String EXTRA_PRINT_DOCUMENT_ADAPTER = 1037bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav "android.print.intent.extra.EXTRA_PRINT_DOCUMENT_ADAPTER"; 104a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 1054b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov /** @hide */ 1064b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public static final int APP_ID_ANY = -2; 1074b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1084b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final Context mContext; 1094b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final IPrintManager mService; 1114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final int mUserId; 1134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final int mAppId; 1154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final Handler mHandler; 1174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 118704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private Map<PrintJobStateChangeListener, PrintJobStateChangeListenerWrapper> mPrintJobStateChangeListeners; 119704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 120704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov /** @hide */ 121704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public interface PrintJobStateChangeListener { 122704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 123704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov /** 124704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * Callback notifying that a print job state changed. 125a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 126704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @param printJobId The print job id. 127704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov */ 128a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov public void onPrintJobStateChanged(PrintJobId printJobId); 129704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 130704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 1314b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov /** 1324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Creates a new instance. 133a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 1344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @param context The current context in which to operate. 1354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @param service The backing system service. 1364b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @hide 1374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 1384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public PrintManager(Context context, IPrintManager service, int userId, int appId) { 1394b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mContext = context; 1404b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mService = service; 1414b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mUserId = userId; 1424b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mAppId = appId; 1434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mHandler = new Handler(context.getMainLooper(), null, false) { 1444b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 1454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void handleMessage(Message message) { 146a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov switch (message.what) { 147a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov case MSG_NOTIFY_PRINT_JOB_STATE_CHANGED: { 148a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 149d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov PrintJobStateChangeListenerWrapper wrapper = 150d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov (PrintJobStateChangeListenerWrapper) args.arg1; 151d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov PrintJobStateChangeListener listener = wrapper.getListener(); 152d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov if (listener != null) { 153d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov PrintJobId printJobId = (PrintJobId) args.arg2; 154d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov listener.onPrintJobStateChanged(printJobId); 155d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov } 156a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov args.recycle(); 1577bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } break; 1584b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1594b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov }; 1614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1624b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1634b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov /** 1644b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Creates an instance that can access all print jobs. 165a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 1664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @param userId The user id for which to get all print jobs. 167a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * @return An instance if the caller has the permission to access all print 168a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * jobs, null otherwise. 1694b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @hide 1704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 1714b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public PrintManager getGlobalPrintManagerForUser(int userId) { 1724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return new PrintManager(mContext, mService, userId, APP_ID_ANY); 1734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1744b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1752fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintJobInfo getPrintJobInfo(PrintJobId printJobId) { 1764b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov try { 177a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mService.getPrintJobInfo(printJobId, mAppId, mUserId); 1784b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } catch (RemoteException re) { 179a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Log.e(LOG_TAG, "Error getting a print job info:" + printJobId, re); 1804b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1814b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return null; 1824b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1834b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1844b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov /** 185704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * Adds a listener for observing the state of print jobs. 186a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 187704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @param listener The listener to add. 188704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @hide 189704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov */ 190704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void addPrintJobStateChangeListener(PrintJobStateChangeListener listener) { 191704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListeners == null) { 192704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListeners = new ArrayMap<PrintJobStateChangeListener, 193704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobStateChangeListenerWrapper>(); 194704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 195704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobStateChangeListenerWrapper wrappedListener = 196a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov new PrintJobStateChangeListenerWrapper(listener, mHandler); 197704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 198704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mService.addPrintJobStateChangeListener(wrappedListener, mAppId, mUserId); 199704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListeners.put(listener, wrappedListener); 200704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } catch (RemoteException re) { 201704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Log.e(LOG_TAG, "Error adding print job state change listener", re); 202704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 203704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 204704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 205704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov /** 206704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * Removes a listener for observing the state of print jobs. 207a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 208704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @param listener The listener to remove. 209704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @hide 210704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov */ 211704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void removePrintJobStateChangeListener(PrintJobStateChangeListener listener) { 212704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListeners == null) { 213704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return; 214704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 215704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobStateChangeListenerWrapper wrappedListener = 216704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListeners.remove(listener); 217704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (wrappedListener == null) { 218704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return; 219704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 220704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListeners.isEmpty()) { 221704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListeners = null; 222704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 223d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov wrappedListener.destroy(); 224704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 225704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mService.removePrintJobStateChangeListener(wrappedListener, mUserId); 226704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } catch (RemoteException re) { 227704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Log.e(LOG_TAG, "Error removing print job state change listener", re); 228704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 229704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 230704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 231704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov /** 232704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * Gets a print job given its id. 233a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 234704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @return The print job list. 235704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @see PrintJob 236704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov * @hide 237704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov */ 238704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public PrintJob getPrintJob(PrintJobId printJobId) { 239704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 240704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobInfo printJob = mService.getPrintJobInfo(printJobId, mAppId, mUserId); 241704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (printJob != null) { 242704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return new PrintJob(printJob, this); 243704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 244704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } catch (RemoteException re) { 245704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Log.e(LOG_TAG, "Error getting print job", re); 246704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 247704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return null; 248704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 249704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 250704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov /** 2514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Gets the print jobs for this application. 252a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 2534b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @return The print job list. 2544b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @see PrintJob 2554b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 2564b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public List<PrintJob> getPrintJobs() { 2574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov try { 258a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov List<PrintJobInfo> printJobInfos = mService.getPrintJobInfos(mAppId, mUserId); 2594b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov if (printJobInfos == null) { 2604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return Collections.emptyList(); 2614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2624b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov final int printJobCount = printJobInfos.size(); 2634b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov List<PrintJob> printJobs = new ArrayList<PrintJob>(printJobCount); 2644b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov for (int i = 0; i < printJobCount; i++) { 2654b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov printJobs.add(new PrintJob(printJobInfos.get(i), this)); 2664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2674b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return printJobs; 2684b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } catch (RemoteException re) { 269a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Log.e(LOG_TAG, "Error getting print jobs", re); 2704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2714b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return Collections.emptyList(); 2724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 2742fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav void cancelPrintJob(PrintJobId printJobId) { 2754b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov try { 2764b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mService.cancelPrintJob(printJobId, mAppId, mUserId); 2774b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } catch (RemoteException re) { 278a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Log.e(LOG_TAG, "Error cancleing a print job: " + printJobId, re); 2794b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2804b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2814b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 282704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov void restartPrintJob(PrintJobId printJobId) { 283704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 284704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mService.restartPrintJob(printJobId, mAppId, mUserId); 285704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } catch (RemoteException re) { 286704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Log.e(LOG_TAG, "Error restarting a print job: " + printJobId, re); 287704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 288704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 289704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 2904b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov /** 291a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * Creates a print job for printing a {@link PrintDocumentAdapter} with 292a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * default print attributes. 293a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 2944b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @param printJobName A name for the new print job. 295a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * @param documentAdapter An adapter that emits the document to print. 2964b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * @param attributes The default print job attributes. 297d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * @return The created print job on success or null on failure. 298fd90651cfcc7e2b75254666fd6861038b72fb4acSvetoslav * @see PrintJob 2994b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 300a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public PrintJob print(String printJobName, PrintDocumentAdapter documentAdapter, 3014b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov PrintAttributes attributes) { 30288d199130d44c6bacb383a7757e782cf97483c68Svetoslav Ganov if (TextUtils.isEmpty(printJobName)) { 30388d199130d44c6bacb383a7757e782cf97483c68Svetoslav Ganov throw new IllegalArgumentException("priintJobName cannot be empty"); 30488d199130d44c6bacb383a7757e782cf97483c68Svetoslav Ganov } 305a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter, 3064b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mContext.getMainLooper()); 3074b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov try { 3087bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Bundle result = mService.print(printJobName, delegate, 3097bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav attributes, mContext.getPackageName(), mAppId, mUserId); 3107bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav if (result != null) { 3117bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB); 3127bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT); 3137bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav if (printJob == null || intent == null) { 3147bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav return null; 3157bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 3167bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav try { 3177bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav mContext.startIntentSender(intent, null, 0, 0, 0); 3187bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav return new PrintJob(printJob, this); 3197bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } catch (SendIntentException sie) { 3207bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Log.e(LOG_TAG, "Couldn't start print job config activity.", sie); 3217bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 3224b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 3234b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } catch (RemoteException re) { 3244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov Log.e(LOG_TAG, "Error creating a print job", re); 3254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 3264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov return null; 3274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 3284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 32944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov /** 330860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov * Gets the list of enabled print services. 331a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 332860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov * @return The enabled service list or an empty list. 333860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov * @hide 334860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov */ 335860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov public List<PrintServiceInfo> getEnabledPrintServices() { 336860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov try { 337860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov List<PrintServiceInfo> enabledServices = mService.getEnabledPrintServices(mUserId); 338860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov if (enabledServices != null) { 339860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov return enabledServices; 340860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 341860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } catch (RemoteException re) { 342d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav Log.e(LOG_TAG, "Error getting the enabled print services", re); 343d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } 344d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav return Collections.emptyList(); 345d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } 346d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav 347d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav /** 348d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav * Gets the list of installed print services. 349a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov * 350d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav * @return The installed service list or an empty list. 351d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav * @hide 352d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav */ 353d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav public List<PrintServiceInfo> getInstalledPrintServices() { 354d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav try { 355d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav List<PrintServiceInfo> installedServices = mService.getInstalledPrintServices(mUserId); 356d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav if (installedServices != null) { 357d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav return installedServices; 358d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } 359d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } catch (RemoteException re) { 360d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav Log.e(LOG_TAG, "Error getting the installed print services", re); 361860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 362860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov return Collections.emptyList(); 363860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 364860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov 365860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov /** 36644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * @hide 36744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov */ 36844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public PrinterDiscoverySession createPrinterDiscoverySession() { 36944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return new PrinterDiscoverySession(mService, mContext, mUserId); 37044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 37144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 372a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub { 37385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 37485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov private final Object mLock = new Object(); 37585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 37685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov private CancellationSignal mLayoutOrWriteCancellation; 37785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 378a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - 379a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov // cleared in finish() 3804b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 381a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private Handler mHandler; // Strong reference OK - cleared in finish() 3824b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 383db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private LayoutSpec mLastLayoutSpec; 384db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 385db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private WriteSpec mLastWriteSpec; 386db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 387db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private boolean mStartReqeusted; 388db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private boolean mStarted; 389db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 390db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private boolean mFinishRequested; 391db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private boolean mFinished; 392db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 393a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public PrintDocumentAdapterDelegate(PrintDocumentAdapter documentAdapter, Looper looper) { 394a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDocumentAdapter = documentAdapter; 3954b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mHandler = new MyHandler(looper); 3964b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 3974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 3984b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 3994b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void start() { 400db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov synchronized (mLock) { 401db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Started or finished - nothing to do. 402db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (mStartReqeusted || mFinishRequested) { 403db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 404db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 405db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 406db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mStartReqeusted = true; 407db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 408db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov doPendingWorkLocked(); 409db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 4104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 4114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 4124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 4136283608e0bd40548742839f5a8b02f7e5c9c5c7cSvetoslav public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes, 41485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov ILayoutResultCallback callback, Bundle metadata, int sequence) { 41585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 416db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Start not called or finish called - nothing to do. 417db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (!mStartReqeusted || mFinishRequested) { 418db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 419db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 420db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 421db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Layout cancels write and overrides layout. 422db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (mLastWriteSpec != null) { 423db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov IoUtils.closeQuietly(mLastWriteSpec.fd); 424db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec = null; 42585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 426db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 427db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec = new LayoutSpec(); 428db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec.callback = callback; 429db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec.oldAttributes = oldAttributes; 430db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec.newAttributes = newAttributes; 431db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec.metadata = metadata; 432db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec.sequence = sequence; 433db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 434db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Cancel the previous cancellable operation.When the 435db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // cancellation completes we will do the pending work. 436db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (cancelPreviousCancellableOperationLocked()) { 437db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 438db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 439db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 440db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov doPendingWorkLocked(); 44185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 4424b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 4434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 4444b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 44585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov public void write(PageRange[] pages, ParcelFileDescriptor fd, 446704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov IWriteResultCallback callback, int sequence) { 44785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 448db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Start not called or finish called - nothing to do. 449db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (!mStartReqeusted || mFinishRequested) { 450db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 451db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 452db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 453db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Write cancels previous writes. 454db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (mLastWriteSpec != null) { 455db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov IoUtils.closeQuietly(mLastWriteSpec.fd); 456db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec = null; 45785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 458db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 459db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec = new WriteSpec(); 460db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec.callback = callback; 461db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec.pages = pages; 462db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec.fd = fd; 463db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec.sequence = sequence; 464db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 465db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Cancel the previous cancellable operation.When the 466db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // cancellation completes we will do the pending work. 467db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (cancelPreviousCancellableOperationLocked()) { 468db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 469db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 470db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 471db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov doPendingWorkLocked(); 47285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 4734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 4744b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 4754b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 4764b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void finish() { 477db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov synchronized (mLock) { 478db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // Start not called or finish called - nothing to do. 479db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (!mStartReqeusted || mFinishRequested) { 480db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 481db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 482db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 483db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mFinishRequested = true; 484db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 485db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // When the current write or layout complete we 486db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov // will do the pending work. 487db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (mLastLayoutSpec != null || mLastWriteSpec != null) { 488db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (DEBUG) { 489db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov Log.i(LOG_TAG, "Waiting for current operation"); 490db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 491db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return; 492db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 493db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 494db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov doPendingWorkLocked(); 495db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 4964b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 4974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 498a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean isFinished() { 499a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mDocumentAdapter == null; 5004b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5014b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 502a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void doFinish() { 503a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDocumentAdapter = null; 5044b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov mHandler = null; 505db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov synchronized (mLock) { 506db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLayoutOrWriteCancellation = null; 507db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 508db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 509db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 510db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private boolean cancelPreviousCancellableOperationLocked() { 511db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (mLayoutOrWriteCancellation != null) { 512db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLayoutOrWriteCancellation.cancel(); 513db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (DEBUG) { 514db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov Log.i(LOG_TAG, "Cancelling previous operation"); 515db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 516db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return true; 517db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 518db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov return false; 519db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 520db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 521db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private void doPendingWorkLocked() { 522db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (mStartReqeusted && !mStarted) { 523db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mStarted = true; 524db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mHandler.sendEmptyMessage(MyHandler.MSG_START); 525db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } else if (mLastLayoutSpec != null) { 526db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mHandler.sendEmptyMessage(MyHandler.MSG_LAYOUT); 527db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } else if (mLastWriteSpec != null) { 528db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mHandler.sendEmptyMessage(MyHandler.MSG_WRITE); 529db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } else if (mFinishRequested && !mFinished) { 530db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mFinished = true; 531db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mHandler.sendEmptyMessage(MyHandler.MSG_FINISH); 532db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 533db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 534db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 535db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private class LayoutSpec { 536db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov ILayoutResultCallback callback; 537db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov PrintAttributes oldAttributes; 538db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov PrintAttributes newAttributes; 539db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov Bundle metadata; 540db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov int sequence; 541db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 542db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 543db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov private class WriteSpec { 544db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov IWriteResultCallback callback; 545db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov PageRange[] pages; 546db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov ParcelFileDescriptor fd; 547db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov int sequence; 5484b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5494b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 5504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov private final class MyHandler extends Handler { 551a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static final int MSG_START = 1; 552a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static final int MSG_LAYOUT = 2; 553a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static final int MSG_WRITE = 3; 554a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static final int MSG_FINISH = 4; 5554b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 5564b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public MyHandler(Looper looper) { 5574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov super(looper, null, true); 5584b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5594b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 5604b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 5614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void handleMessage(Message message) { 562a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (isFinished()) { 563a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return; 564a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 5654b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov switch (message.what) { 566a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov case MSG_START: { 567a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDocumentAdapter.onStart(); 568a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 569a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov break; 5704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 571a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov case MSG_LAYOUT: { 572db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov final CancellationSignal cancellation; 573db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov final LayoutSpec layoutSpec; 574db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 57585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 576db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov layoutSpec = mLastLayoutSpec; 577db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastLayoutSpec = null; 578db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov cancellation = new CancellationSignal(); 57985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLayoutOrWriteCancellation = cancellation; 580a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 58185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 582db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (layoutSpec != null) { 583db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (DEBUG) { 584db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov Log.i(LOG_TAG, "Performing layout"); 585db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 586db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mDocumentAdapter.onLayout(layoutSpec.oldAttributes, 587db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov layoutSpec.newAttributes, cancellation, 588db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov new MyLayoutResultCallback(layoutSpec.callback, 589db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov layoutSpec.sequence), layoutSpec.metadata); 590db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 591a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 592a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov break; 5934b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 594a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov case MSG_WRITE: { 595db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov final CancellationSignal cancellation; 596db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov final WriteSpec writeSpec; 597db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov 59885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 599a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov writeSpec = mLastWriteSpec; 600db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mLastWriteSpec = null; 601db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov cancellation = new CancellationSignal(); 60285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLayoutOrWriteCancellation = cancellation; 6034b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 60485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 605db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (writeSpec != null) { 606db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (DEBUG) { 607db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov Log.i(LOG_TAG, "Performing write"); 608db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 609db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov mDocumentAdapter.onWrite(writeSpec.pages, writeSpec.fd, 610db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov cancellation, new MyWriteResultCallback(writeSpec.callback, 611db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov writeSpec.fd, writeSpec.sequence)); 612db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 613a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 614a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov break; 6154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 616a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov case MSG_FINISH: { 617db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov if (DEBUG) { 618db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov Log.i(LOG_TAG, "Performing finish"); 619db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov } 620a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDocumentAdapter.onFinish(); 621a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov doFinish(); 622a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 623a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov break; 6244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 6254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov default: { 6264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov throw new IllegalArgumentException("Unknown message: " 6274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov + message.what); 6284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 6294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 6304b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 6314b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 63214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 63314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private final class MyLayoutResultCallback extends LayoutResultCallback { 63414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private ILayoutResultCallback mCallback; 63514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private final int mSequence; 63614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 63714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public MyLayoutResultCallback(ILayoutResultCallback callback, 63814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov int sequence) { 63914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mCallback = callback; 64014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mSequence = sequence; 64114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 64214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 64314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov @Override 64414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { 645269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (info == null) { 646269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throw new NullPointerException("document info cannot be null"); 647269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 64814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov final ILayoutResultCallback callback; 64914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov synchronized (mLock) { 65014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback = mCallback; 65114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov clearLocked(); 65214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 65314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov if (callback != null) { 65414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov try { 65514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback.onLayoutFinished(info, changed, mSequence); 65614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } catch (RemoteException re) { 65714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov Log.e(LOG_TAG, "Error calling onLayoutFinished", re); 65814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 65914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 66014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 66114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 66214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov @Override 66314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public void onLayoutFailed(CharSequence error) { 66414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov final ILayoutResultCallback callback; 66514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov synchronized (mLock) { 66614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback = mCallback; 66714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov clearLocked(); 66814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 66914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov if (callback != null) { 67014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov try { 67114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback.onLayoutFailed(error, mSequence); 67214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } catch (RemoteException re) { 67314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov Log.e(LOG_TAG, "Error calling onLayoutFailed", re); 67414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 67514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 67614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 67714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 67814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov @Override 67914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public void onLayoutCancelled() { 68014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov synchronized (mLock) { 68114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov clearLocked(); 68214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 68314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 68414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 68514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private void clearLocked() { 68614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mLayoutOrWriteCancellation = null; 68714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mCallback = null; 688db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov doPendingWorkLocked(); 68914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 69014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 69114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 69214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private final class MyWriteResultCallback extends WriteResultCallback { 693d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private ParcelFileDescriptor mFd; 69414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private int mSequence; 69514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private IWriteResultCallback mCallback; 69614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 69714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public MyWriteResultCallback(IWriteResultCallback callback, 698d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov ParcelFileDescriptor fd, int sequence) { 69914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mFd = fd; 70014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mSequence = sequence; 70114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mCallback = callback; 70214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 70314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 70414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov @Override 70514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public void onWriteFinished(PageRange[] pages) { 70614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov final IWriteResultCallback callback; 70714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov synchronized (mLock) { 70814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback = mCallback; 70914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov clearLocked(); 71014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 71114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov if (pages == null) { 71214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov throw new IllegalArgumentException("pages cannot be null"); 71314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 71414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov if (pages.length == 0) { 71514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov throw new IllegalArgumentException("pages cannot be empty"); 71614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 71714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov if (callback != null) { 71814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov try { 71914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback.onWriteFinished(pages, mSequence); 72014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } catch (RemoteException re) { 72114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov Log.e(LOG_TAG, "Error calling onWriteFinished", re); 72214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 72314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 72414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 72514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 72614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov @Override 72714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public void onWriteFailed(CharSequence error) { 72814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov final IWriteResultCallback callback; 72914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov synchronized (mLock) { 73014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback = mCallback; 73114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov clearLocked(); 73214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 73314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov if (callback != null) { 73414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov try { 73514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov callback.onWriteFailed(error, mSequence); 73614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } catch (RemoteException re) { 73714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov Log.e(LOG_TAG, "Error calling onWriteFailed", re); 73814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 73914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 74014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 74114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 74214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov @Override 74314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov public void onWriteCancelled() { 74414db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov synchronized (mLock) { 74514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov clearLocked(); 74614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 74714db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 74814db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov 74914db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov private void clearLocked() { 75014db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mLayoutOrWriteCancellation = null; 75114db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov IoUtils.closeQuietly(mFd); 75214db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mCallback = null; 75314db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov mFd = null; 754db63677c7c02cad7c25627533e5add5ed46870f8Svetoslav Ganov doPendingWorkLocked(); 75514db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 75614db9654f6c31e94fe9272776f1f1b8602a17fdcSvetoslav Ganov } 7574b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 758704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 759704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private static final class PrintJobStateChangeListenerWrapper extends 760704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov IPrintJobStateChangeListener.Stub { 761704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private final WeakReference<PrintJobStateChangeListener> mWeakListener; 762a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov private final WeakReference<Handler> mWeakHandler; 763704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 764a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov public PrintJobStateChangeListenerWrapper(PrintJobStateChangeListener listener, 765a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Handler handler) { 766704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mWeakListener = new WeakReference<PrintJobStateChangeListener>(listener); 767a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mWeakHandler = new WeakReference<Handler>(handler); 768704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 769704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 770704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 771704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void onPrintJobStateChanged(PrintJobId printJobId) { 772a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Handler handler = mWeakHandler.get(); 773704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobStateChangeListener listener = mWeakListener.get(); 774a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (handler != null && listener != null) { 775a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov SomeArgs args = SomeArgs.obtain(); 776d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov args.arg1 = this; 777a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov args.arg2 = printJobId; 778a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov handler.obtainMessage(MSG_NOTIFY_PRINT_JOB_STATE_CHANGED, 779a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov args).sendToTarget(); 780704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 781704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 782a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 783d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov public void destroy() { 784d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov mWeakListener.clear(); 785d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov } 786d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov 787d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov public PrintJobStateChangeListener getListener() { 788d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov return mWeakListener.get(); 789d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov } 790d91cb3ea61ea5096637c5d2b5e3e6147d0d2cce3Svetoslav Ganov } 7914b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov} 792