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 com.android.printspooler; 184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.app.Service; 204b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.ComponentName; 214b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.Intent; 22269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.os.AsyncTask; 23b4fda134761c9521a7e127db3806a07a18763b77Svetoslavimport android.os.Bundle; 244b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.IBinder; 254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Message; 264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.ParcelFileDescriptor; 274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.RemoteException; 28a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpooler; 29a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerCallbacks; 30835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganovimport android.print.IPrintSpoolerClient; 31269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PageRange; 324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.PrintAttributes; 33269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrintAttributes.Margins; 34269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrintAttributes.MediaSize; 35269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrintAttributes.Resolution; 36269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrintDocumentInfo; 372fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId; 384b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.PrintJobInfo; 39269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrintManager; 40269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterId; 41269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterInfo; 42a76233ae845da4bc9e3bcd89821701a747215e7bSvetoslavimport android.text.TextUtils; 43dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganovimport android.util.ArrayMap; 44269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.util.AtomicFile; 45835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganovimport android.util.Log; 464b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.util.Slog; 47269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.util.Xml; 484b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 49269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport com.android.internal.os.HandlerCaller; 50269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport com.android.internal.util.FastXmlSerializer; 514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 522fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport libcore.io.IoUtils; 532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 54269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport org.xmlpull.v1.XmlPullParser; 55269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport org.xmlpull.v1.XmlPullParserException; 56269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport org.xmlpull.v1.XmlSerializer; 57269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 58269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.io.File; 59dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganovimport java.io.FileDescriptor; 60269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.io.FileInputStream; 61269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.io.FileNotFoundException; 62269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.io.FileOutputStream; 63269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.io.IOException; 64dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganovimport java.io.PrintWriter; 65269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.ArrayList; 66835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganovimport java.util.List; 67835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov 684b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/** 694b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Service for exposing some of the {@link PrintSpooler} functionality to 704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * another process. 714b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpublic final class PrintSpoolerService extends Service { 734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 74269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String LOG_TAG = "PrintSpoolerService"; 75269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 76b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = false; 77269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 78c6066799ad130140159230d14451b429eb828755Svetoslav private static final boolean DEBUG_PERSISTENCE = false; 79269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 80269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final boolean PERSISTNECE_MANAGER_ENABLED = true; 81269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 82835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov private static final long CHECK_ALL_PRINTJOBS_HANDLED_DELAY = 5000; 83835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov 84dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private static final String PRINT_JOB_FILE_PREFIX = "print_job_"; 85dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 86269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String PRINT_FILE_EXTENSION = "pdf"; 87269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 88269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final Object sLock = new Object(); 89269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 90269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private final Object mLock = new Object(); 91269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 92269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private final List<PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>(); 93269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 94269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static PrintSpoolerService sInstance; 95269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 96835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov private IPrintSpoolerClient mClient; 974b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 98269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private HandlerCaller mHandlerCaller; 99269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 100269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private PersistenceManager mPersistanceManager; 101269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 102269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private NotificationController mNotificationController; 103269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 104269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public static PrintSpoolerService peekInstance() { 105269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (sLock) { 106269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return sInstance; 107269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 108269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1094b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 1114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public void onCreate() { 1124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov super.onCreate(); 113269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mHandlerCaller = new HandlerCaller(this, getMainLooper(), 114269403b032f965ff3847eb982c2f697229dc5a92Svetoslav new HandlerCallerCallback(), false); 115269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 116269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mPersistanceManager = new PersistenceManager(); 117269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mNotificationController = new NotificationController(PrintSpoolerService.this); 118269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 119269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 120269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mPersistanceManager.readStateLocked(); 121269403b032f965ff3847eb982c2f697229dc5a92Svetoslav handleReadPrintJobsLocked(); 122269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 123269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 124269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (sLock) { 125269403b032f965ff3847eb982c2f697229dc5a92Svetoslav sInstance = this; 126269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 1304b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov public IBinder onBind(Intent intent) { 1317bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav return new PrintSpooler(); 1324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 1334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 134dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov @Override 135dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 136dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov synchronized (mLock) { 137b67a637e60c356ab520050b2bd09a95ae47f3017Svetoslav String prefix = (args.length > 0) ? args[0] : ""; 138dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov String tab = " "; 139dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 140dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append("print jobs:").println(); 141dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int printJobCount = mPrintJobs.size(); 142dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < printJobCount; i++) { 143dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo printJob = mPrintJobs.get(i); 144dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append(tab).append(printJob.toString()); 145dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.println(); 146dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 147dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 148dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append("print job files:").println(); 149dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov File[] files = getFilesDir().listFiles(); 150dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (files != null) { 151dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int fileCount = files.length; 152dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < fileCount; i++) { 153dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov File file = files[i]; 154dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (file.isFile() && file.getName().startsWith(PRINT_JOB_FILE_PREFIX)) { 155dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append(tab).append(file.getName()).println(); 156dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 157dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 158dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 159dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 160dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 161dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 162269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void sendOnPrintJobQueued(PrintJobInfo printJob) { 163269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Message message = mHandlerCaller.obtainMessageO( 164269403b032f965ff3847eb982c2f697229dc5a92Svetoslav HandlerCallerCallback.MSG_ON_PRINT_JOB_QUEUED, printJob); 165269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mHandlerCaller.executeOrSendMessage(message); 166269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 167269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 168269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void sendOnAllPrintJobsForServiceHandled(ComponentName service) { 169269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Message message = mHandlerCaller.obtainMessageO( 170269403b032f965ff3847eb982c2f697229dc5a92Svetoslav HandlerCallerCallback.MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED, service); 171269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mHandlerCaller.executeOrSendMessage(message); 172269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 173269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 174269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void sendOnAllPrintJobsHandled() { 175269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Message message = mHandlerCaller.obtainMessage( 176269403b032f965ff3847eb982c2f697229dc5a92Svetoslav HandlerCallerCallback.MSG_ON_ALL_PRINT_JOBS_HANDLED); 177269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mHandlerCaller.executeOrSendMessage(message); 178269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 179269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 180269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private final class HandlerCallerCallback implements HandlerCaller.Callback { 181704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public static final int MSG_SET_CLIENT = 1; 1827bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final int MSG_ON_PRINT_JOB_QUEUED = 2; 1837bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 3; 1847bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 4; 1857bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 5; 1867bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public static final int MSG_ON_PRINT_JOB_STATE_CHANGED = 6; 1874b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 1884b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 189269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public void executeMessage(Message message) { 190835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov switch (message.what) { 191835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov case MSG_SET_CLIENT: { 192269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 193269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mClient = (IPrintSpoolerClient) message.obj; 194269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mClient != null) { 195269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Message msg = mHandlerCaller.obtainMessage( 196269403b032f965ff3847eb982c2f697229dc5a92Svetoslav HandlerCallerCallback.MSG_CHECK_ALL_PRINTJOBS_HANDLED); 197269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mHandlerCaller.sendMessageDelayed(msg, 198269403b032f965ff3847eb982c2f697229dc5a92Svetoslav CHECK_ALL_PRINTJOBS_HANDLED_DELAY); 199269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 200835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 201835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } break; 202835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov 203835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov case MSG_ON_PRINT_JOB_QUEUED: { 204835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov PrintJobInfo printJob = (PrintJobInfo) message.obj; 205835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (mClient != null) { 206835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov try { 207835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov mClient.onPrintJobQueued(printJob); 208835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } catch (RemoteException re) { 209835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.e(LOG_TAG, "Error notify for a queued print job.", re); 210835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 211835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 212835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } break; 213835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov 214835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov case MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED: { 215835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov ComponentName service = (ComponentName) message.obj; 216835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (mClient != null) { 217835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov try { 218835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov mClient.onAllPrintJobsForServiceHandled(service); 219835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } catch (RemoteException re) { 220835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.e(LOG_TAG, "Error notify for all print jobs per service" 221835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov + " handled.", re); 222835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 223835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 224835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } break; 225835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov 226835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov case MSG_ON_ALL_PRINT_JOBS_HANDLED: { 227835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (mClient != null) { 228835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov try { 229835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov mClient.onAllPrintJobsHandled(); 230835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } catch (RemoteException re) { 231835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.e(LOG_TAG, "Error notify for all print job handled.", re); 232835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 233835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 234835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } break; 235835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov 236835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov case MSG_CHECK_ALL_PRINTJOBS_HANDLED: { 237269403b032f965ff3847eb982c2f697229dc5a92Svetoslav checkAllPrintJobsHandled(); 238269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } break; 239704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 240704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov case MSG_ON_PRINT_JOB_STATE_CHANGED: { 241704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mClient != null) { 242dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo printJob = (PrintJobInfo) message.obj; 243704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 244dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mClient.onPrintJobStateChanged(printJob); 245704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } catch (RemoteException re) { 246704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Slog.e(LOG_TAG, "Error notify for print job state change.", re); 247704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 248704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 249704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } break; 2504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 2524b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 253269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 254269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, 255269403b032f965ff3847eb982c2f697229dc5a92Svetoslav int state, int appId) { 256269403b032f965ff3847eb982c2f697229dc5a92Svetoslav List<PrintJobInfo> foundPrintJobs = null; 257269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 258269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int printJobCount = mPrintJobs.size(); 259269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int i = 0; i < printJobCount; i++) { 260269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = mPrintJobs.get(i); 261269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrinterId printerId = printJob.getPrinterId(); 262269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final boolean sameComponent = (componentName == null 263269403b032f965ff3847eb982c2f697229dc5a92Svetoslav || (printerId != null 264269403b032f965ff3847eb982c2f697229dc5a92Svetoslav && componentName.equals(printerId.getServiceName()))); 265269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final boolean sameAppId = appId == PrintManager.APP_ID_ANY 266269403b032f965ff3847eb982c2f697229dc5a92Svetoslav || printJob.getAppId() == appId; 267269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final boolean sameState = (state == printJob.getState()) 268269403b032f965ff3847eb982c2f697229dc5a92Svetoslav || (state == PrintJobInfo.STATE_ANY) 269269403b032f965ff3847eb982c2f697229dc5a92Svetoslav || (state == PrintJobInfo.STATE_ANY_VISIBLE_TO_CLIENTS 270d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov && isStateVisibleToUser(printJob.getState())) 271d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov || (state == PrintJobInfo.STATE_ANY_ACTIVE 2729b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov && isActiveState(printJob.getState())) 2739b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov || (state == PrintJobInfo.STATE_ANY_SCHEDULED 2749b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov && isScheduledState(printJob.getState())); 275269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (sameComponent && sameAppId && sameState) { 276269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (foundPrintJobs == null) { 277269403b032f965ff3847eb982c2f697229dc5a92Svetoslav foundPrintJobs = new ArrayList<PrintJobInfo>(); 278269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 279269403b032f965ff3847eb982c2f697229dc5a92Svetoslav foundPrintJobs.add(printJob); 280269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 281269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 282269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 283269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return foundPrintJobs; 284269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 285269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 286d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private boolean isStateVisibleToUser(int state) { 287d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return (isActiveState(state) && (state == PrintJobInfo.STATE_FAILED 2882fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav || state == PrintJobInfo.STATE_COMPLETED || state == PrintJobInfo.STATE_CANCELED 2892fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav || state == PrintJobInfo.STATE_BLOCKED)); 290d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 291d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 2922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) { 293269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 294269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int printJobCount = mPrintJobs.size(); 295269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int i = 0; i < printJobCount; i++) { 296269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = mPrintJobs.get(i); 2972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (printJob.getId().equals(printJobId) 298269403b032f965ff3847eb982c2f697229dc5a92Svetoslav && (appId == PrintManager.APP_ID_ANY 299269403b032f965ff3847eb982c2f697229dc5a92Svetoslav || appId == printJob.getAppId())) { 300269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return printJob; 301269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 302269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 303269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return null; 304269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 305269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 306269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 3072fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void createPrintJob(PrintJobInfo printJob) { 308269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 309269403b032f965ff3847eb982c2f697229dc5a92Svetoslav addPrintJobLocked(printJob); 310dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov setPrintJobState(printJob.getId(), PrintJobInfo.STATE_CREATED, null); 3117bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 3127bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Message message = mHandlerCaller.obtainMessageO( 3137bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED, 3147bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav printJob); 3157bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav mHandlerCaller.executeOrSendMessage(message); 316269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 317269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 318269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 319269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void handleReadPrintJobsLocked() { 320dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Make a map with the files for a print job since we may have 321dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // to delete some. One example of getting orphan files if the 322dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // spooler crashes while constructing a print job. We do not 323dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // persist partially populated print jobs under construction to 324dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // avoid special handling for various attributes missing. 325dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov ArrayMap<PrintJobId, File> fileForJobMap = null; 326dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov File[] files = getFilesDir().listFiles(); 327dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (files != null) { 328dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int fileCount = files.length; 329dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < fileCount; i++) { 330dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov File file = files[i]; 331dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (file.isFile() && file.getName().startsWith(PRINT_JOB_FILE_PREFIX)) { 332dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (fileForJobMap == null) { 333dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov fileForJobMap = new ArrayMap<PrintJobId, File>(); 334dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 3352b40c83ae1ec17ea9371c3fd3ac6c79c156faa1dSvetoslav Ganov String printJobIdString = file.getName().substring( 3362b40c83ae1ec17ea9371c3fd3ac6c79c156faa1dSvetoslav Ganov PRINT_JOB_FILE_PREFIX.length(), 3372b40c83ae1ec17ea9371c3fd3ac6c79c156faa1dSvetoslav Ganov file.getName().indexOf('.')); 338dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobId printJobId = PrintJobId.unflattenFromString( 339dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobIdString); 340dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov fileForJobMap.put(printJobId, file); 341dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 342dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 343dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 344dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 345269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int printJobCount = mPrintJobs.size(); 346269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int i = 0; i < printJobCount; i++) { 347269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = mPrintJobs.get(i); 348269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 349dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // We want to have only the orphan files at the end. 350dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (fileForJobMap != null) { 351dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov fileForJobMap.remove(printJob.getId()); 352dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 353dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 354269403b032f965ff3847eb982c2f697229dc5a92Svetoslav switch (printJob.getState()) { 355269403b032f965ff3847eb982c2f697229dc5a92Svetoslav case PrintJobInfo.STATE_QUEUED: 356d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov case PrintJobInfo.STATE_STARTED: 357d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov case PrintJobInfo.STATE_BLOCKED: { 358d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // We have a print job that was queued or started or blocked in 359d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // the past but the device battery died or a crash occurred. In 360d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // this case we assume the print job failed and let the user 361d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // decide whether to restart the job or just cancel it. 362269403b032f965ff3847eb982c2f697229dc5a92Svetoslav setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED, 363269403b032f965ff3847eb982c2f697229dc5a92Svetoslav getString(R.string.no_connection_to_printer)); 3642fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } break; 365269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 366269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 367dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 368a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (!mPrintJobs.isEmpty()) { 369a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov // Update the notification. 370a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mNotificationController.onUpdateNotifications(mPrintJobs); 371a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 372a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 373dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Delete the orphan files. 374dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (fileForJobMap != null) { 375dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int orphanFileCount = fileForJobMap.size(); 376dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < orphanFileCount; i++) { 377dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov File file = fileForJobMap.valueAt(i); 378dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov file.delete(); 379dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 380dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 381269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 382269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 383269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public void checkAllPrintJobsHandled() { 384269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 385269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!hasActivePrintJobsLocked()) { 386269403b032f965ff3847eb982c2f697229dc5a92Svetoslav notifyOnAllPrintJobsHandled(); 387269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 388269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 389269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 390269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 3912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void writePrintJobData(final ParcelFileDescriptor fd, final PrintJobId printJobId) { 392269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final PrintJobInfo printJob; 393269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 394269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 395269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 396269403b032f965ff3847eb982c2f697229dc5a92Svetoslav new AsyncTask<Void, Void, Void>() { 397269403b032f965ff3847eb982c2f697229dc5a92Svetoslav @Override 398269403b032f965ff3847eb982c2f697229dc5a92Svetoslav protected Void doInBackground(Void... params) { 399269403b032f965ff3847eb982c2f697229dc5a92Svetoslav FileInputStream in = null; 400269403b032f965ff3847eb982c2f697229dc5a92Svetoslav FileOutputStream out = null; 401269403b032f965ff3847eb982c2f697229dc5a92Svetoslav try { 402269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 403269403b032f965ff3847eb982c2f697229dc5a92Svetoslav File file = generateFileForPrintJob(printJobId); 404269403b032f965ff3847eb982c2f697229dc5a92Svetoslav in = new FileInputStream(file); 405269403b032f965ff3847eb982c2f697229dc5a92Svetoslav out = new FileOutputStream(fd.getFileDescriptor()); 406269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 407269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final byte[] buffer = new byte[8192]; 408269403b032f965ff3847eb982c2f697229dc5a92Svetoslav while (true) { 409269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int readByteCount = in.read(buffer); 410269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (readByteCount < 0) { 411269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return null; 412269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 413269403b032f965ff3847eb982c2f697229dc5a92Svetoslav out.write(buffer, 0, readByteCount); 414269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 415269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (FileNotFoundException fnfe) { 416269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.e(LOG_TAG, "Error writing print job data!", fnfe); 417269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (IOException ioe) { 418269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.e(LOG_TAG, "Error writing print job data!", ioe); 419269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } finally { 420269403b032f965ff3847eb982c2f697229dc5a92Svetoslav IoUtils.closeQuietly(in); 421269403b032f965ff3847eb982c2f697229dc5a92Svetoslav IoUtils.closeQuietly(out); 422269403b032f965ff3847eb982c2f697229dc5a92Svetoslav IoUtils.closeQuietly(fd); 423269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 424269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.i(LOG_TAG, "[END WRITE]"); 425269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return null; 426269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 427269403b032f965ff3847eb982c2f697229dc5a92Svetoslav }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 428269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 429269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 4302fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public File generateFileForPrintJob(PrintJobId printJobId) { 431dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return new File(getFilesDir(), PRINT_JOB_FILE_PREFIX 4322fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav + printJobId.flattenToString() + "." + PRINT_FILE_EXTENSION); 433269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 434269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 435269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void addPrintJobLocked(PrintJobInfo printJob) { 436269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mPrintJobs.add(printJob); 437269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PRINT_JOB_LIFECYCLE) { 438269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.i(LOG_TAG, "[ADD] " + printJob); 439269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 440269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 441269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 4422fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav private void removeObsoletePrintJobs() { 4432fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 444885810de69d75979df4299d21fa236490767eae4Svetoslav boolean persistState = false; 4452fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav final int printJobCount = mPrintJobs.size(); 4462fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav for (int i = printJobCount - 1; i >= 0; i--) { 4472fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintJobInfo printJob = mPrintJobs.get(i); 4482fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (isObsoleteState(printJob.getState())) { 4492fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mPrintJobs.remove(i); 4502fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (DEBUG_PRINT_JOB_LIFECYCLE) { 4512fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.i(LOG_TAG, "[REMOVE] " + printJob.getId().flattenToString()); 4522fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 4532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav removePrintJobFileLocked(printJob.getId()); 454885810de69d75979df4299d21fa236490767eae4Svetoslav persistState = true; 4552fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 4562fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 457885810de69d75979df4299d21fa236490767eae4Svetoslav if (persistState) { 458885810de69d75979df4299d21fa236490767eae4Svetoslav mPersistanceManager.writeStateLocked(); 459885810de69d75979df4299d21fa236490767eae4Svetoslav } 4602fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 4612fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 4622fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 4632fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav private void removePrintJobFileLocked(PrintJobId printJobId) { 4642fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav File file = generateFileForPrintJob(printJobId); 4652fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (file.exists()) { 4662fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav file.delete(); 467269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PRINT_JOB_LIFECYCLE) { 468dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov Slog.i(LOG_TAG, "[REMOVE FILE FOR] " + printJobId); 469269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 470269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 471269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 472269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 4732fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobState(PrintJobId printJobId, int state, String error) { 474269403b032f965ff3847eb982c2f697229dc5a92Svetoslav boolean success = false; 475269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 476269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 477269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 478269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 479704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final int oldState = printJob.getState(); 480704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (oldState == state) { 481704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return false; 482704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 483704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 484269403b032f965ff3847eb982c2f697229dc5a92Svetoslav success = true; 485269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 486269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setState(state); 487d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov printJob.setStateReason(error); 488a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov printJob.setCancelling(false); 489269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 490269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PRINT_JOB_LIFECYCLE) { 491269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob); 492269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 493269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 494269403b032f965ff3847eb982c2f697229dc5a92Svetoslav switch (state) { 495269403b032f965ff3847eb982c2f697229dc5a92Svetoslav case PrintJobInfo.STATE_COMPLETED: 496269403b032f965ff3847eb982c2f697229dc5a92Svetoslav case PrintJobInfo.STATE_CANCELED: 497dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mPrintJobs.remove(printJob); 4982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav removePrintJobFileLocked(printJob.getId()); 499269403b032f965ff3847eb982c2f697229dc5a92Svetoslav // $fall-through$ 500269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 501269403b032f965ff3847eb982c2f697229dc5a92Svetoslav case PrintJobInfo.STATE_FAILED: { 502269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrinterId printerId = printJob.getPrinterId(); 503269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printerId != null) { 504269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ComponentName service = printerId.getServiceName(); 505269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!hasActivePrintJobsForServiceLocked(service)) { 506269403b032f965ff3847eb982c2f697229dc5a92Svetoslav sendOnAllPrintJobsForServiceHandled(service); 507269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 508269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 509269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } break; 510269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 511269403b032f965ff3847eb982c2f697229dc5a92Svetoslav case PrintJobInfo.STATE_QUEUED: { 512269403b032f965ff3847eb982c2f697229dc5a92Svetoslav sendOnPrintJobQueued(new PrintJobInfo(printJob)); 513269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } break; 514269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 515269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 516269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (shouldPersistPrintJob(printJob)) { 517269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mPersistanceManager.writeStateLocked(); 518269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 519269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 520269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!hasActivePrintJobsLocked()) { 521269403b032f965ff3847eb982c2f697229dc5a92Svetoslav notifyOnAllPrintJobsHandled(); 522269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 523704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 524dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov Message message = mHandlerCaller.obtainMessageO( 525704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED, 526dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJob); 527704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mHandlerCaller.executeOrSendMessage(message); 528a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 529a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mNotificationController.onUpdateNotifications(mPrintJobs); 530269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 531269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 532269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 533269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return success; 534269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 535269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 536269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public boolean hasActivePrintJobsLocked() { 537269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int printJobCount = mPrintJobs.size(); 538269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int i = 0; i < printJobCount; i++) { 539269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = mPrintJobs.get(i); 540269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (isActiveState(printJob.getState())) { 541269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return true; 542269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 543269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 544269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 545269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 546269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 547269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public boolean hasActivePrintJobsForServiceLocked(ComponentName service) { 548269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int printJobCount = mPrintJobs.size(); 549269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int i = 0; i < printJobCount; i++) { 550269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = mPrintJobs.get(i); 55175d28505c8f73a977cc7ae0cc08a60120f7c92b2Svetoslav if (isActiveState(printJob.getState()) && printJob.getPrinterId() != null 552269403b032f965ff3847eb982c2f697229dc5a92Svetoslav && printJob.getPrinterId().getServiceName().equals(service)) { 553269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return true; 554269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 555269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 556269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 557269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 558269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 5592fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav private boolean isObsoleteState(int printJobState) { 5602fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return (isTeminalState(printJobState) 5612fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav || printJobState == PrintJobInfo.STATE_QUEUED); 5622fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5632fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 5649b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov private boolean isScheduledState(int printJobState) { 5659b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov return printJobState == PrintJobInfo.STATE_QUEUED 5669b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov || printJobState == PrintJobInfo.STATE_STARTED 5679b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov || printJobState == PrintJobInfo.STATE_BLOCKED; 5689b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov } 5699b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov 570269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private boolean isActiveState(int printJobState) { 571269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return printJobState == PrintJobInfo.STATE_CREATED 572269403b032f965ff3847eb982c2f697229dc5a92Svetoslav || printJobState == PrintJobInfo.STATE_QUEUED 573d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov || printJobState == PrintJobInfo.STATE_STARTED 574d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov || printJobState == PrintJobInfo.STATE_BLOCKED; 575269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 576269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 5772fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav private boolean isTeminalState(int printJobState) { 5782fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return printJobState == PrintJobInfo.STATE_COMPLETED 5792fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav || printJobState == PrintJobInfo.STATE_CANCELED; 5802fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5812fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 5822fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobTag(PrintJobId printJobId, String tag) { 583269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 584269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 585269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 586269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String printJobTag = printJob.getTag(); 587269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJobTag == null) { 588269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (tag == null) { 589269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 590269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 591269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } else if (printJobTag.equals(tag)) { 592269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 593269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 594269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setTag(tag); 595269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (shouldPersistPrintJob(printJob)) { 596269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mPersistanceManager.writeStateLocked(); 597269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 598269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return true; 599269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 600269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 601269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 602269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 603269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 604a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov public void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) { 605a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 606a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 607a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (printJob != null) { 608a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov printJob.setCancelling(cancelling); 609a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (shouldPersistPrintJob(printJob)) { 610a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mPersistanceManager.writeStateLocked(); 611a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 612a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mNotificationController.onUpdateNotifications(mPrintJobs); 613a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 614a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Message message = mHandlerCaller.obtainMessageO( 615a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED, 616a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov printJob); 617a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mHandlerCaller.executeOrSendMessage(message); 618a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 619a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 620a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 621a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 6222fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void setPrintJobCopiesNoPersistence(PrintJobId printJobId, int copies) { 623269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 624269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 625269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 626269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setCopies(copies); 627269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 628269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 629269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 630269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 631b4fda134761c9521a7e127db3806a07a18763b77Svetoslav public void setPrintJobAdvancedOptionsNoPersistence(PrintJobId printJobId, 632b4fda134761c9521a7e127db3806a07a18763b77Svetoslav Bundle advancedOptions) { 633b4fda134761c9521a7e127db3806a07a18763b77Svetoslav synchronized (mLock) { 634b4fda134761c9521a7e127db3806a07a18763b77Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 635b4fda134761c9521a7e127db3806a07a18763b77Svetoslav if (printJob != null) { 636b4fda134761c9521a7e127db3806a07a18763b77Svetoslav printJob.setAdvancedOptions(advancedOptions); 637b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 638b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 639b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 640b4fda134761c9521a7e127db3806a07a18763b77Svetoslav 6412fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void setPrintJobPrintDocumentInfoNoPersistence(PrintJobId printJobId, 6422fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintDocumentInfo info) { 643269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 644269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 645269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 646269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setDocumentInfo(info); 647269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 648269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 649269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 650269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 6512fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void setPrintJobAttributesNoPersistence(PrintJobId printJobId, 6522fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintAttributes attributes) { 653269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 654269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 655269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 656269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setAttributes(attributes); 657269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 658269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 659269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 660269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 6612fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void setPrintJobPrinterNoPersistence(PrintJobId printJobId, PrinterInfo printer) { 662269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 663269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 664269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 665269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setPrinterId(printer.getId()); 666269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setPrinterName(printer.getName()); 667269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 668269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 669269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 670269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 6712fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void setPrintJobPagesNoPersistence(PrintJobId printJobId, PageRange[] pages) { 672269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 673269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY); 674269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printJob != null) { 675269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setPages(pages); 676269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 677269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 678269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 679269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 680269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private boolean shouldPersistPrintJob(PrintJobInfo printJob) { 681269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return printJob.getState() >= PrintJobInfo.STATE_QUEUED; 682269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 683269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 684269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void notifyOnAllPrintJobsHandled() { 685269403b032f965ff3847eb982c2f697229dc5a92Svetoslav // This has to run on the tread that is persisting the current state 686269403b032f965ff3847eb982c2f697229dc5a92Svetoslav // since this call may result in the system unbinding from the spooler 687269403b032f965ff3847eb982c2f697229dc5a92Svetoslav // and as a result the spooler process may get killed before the write 688269403b032f965ff3847eb982c2f697229dc5a92Svetoslav // completes. 689269403b032f965ff3847eb982c2f697229dc5a92Svetoslav new AsyncTask<Void, Void, Void>() { 690269403b032f965ff3847eb982c2f697229dc5a92Svetoslav @Override 691269403b032f965ff3847eb982c2f697229dc5a92Svetoslav protected Void doInBackground(Void... params) { 692269403b032f965ff3847eb982c2f697229dc5a92Svetoslav sendOnAllPrintJobsHandled(); 693269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return null; 694269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 695269403b032f965ff3847eb982c2f697229dc5a92Svetoslav }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); 696269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 697269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 698269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private final class PersistenceManager { 699269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String PERSIST_FILE_NAME = "print_spooler_state.xml"; 700269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 701269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_SPOOLER = "spooler"; 702269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_JOB = "job"; 703269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 704269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_PRINTER_ID = "printerId"; 705269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_PAGE_RANGE = "pageRange"; 706269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_ATTRIBUTES = "attributes"; 707269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_DOCUMENT_INFO = "documentInfo"; 708269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 709269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_ID = "id"; 710269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_LABEL = "label"; 711773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav private static final String ATTR_LABEL_RES_ID = "labelResId"; 712773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav private static final String ATTR_PACKAGE_NAME = "packageName"; 713269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_STATE = "state"; 714269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_APP_ID = "appId"; 715269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_TAG = "tag"; 716704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private static final String ATTR_CREATION_TIME = "creationTime"; 717269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_COPIES = "copies"; 718704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private static final String ATTR_PRINTER_NAME = "printerName"; 719704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private static final String ATTR_STATE_REASON = "stateReason"; 720a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov private static final String ATTR_CANCELLING = "cancelling"; 721269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 722b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String TAG_ADVANCED_OPTIONS = "advancedOptions"; 723b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String TAG_ADVANCED_OPTION = "advancedOption"; 724b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String ATTR_KEY = "key"; 725b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String ATTR_TYPE = "type"; 726b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String ATTR_VALUE = "value"; 727b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String TYPE_STRING = "string"; 728b4fda134761c9521a7e127db3806a07a18763b77Svetoslav private static final String TYPE_INT = "int"; 729b4fda134761c9521a7e127db3806a07a18763b77Svetoslav 730269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_MEDIA_SIZE = "mediaSize"; 731269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_RESOLUTION = "resolution"; 732269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String TAG_MARGINS = "margins"; 733269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 734269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_COLOR_MODE = "colorMode"; 735269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 736704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private static final String ATTR_LOCAL_ID = "localId"; 737269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_SERVICE_NAME = "serviceName"; 738269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 739269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_WIDTH_MILS = "widthMils"; 740269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_HEIGHT_MILS = "heightMils"; 741269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 742269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_HORIZONTAL_DPI = "horizontalDip"; 743269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_VERTICAL_DPI = "verticalDpi"; 744269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 745269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_LEFT_MILS = "leftMils"; 746269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_TOP_MILS = "topMils"; 747269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_RIGHT_MILS = "rightMils"; 748269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_BOTTOM_MILS = "bottomMils"; 749269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 750269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_START = "start"; 751269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_END = "end"; 752269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 753269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_NAME = "name"; 754269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_PAGE_COUNT = "pageCount"; 755269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private static final String ATTR_CONTENT_TYPE = "contentType"; 7567d7888d1c7daa78ee0ad24a24c8dd54b01749259Svetoslav Ganov private static final String ATTR_DATA_SIZE = "dataSize"; 757269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 758269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private final AtomicFile mStatePersistFile; 759269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 760269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private boolean mWriteStateScheduled; 761269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 762269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private PersistenceManager() { 763269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mStatePersistFile = new AtomicFile(new File(getFilesDir(), 764269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PERSIST_FILE_NAME)); 765269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 766269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 767269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public void writeStateLocked() { 768269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!PERSISTNECE_MANAGER_ENABLED) { 769269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 770269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 771269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mWriteStateScheduled) { 772269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 773269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 774269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mWriteStateScheduled = true; 775269403b032f965ff3847eb982c2f697229dc5a92Svetoslav new AsyncTask<Void, Void, Void>() { 776269403b032f965ff3847eb982c2f697229dc5a92Svetoslav @Override 777269403b032f965ff3847eb982c2f697229dc5a92Svetoslav protected Void doInBackground(Void... params) { 778269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 779269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mWriteStateScheduled = false; 780269403b032f965ff3847eb982c2f697229dc5a92Svetoslav doWriteStateLocked(); 781269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 782269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return null; 783269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 784269403b032f965ff3847eb982c2f697229dc5a92Svetoslav }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); 785269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 786269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 787269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void doWriteStateLocked() { 788269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PERSISTENCE) { 789269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.i(LOG_TAG, "[PERSIST START]"); 790269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 791269403b032f965ff3847eb982c2f697229dc5a92Svetoslav FileOutputStream out = null; 792269403b032f965ff3847eb982c2f697229dc5a92Svetoslav try { 793269403b032f965ff3847eb982c2f697229dc5a92Svetoslav out = mStatePersistFile.startWrite(); 794269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 795269403b032f965ff3847eb982c2f697229dc5a92Svetoslav XmlSerializer serializer = new FastXmlSerializer(); 796269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.setOutput(out, "utf-8"); 797269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startDocument(null, true); 798269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_SPOOLER); 799269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 800269403b032f965ff3847eb982c2f697229dc5a92Svetoslav List<PrintJobInfo> printJobs = mPrintJobs; 801269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 802269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int printJobCount = printJobs.size(); 803269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int j = 0; j < printJobCount; j++) { 804269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = printJobs.get(j); 805269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 806885810de69d75979df4299d21fa236490767eae4Svetoslav if (!shouldPersistPrintJob(printJob)) { 807885810de69d75979df4299d21fa236490767eae4Svetoslav continue; 808885810de69d75979df4299d21fa236490767eae4Svetoslav } 809885810de69d75979df4299d21fa236490767eae4Svetoslav 810269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_JOB); 811269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 8122fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav serializer.attribute(null, ATTR_ID, printJob.getId().flattenToString()); 813269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_LABEL, printJob.getLabel().toString()); 814269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_STATE, String.valueOf(printJob.getState())); 815269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_APP_ID, String.valueOf(printJob.getAppId())); 816269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String tag = printJob.getTag(); 817269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (tag != null) { 818269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_TAG, tag); 819269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 820704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov serializer.attribute(null, ATTR_CREATION_TIME, String.valueOf( 821704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov printJob.getCreationTime())); 822269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_COPIES, String.valueOf(printJob.getCopies())); 823704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov String printerName = printJob.getPrinterName(); 824704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (!TextUtils.isEmpty(printerName)) { 825704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov serializer.attribute(null, ATTR_PRINTER_NAME, printerName); 826704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 827704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov String stateReason = printJob.getStateReason(); 828704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (!TextUtils.isEmpty(stateReason)) { 829704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov serializer.attribute(null, ATTR_STATE_REASON, stateReason); 830704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 831a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov serializer.attribute(null, ATTR_CANCELLING, String.valueOf( 832a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov printJob.isCancelling())); 833269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 834269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrinterId printerId = printJob.getPrinterId(); 835269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (printerId != null) { 836269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_PRINTER_ID); 837269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_LOCAL_ID, printerId.getLocalId()); 838269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_SERVICE_NAME, printerId.getServiceName() 839269403b032f965ff3847eb982c2f697229dc5a92Svetoslav .flattenToString()); 840269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_PRINTER_ID); 841269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 842269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 843269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PageRange[] pages = printJob.getPages(); 844269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (pages != null) { 845269403b032f965ff3847eb982c2f697229dc5a92Svetoslav for (int i = 0; i < pages.length; i++) { 846269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_PAGE_RANGE); 847269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_START, String.valueOf( 848269403b032f965ff3847eb982c2f697229dc5a92Svetoslav pages[i].getStart())); 849269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_END, String.valueOf( 850269403b032f965ff3847eb982c2f697229dc5a92Svetoslav pages[i].getEnd())); 851269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_PAGE_RANGE); 852269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 853269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 854269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 855269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintAttributes attributes = printJob.getAttributes(); 856269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (attributes != null) { 857269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_ATTRIBUTES); 858269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 859269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int colorMode = attributes.getColorMode(); 860269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_COLOR_MODE, 861269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String.valueOf(colorMode)); 862269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 863269403b032f965ff3847eb982c2f697229dc5a92Svetoslav MediaSize mediaSize = attributes.getMediaSize(); 864269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mediaSize != null) { 865269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_MEDIA_SIZE); 866269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_ID, mediaSize.getId()); 867269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_WIDTH_MILS, String.valueOf( 868269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mediaSize.getWidthMils())); 869269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_HEIGHT_MILS, String.valueOf( 870269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mediaSize.getHeightMils())); 871a76233ae845da4bc9e3bcd89821701a747215e7bSvetoslav // We prefer to store only the package name and 872a76233ae845da4bc9e3bcd89821701a747215e7bSvetoslav // resource id and fallback to the label. 873a76233ae845da4bc9e3bcd89821701a747215e7bSvetoslav if (!TextUtils.isEmpty(mediaSize.mPackageName) 874773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav && mediaSize.mLabelResId > 0) { 875773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav serializer.attribute(null, ATTR_PACKAGE_NAME, 876773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav mediaSize.mPackageName); 877773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav serializer.attribute(null, ATTR_LABEL_RES_ID, 878773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav String.valueOf(mediaSize.mLabelResId)); 879773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav } else { 880773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav serializer.attribute(null, ATTR_LABEL, 881773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav mediaSize.getLabel(getPackageManager())); 882773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav } 883269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_MEDIA_SIZE); 884269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 885269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 886269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Resolution resolution = attributes.getResolution(); 887269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (resolution != null) { 888269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_RESOLUTION); 889269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_ID, resolution.getId()); 890269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_HORIZONTAL_DPI, String.valueOf( 891269403b032f965ff3847eb982c2f697229dc5a92Svetoslav resolution.getHorizontalDpi())); 892269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_VERTICAL_DPI, String.valueOf( 893269403b032f965ff3847eb982c2f697229dc5a92Svetoslav resolution.getVerticalDpi())); 894c6066799ad130140159230d14451b429eb828755Svetoslav serializer.attribute(null, ATTR_LABEL, 895651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav resolution.getLabel()); 896269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_RESOLUTION); 897269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 898269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 899651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav Margins margins = attributes.getMinMargins(); 900269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (margins != null) { 901269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_MARGINS); 902269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_LEFT_MILS, String.valueOf( 903269403b032f965ff3847eb982c2f697229dc5a92Svetoslav margins.getLeftMils())); 904269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_TOP_MILS, String.valueOf( 905269403b032f965ff3847eb982c2f697229dc5a92Svetoslav margins.getTopMils())); 906269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_RIGHT_MILS, String.valueOf( 907269403b032f965ff3847eb982c2f697229dc5a92Svetoslav margins.getRightMils())); 908269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_BOTTOM_MILS, String.valueOf( 909269403b032f965ff3847eb982c2f697229dc5a92Svetoslav margins.getBottomMils())); 910269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_MARGINS); 911269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 912269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 913269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_ATTRIBUTES); 914269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 915269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 916269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintDocumentInfo documentInfo = printJob.getDocumentInfo(); 917269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (documentInfo != null) { 918269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.startTag(null, TAG_DOCUMENT_INFO); 919269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_NAME, documentInfo.getName()); 920269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_CONTENT_TYPE, String.valueOf( 921269403b032f965ff3847eb982c2f697229dc5a92Svetoslav documentInfo.getContentType())); 922269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.attribute(null, ATTR_PAGE_COUNT, String.valueOf( 923269403b032f965ff3847eb982c2f697229dc5a92Svetoslav documentInfo.getPageCount())); 9247d7888d1c7daa78ee0ad24a24c8dd54b01749259Svetoslav Ganov serializer.attribute(null, ATTR_DATA_SIZE, String.valueOf( 9257d7888d1c7daa78ee0ad24a24c8dd54b01749259Svetoslav Ganov documentInfo.getDataSize())); 926269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_DOCUMENT_INFO); 927269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 928269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 929b4fda134761c9521a7e127db3806a07a18763b77Svetoslav Bundle advancedOptions = printJob.getAdvancedOptions(); 930b4fda134761c9521a7e127db3806a07a18763b77Svetoslav if (advancedOptions != null) { 931b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.startTag(null, TAG_ADVANCED_OPTIONS); 932b4fda134761c9521a7e127db3806a07a18763b77Svetoslav for (String key : advancedOptions.keySet()) { 933b4fda134761c9521a7e127db3806a07a18763b77Svetoslav Object value = advancedOptions.get(key); 934b4fda134761c9521a7e127db3806a07a18763b77Svetoslav if (value instanceof String) { 935b4fda134761c9521a7e127db3806a07a18763b77Svetoslav String stringValue = (String) value; 936b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.startTag(null, TAG_ADVANCED_OPTION); 937b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.attribute(null, ATTR_KEY, key); 938b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.attribute(null, ATTR_TYPE, TYPE_STRING); 939b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.attribute(null, ATTR_VALUE, stringValue); 940b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.endTag(null, TAG_ADVANCED_OPTION); 941b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } else if (value instanceof Integer) { 942b4fda134761c9521a7e127db3806a07a18763b77Svetoslav String intValue = Integer.toString((Integer) value); 943b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.startTag(null, TAG_ADVANCED_OPTION); 944b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.attribute(null, ATTR_KEY, key); 945b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.attribute(null, ATTR_TYPE, TYPE_INT); 946b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.attribute(null, ATTR_VALUE, intValue); 947b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.endTag(null, TAG_ADVANCED_OPTION); 948b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 949b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 950b4fda134761c9521a7e127db3806a07a18763b77Svetoslav serializer.endTag(null, TAG_ADVANCED_OPTIONS); 951b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 952b4fda134761c9521a7e127db3806a07a18763b77Svetoslav 953269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_JOB); 954269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 955269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PERSISTENCE) { 956269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.i(LOG_TAG, "[PERSISTED] " + printJob); 957269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 958269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 959269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 960269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endTag(null, TAG_SPOOLER); 961269403b032f965ff3847eb982c2f697229dc5a92Svetoslav serializer.endDocument(); 962269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mStatePersistFile.finishWrite(out); 963269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PERSISTENCE) { 964269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.i(LOG_TAG, "[PERSIST END]"); 965269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 966269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (IOException e) { 967269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed to write state, restoring backup.", e); 968269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mStatePersistFile.failWrite(out); 969269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } finally { 970269403b032f965ff3847eb982c2f697229dc5a92Svetoslav IoUtils.closeQuietly(out); 971269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 972269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 973269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 974269403b032f965ff3847eb982c2f697229dc5a92Svetoslav public void readStateLocked() { 975269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!PERSISTNECE_MANAGER_ENABLED) { 976269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 977269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 978269403b032f965ff3847eb982c2f697229dc5a92Svetoslav FileInputStream in = null; 979269403b032f965ff3847eb982c2f697229dc5a92Svetoslav try { 980269403b032f965ff3847eb982c2f697229dc5a92Svetoslav in = mStatePersistFile.openRead(); 981269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (FileNotFoundException e) { 982269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.i(LOG_TAG, "No existing print spooler state."); 983269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 984269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 985269403b032f965ff3847eb982c2f697229dc5a92Svetoslav try { 986269403b032f965ff3847eb982c2f697229dc5a92Svetoslav XmlPullParser parser = Xml.newPullParser(); 987269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.setInput(in, null); 988269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parseState(parser); 989269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (IllegalStateException ise) { 990269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed parsing ", ise); 991269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (NullPointerException npe) { 992269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed parsing ", npe); 993269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (NumberFormatException nfe) { 994269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed parsing ", nfe); 995269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (XmlPullParserException xppe) { 996269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed parsing ", xppe); 997269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (IOException ioe) { 998269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed parsing ", ioe); 999269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } catch (IndexOutOfBoundsException iobe) { 1000269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Slog.w(LOG_TAG, "Failed parsing ", iobe); 1001269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } finally { 1002269403b032f965ff3847eb982c2f697229dc5a92Svetoslav IoUtils.closeQuietly(in); 1003269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1004269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1005269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1006269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void parseState(XmlPullParser parser) 1007269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throws IOException, XmlPullParserException { 1008269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1009269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1010269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.START_TAG, TAG_SPOOLER); 1011269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1012269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1013269403b032f965ff3847eb982c2f697229dc5a92Svetoslav while (parsePrintJob(parser)) { 1014269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1015269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1016269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1017269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1018269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_SPOOLER); 1019269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1020269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1021269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private boolean parsePrintJob(XmlPullParser parser) 1022269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throws IOException, XmlPullParserException { 1023269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1024269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!accept(parser, XmlPullParser.START_TAG, TAG_JOB)) { 1025269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 1026269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1027269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1028269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintJobInfo printJob = new PrintJobInfo(); 1029269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 10302fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintJobId printJobId = PrintJobId.unflattenFromString( 10312fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav parser.getAttributeValue(null, ATTR_ID)); 1032269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setId(printJobId); 1033269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String label = parser.getAttributeValue(null, ATTR_LABEL); 1034269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setLabel(label); 1035269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int state = Integer.parseInt(parser.getAttributeValue(null, ATTR_STATE)); 1036269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setState(state); 1037269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int appId = Integer.parseInt(parser.getAttributeValue(null, ATTR_APP_ID)); 1038269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setAppId(appId); 1039269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String tag = parser.getAttributeValue(null, ATTR_TAG); 1040269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setTag(tag); 1041704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov String creationTime = parser.getAttributeValue(null, ATTR_CREATION_TIME); 1042704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov printJob.setCreationTime(Long.parseLong(creationTime)); 1043269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String copies = parser.getAttributeValue(null, ATTR_COPIES); 1044269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setCopies(Integer.parseInt(copies)); 1045704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov String printerName = parser.getAttributeValue(null, ATTR_PRINTER_NAME); 1046704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov printJob.setPrinterName(printerName); 1047704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov String stateReason = parser.getAttributeValue(null, ATTR_STATE_REASON); 1048704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov printJob.setStateReason(stateReason); 1049a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov String cancelling = parser.getAttributeValue(null, ATTR_CANCELLING); 1050a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov printJob.setCancelling(!TextUtils.isEmpty(cancelling) 1051a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov ? Boolean.parseBoolean(cancelling) : false); 1052269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1053269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1054269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1055269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1056269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_PRINTER_ID)) { 1057269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String localId = parser.getAttributeValue(null, ATTR_LOCAL_ID); 1058269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ComponentName service = ComponentName.unflattenFromString(parser.getAttributeValue( 1059269403b032f965ff3847eb982c2f697229dc5a92Svetoslav null, ATTR_SERVICE_NAME)); 1060269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setPrinterId(new PrinterId(service, localId)); 1061269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1062269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1063269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_PRINTER_ID); 1064269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1065269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1066269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1067269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1068269403b032f965ff3847eb982c2f697229dc5a92Svetoslav List<PageRange> pageRanges = null; 1069269403b032f965ff3847eb982c2f697229dc5a92Svetoslav while (accept(parser, XmlPullParser.START_TAG, TAG_PAGE_RANGE)) { 1070269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int start = Integer.parseInt(parser.getAttributeValue(null, ATTR_START)); 1071269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int end = Integer.parseInt(parser.getAttributeValue(null, ATTR_END)); 1072269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PageRange pageRange = new PageRange(start, end); 1073269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (pageRanges == null) { 1074269403b032f965ff3847eb982c2f697229dc5a92Svetoslav pageRanges = new ArrayList<PageRange>(); 1075269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1076269403b032f965ff3847eb982c2f697229dc5a92Svetoslav pageRanges.add(pageRange); 1077269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1078269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1079269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_PAGE_RANGE); 1080269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1081b4fda134761c9521a7e127db3806a07a18763b77Svetoslav skipEmptyTextTags(parser); 1082269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1083269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (pageRanges != null) { 1084269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PageRange[] pageRangesArray = new PageRange[pageRanges.size()]; 1085269403b032f965ff3847eb982c2f697229dc5a92Svetoslav pageRanges.toArray(pageRangesArray); 1086269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setPages(pageRangesArray); 1087269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1088269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1089269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1090269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_ATTRIBUTES)) { 1091269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1092269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintAttributes.Builder builder = new PrintAttributes.Builder(); 1093269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1094269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String colorMode = parser.getAttributeValue(null, ATTR_COLOR_MODE); 1095269403b032f965ff3847eb982c2f697229dc5a92Svetoslav builder.setColorMode(Integer.parseInt(colorMode)); 1096269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1097269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1098269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1099269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1100269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_MEDIA_SIZE)) { 1101269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String id = parser.getAttributeValue(null, ATTR_ID); 1102269403b032f965ff3847eb982c2f697229dc5a92Svetoslav label = parser.getAttributeValue(null, ATTR_LABEL); 1103269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int widthMils = Integer.parseInt(parser.getAttributeValue(null, 1104269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_WIDTH_MILS)); 1105269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int heightMils = Integer.parseInt(parser.getAttributeValue(null, 1106269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_HEIGHT_MILS)); 1107773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 1108b206f1271d17164c3f2f65219eee7a0b4b4fa6dcSvetoslav String labelResIdString = parser.getAttributeValue(null, ATTR_LABEL_RES_ID); 1109b206f1271d17164c3f2f65219eee7a0b4b4fa6dcSvetoslav final int labelResId = (labelResIdString != null) 1110b206f1271d17164c3f2f65219eee7a0b4b4fa6dcSvetoslav ? Integer.parseInt(labelResIdString) : 0; 1111773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav label = parser.getAttributeValue(null, ATTR_LABEL); 1112b4fda134761c9521a7e127db3806a07a18763b77Svetoslav MediaSize mediaSize = new MediaSize(id, label, packageName, 1113b4fda134761c9521a7e127db3806a07a18763b77Svetoslav widthMils, heightMils, labelResId); 1114269403b032f965ff3847eb982c2f697229dc5a92Svetoslav builder.setMediaSize(mediaSize); 1115269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1116269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1117269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_MEDIA_SIZE); 1118269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1119269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1120269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1121269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1122269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_RESOLUTION)) { 1123269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String id = parser.getAttributeValue(null, ATTR_ID); 1124269403b032f965ff3847eb982c2f697229dc5a92Svetoslav label = parser.getAttributeValue(null, ATTR_LABEL); 1125269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int horizontalDpi = Integer.parseInt(parser.getAttributeValue(null, 1126269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_HORIZONTAL_DPI)); 1127269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int verticalDpi = Integer.parseInt(parser.getAttributeValue(null, 1128269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_VERTICAL_DPI)); 1129c6066799ad130140159230d14451b429eb828755Svetoslav Resolution resolution = new Resolution(id, label, horizontalDpi, verticalDpi); 1130269403b032f965ff3847eb982c2f697229dc5a92Svetoslav builder.setResolution(resolution); 1131269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1132269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1133269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_RESOLUTION); 1134269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1135269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1136269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1137269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1138269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_MARGINS)) { 1139269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int leftMils = Integer.parseInt(parser.getAttributeValue(null, 1140269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_LEFT_MILS)); 1141269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int topMils = Integer.parseInt(parser.getAttributeValue(null, 1142269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_TOP_MILS)); 1143269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int rightMils = Integer.parseInt(parser.getAttributeValue(null, 1144269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_RIGHT_MILS)); 1145269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int bottomMils = Integer.parseInt(parser.getAttributeValue(null, 1146269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_BOTTOM_MILS)); 1147269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Margins margins = new Margins(leftMils, topMils, rightMils, bottomMils); 1148651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav builder.setMinMargins(margins); 1149269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1150269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1151269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_MARGINS); 1152269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1153269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1154269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1155651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav printJob.setAttributes(builder.build()); 1156269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1157269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1158269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_ATTRIBUTES); 1159269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1160269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1161269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1162269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1163269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_DOCUMENT_INFO)) { 1164269403b032f965ff3847eb982c2f697229dc5a92Svetoslav String name = parser.getAttributeValue(null, ATTR_NAME); 1165269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int pageCount = Integer.parseInt(parser.getAttributeValue(null, 1166269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_PAGE_COUNT)); 1167269403b032f965ff3847eb982c2f697229dc5a92Svetoslav final int contentType = Integer.parseInt(parser.getAttributeValue(null, 1168269403b032f965ff3847eb982c2f697229dc5a92Svetoslav ATTR_CONTENT_TYPE)); 11697d7888d1c7daa78ee0ad24a24c8dd54b01749259Svetoslav Ganov final int dataSize = Integer.parseInt(parser.getAttributeValue(null, 11707d7888d1c7daa78ee0ad24a24c8dd54b01749259Svetoslav Ganov ATTR_DATA_SIZE)); 1171269403b032f965ff3847eb982c2f697229dc5a92Svetoslav PrintDocumentInfo info = new PrintDocumentInfo.Builder(name) 1172269403b032f965ff3847eb982c2f697229dc5a92Svetoslav .setPageCount(pageCount) 1173651dd4e6ee6510caf9f15c51094a11121af17ec2Svetoslav .setContentType(contentType).build(); 1174269403b032f965ff3847eb982c2f697229dc5a92Svetoslav printJob.setDocumentInfo(info); 11757d7888d1c7daa78ee0ad24a24c8dd54b01749259Svetoslav Ganov info.setDataSize(dataSize); 1176269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1177269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1178269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_DOCUMENT_INFO); 1179269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1180269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1181269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1182b4fda134761c9521a7e127db3806a07a18763b77Svetoslav skipEmptyTextTags(parser); 1183b4fda134761c9521a7e127db3806a07a18763b77Svetoslav if (accept(parser, XmlPullParser.START_TAG, TAG_ADVANCED_OPTIONS)) { 1184b4fda134761c9521a7e127db3806a07a18763b77Svetoslav parser.next(); 1185b4fda134761c9521a7e127db3806a07a18763b77Svetoslav skipEmptyTextTags(parser); 1186b4fda134761c9521a7e127db3806a07a18763b77Svetoslav Bundle advancedOptions = new Bundle(); 1187b4fda134761c9521a7e127db3806a07a18763b77Svetoslav while (accept(parser, XmlPullParser.START_TAG, TAG_ADVANCED_OPTION)) { 1188b4fda134761c9521a7e127db3806a07a18763b77Svetoslav String key = parser.getAttributeValue(null, ATTR_KEY); 1189b4fda134761c9521a7e127db3806a07a18763b77Svetoslav String value = parser.getAttributeValue(null, ATTR_VALUE); 1190b4fda134761c9521a7e127db3806a07a18763b77Svetoslav String type = parser.getAttributeValue(null, ATTR_TYPE); 1191b4fda134761c9521a7e127db3806a07a18763b77Svetoslav if (TYPE_STRING.equals(type)) { 1192b4fda134761c9521a7e127db3806a07a18763b77Svetoslav advancedOptions.putString(key, value); 1193b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } else if (TYPE_INT.equals(type)) { 1194b4fda134761c9521a7e127db3806a07a18763b77Svetoslav advancedOptions.putInt(key, Integer.valueOf(value)); 1195b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 1196b4fda134761c9521a7e127db3806a07a18763b77Svetoslav parser.next(); 1197b4fda134761c9521a7e127db3806a07a18763b77Svetoslav skipEmptyTextTags(parser); 1198b4fda134761c9521a7e127db3806a07a18763b77Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_ADVANCED_OPTION); 1199b4fda134761c9521a7e127db3806a07a18763b77Svetoslav parser.next(); 1200b4fda134761c9521a7e127db3806a07a18763b77Svetoslav skipEmptyTextTags(parser); 1201b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 1202b4fda134761c9521a7e127db3806a07a18763b77Svetoslav printJob.setAdvancedOptions(advancedOptions); 1203b4fda134761c9521a7e127db3806a07a18763b77Svetoslav skipEmptyTextTags(parser); 1204b4fda134761c9521a7e127db3806a07a18763b77Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_ADVANCED_OPTIONS); 1205b4fda134761c9521a7e127db3806a07a18763b77Svetoslav parser.next(); 1206b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 1207b4fda134761c9521a7e127db3806a07a18763b77Svetoslav 1208269403b032f965ff3847eb982c2f697229dc5a92Svetoslav mPrintJobs.add(printJob); 1209269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1210269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (DEBUG_PERSISTENCE) { 1211269403b032f965ff3847eb982c2f697229dc5a92Svetoslav Log.i(LOG_TAG, "[RESTORED] " + printJob); 1212269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1213269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1214269403b032f965ff3847eb982c2f697229dc5a92Svetoslav skipEmptyTextTags(parser); 1215269403b032f965ff3847eb982c2f697229dc5a92Svetoslav expect(parser, XmlPullParser.END_TAG, TAG_JOB); 1216269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1217269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return true; 1218269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1219269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1220269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void expect(XmlPullParser parser, int type, String tag) 1221269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throws IOException, XmlPullParserException { 1222269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!accept(parser, type, tag)) { 1223269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throw new XmlPullParserException("Exepected event: " + type 1224269403b032f965ff3847eb982c2f697229dc5a92Svetoslav + " and tag: " + tag + " but got event: " + parser.getEventType() 1225269403b032f965ff3847eb982c2f697229dc5a92Svetoslav + " and tag:" + parser.getName()); 1226269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1227269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1228269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1229269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private void skipEmptyTextTags(XmlPullParser parser) 1230269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throws IOException, XmlPullParserException { 1231269403b032f965ff3847eb982c2f697229dc5a92Svetoslav while (accept(parser, XmlPullParser.TEXT, null) 1232269403b032f965ff3847eb982c2f697229dc5a92Svetoslav && "\n".equals(parser.getText())) { 1233269403b032f965ff3847eb982c2f697229dc5a92Svetoslav parser.next(); 1234269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1235269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1236269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 1237269403b032f965ff3847eb982c2f697229dc5a92Svetoslav private boolean accept(XmlPullParser parser, int type, String tag) 1238269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throws IOException, XmlPullParserException { 1239269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (parser.getEventType() != type) { 1240269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 1241269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1242269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (tag != null) { 1243269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (!tag.equals(parser.getName())) { 1244269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 1245269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1246269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } else if (parser.getName() != null) { 1247269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return false; 1248269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1249269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return true; 1250269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 1251269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 12527bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 12537bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav final class PrintSpooler extends IPrintSpooler.Stub { 12547bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 12557bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void getPrintJobInfos(IPrintSpoolerCallbacks callback, 12567bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav ComponentName componentName, int state, int appId, int sequence) 12577bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav throws RemoteException { 12587bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav List<PrintJobInfo> printJobs = null; 12597bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav try { 12607bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav printJobs = PrintSpoolerService.this.getPrintJobInfos( 12617bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav componentName, state, appId); 12627bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } finally { 12637bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav callback.onGetPrintJobInfosResult(printJobs, sequence); 12647bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12657bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12667bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 12677bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 12687bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void getPrintJobInfo(PrintJobId printJobId, IPrintSpoolerCallbacks callback, 12697bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav int appId, int sequence) throws RemoteException { 12707bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintJobInfo printJob = null; 12717bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav try { 12727bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav printJob = PrintSpoolerService.this.getPrintJobInfo(printJobId, appId); 12737bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } finally { 12747bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav callback.onGetPrintJobInfoResult(printJob, sequence); 12757bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12767bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12777bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 12787bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 12797bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void createPrintJob(PrintJobInfo printJob) { 12807bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintSpoolerService.this.createPrintJob(printJob); 12817bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12827bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 12837bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 12847bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void setPrintJobState(PrintJobId printJobId, int state, String error, 12857bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav IPrintSpoolerCallbacks callback, int sequece) throws RemoteException { 12867bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav boolean success = false; 12877bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav try { 12887bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav success = PrintSpoolerService.this.setPrintJobState( 12897bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav printJobId, state, error); 12907bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } finally { 12917bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav callback.onSetPrintJobStateResult(success, sequece); 12927bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12937bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 12947bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 12957bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 12967bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void setPrintJobTag(PrintJobId printJobId, String tag, 12977bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav IPrintSpoolerCallbacks callback, int sequece) throws RemoteException { 12987bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav boolean success = false; 12997bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav try { 13007bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav success = PrintSpoolerService.this.setPrintJobTag(printJobId, tag); 13017bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } finally { 13027bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav callback.onSetPrintJobTagResult(success, sequece); 13037bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13047bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13057bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 13067bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 13077bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) { 13087bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintSpoolerService.this.writePrintJobData(fd, printJobId); 13097bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13107bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 13117bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 13127bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void setClient(IPrintSpoolerClient client) { 13137bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Message message = mHandlerCaller.obtainMessageO( 13147bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav HandlerCallerCallback.MSG_SET_CLIENT, client); 13157bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav mHandlerCaller.executeOrSendMessage(message); 13167bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13177bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 13187bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 13197bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void removeObsoletePrintJobs() { 13207bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintSpoolerService.this.removeObsoletePrintJobs(); 13217bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13227bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 13237bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 13247bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 13257bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintSpoolerService.this.dump(fd, writer, args); 13267bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13277bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 13287bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @Override 13297bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) { 13307bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintSpoolerService.this.setPrintJobCancelling(printJobId, cancelling); 13317bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13327bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 13337bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public PrintSpoolerService getService() { 13347bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav return PrintSpoolerService.this; 13357bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13367bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 13374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov} 1338