1a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/* 2a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Copyright (C) 2013 The Android Open Source Project 3a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * 4a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 5a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * you may not use this file except in compliance with the License. 6a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * You may obtain a copy of the License at 7a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * 8a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 9a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * 10a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software 11a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 12a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * See the License for the specific language governing permissions and 14a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * limitations under the License. 15a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */ 16a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 17a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovpackage com.android.server.print; 18a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 19a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ComponentName; 20a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Context; 21a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Intent; 22a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ServiceConnection; 23a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.Binder; 24f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganovimport android.os.Build; 25a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.IBinder; 26a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.ParcelFileDescriptor; 27a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.RemoteException; 28a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.SystemClock; 29a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.UserHandle; 30a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpooler; 31a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerCallbacks; 32a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerClient; 332fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId; 34a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.PrintJobInfo; 35a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.Slog; 36a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.TimedRemoteCaller; 37a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 38b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor; 39b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter; 40a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.lang.ref.WeakReference; 41a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.List; 42a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.concurrent.TimeoutException; 43a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 442fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport libcore.io.IoUtils; 452fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 46a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/** 47a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * This represents the remote print spooler as a local object to the 48a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * PrintManagerService. It is responsible to connecting to the remote 49a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * spooler if needed, to make the timed remote calls, to handle 50a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * remote exceptions, and to bind/unbind to the remote instance as 51a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * needed. 52a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */ 53a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovfinal class RemotePrintSpooler { 54a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 55a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final String LOG_TAG = "RemotePrintSpooler"; 56a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 57c6066799ad130140159230d14451b429eb828755Svetoslav private static final boolean DEBUG = false; 58a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 59f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov private static final long BIND_SPOOLER_SERVICE_TIMEOUT = 60f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov ("eng".equals(Build.TYPE)) ? 120000 : 10000; 61a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 62a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Object mLock = new Object(); 63a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 64a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller(); 65a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 66a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller(); 67a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 68a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller(); 69a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 70a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SetPrintJobTagCaller mSetPrintJobTagCaller = new SetPrintJobTagCaller(); 71a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 72a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final ServiceConnection mServiceConnection = new MyServiceConnection(); 73a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 74a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Context mContext; 75a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 76a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final UserHandle mUserHandle; 77a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 78a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final PrintSpoolerClient mClient; 79a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 80a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Intent mIntent; 81a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 82a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final PrintSpoolerCallbacks mCallbacks; 83a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 84a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private IPrintSpooler mRemoteInstance; 85a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 86a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean mDestroyed; 87a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 8885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov private boolean mCanUnbind; 8985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 90a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static interface PrintSpoolerCallbacks { 91a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob); 92a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService); 93dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob); 94a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 95a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 96a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public RemotePrintSpooler(Context context, int userId, 97a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov PrintSpoolerCallbacks callbacks) { 98a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mContext = context; 99a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mUserHandle = new UserHandle(userId); 100a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallbacks = callbacks; 101a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mClient = new PrintSpoolerClient(this); 102a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mIntent = new Intent(); 103a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mIntent.setComponent(new ComponentName("com.android.printspooler", 104a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav "com.android.printspooler.model.PrintSpoolerService")); 105a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 106a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 107a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state, 108a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov int appId) { 109a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 110a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 111a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 11285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 113a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 114a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 115a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(), 116a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov componentName, state, appId); 117a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 118a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print jobs.", re); 119a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 120a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print jobs.", te); 12185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 122835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 123835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); 124835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 12585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 12685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 12785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 12885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 129a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 130a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return null; 131a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 132a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 1337bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public final void createPrintJob(PrintJobInfo printJob) { 134a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 135a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 136a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 13785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 138a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 139a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 1407bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav getRemoteInstanceLazy().createPrintJob(printJob); 141a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 142a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error creating print job.", re); 143a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 144a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error creating print job.", te); 14585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 146835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 147835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); 148835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 14985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 15085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 15185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 15285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 153a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 154a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 155a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 1562fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) { 157a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 158a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 159a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 16085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 161a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 162a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 163a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov getRemoteInstanceLazy().writePrintJobData(fd, printJobId); 164a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 165a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error writing print job data.", re); 166a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 167a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error writing print job data.", te); 168a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 169835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 170835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); 171835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 172a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // We passed the file descriptor across and now the other 173a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // side is responsible to close it, so close the local copy. 174a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov IoUtils.closeQuietly(fd); 17585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 17685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 17785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 17885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 179a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 180a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 181a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 1822fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) { 183a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 184a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 185a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 18685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 187a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 188a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 189a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(), 190a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov printJobId, appId); 191a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 192a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print job info.", re); 193a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 194a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print job info.", te); 19585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 196835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 197835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()"); 198835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 19985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 20085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 20185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 20285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 203a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 204a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return null; 205a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 206a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2072fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final boolean setPrintJobState(PrintJobId printJobId, int state, String error) { 208a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 209a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 210a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 21185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 212a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 213a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 214a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(), 2158c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov printJobId, state, error); 216a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 217a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job state.", re); 218a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 219a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job state.", te); 22085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 221835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 222835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); 223835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 22485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 22585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 22685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 22785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 228a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 229a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 230a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 231a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2322fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final boolean setPrintJobTag(PrintJobId printJobId, String tag) { 233a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 234a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 235a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 23685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 237a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 238a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 239a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(), 240a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov printJobId, tag); 241a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 242a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job tag.", re); 243a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 244a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job tag.", te); 24585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 246835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 247835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); 248835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 24985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 25085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 25185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 25285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 253a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 254a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 255a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 256a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 257a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov public final void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) { 258a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov throwIfCalledOnMainThread(); 259a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 260a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov throwIfDestroyedLocked(); 261a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mCanUnbind = false; 262a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 263a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov try { 264a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov getRemoteInstanceLazy().setPrintJobCancelling(printJobId, 265a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov cancelling); 266a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } catch (RemoteException re) { 267a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job cancelling.", re); 268a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } catch (TimeoutException te) { 269a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job cancelling.", te); 270a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } finally { 271a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (DEBUG) { 272a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 273a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov + "] setPrintJobCancelling()"); 274a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 275a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 276a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mCanUnbind = true; 277a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mLock.notifyAll(); 278a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 279a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 280a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 281a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 2822fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final void removeObsoletePrintJobs() { 2832fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav throwIfCalledOnMainThread(); 2842fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 2852fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav throwIfDestroyedLocked(); 2862fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mCanUnbind = false; 2872fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2882fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav try { 2892fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav getRemoteInstanceLazy().removeObsoletePrintJobs(); 2902fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } catch (RemoteException re) { 2912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re); 2922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } catch (TimeoutException te) { 2932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te); 2942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } finally { 2952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (DEBUG) { 2962fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 2972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav + "] removeObsoletePrintJobs()"); 2982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2992fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 3002fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mCanUnbind = true; 3012fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mLock.notifyAll(); 3022fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 3032fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 3042fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 3052fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 306a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public final void destroy() { 307a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 308a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (DEBUG) { 309a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] destroy()"); 310a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 311a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 312a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 313a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov unbindLocked(); 314a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDestroyed = true; 31585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 316a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 317a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 318a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 319b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov public void dump(FileDescriptor fd, PrintWriter pw, String prefix) { 320b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov synchronized (mLock) { 321b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("destroyed=") 322b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(String.valueOf(mDestroyed)).println(); 323b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("bound=") 324b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append((mRemoteInstance != null) ? "true" : "false").println(); 325dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 326dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.flush(); 327dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 328dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov try { 329dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov getRemoteInstanceLazy().asBinder().dump(fd, new String[]{prefix}); 330dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } catch (TimeoutException te) { 331dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov /* ignore */ 332dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } catch (RemoteException re) { 333dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov /* ignore */ 334b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 335b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 336b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 337b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 338a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void onAllPrintJobsHandled() { 339a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 340a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 341a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov unbindLocked(); 342a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 343a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 344a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 345dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private void onPrintJobStateChanged(PrintJobInfo printJob) { 346dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mCallbacks.onPrintJobStateChanged(printJob); 347704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 348704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 349a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException { 350a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 351a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mRemoteInstance != null) { 352a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mRemoteInstance; 353a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 354a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov bindLocked(); 355a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mRemoteInstance; 356a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 357a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 358a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 359a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void bindLocked() throws TimeoutException { 3602fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (mRemoteInstance != null) { 3612fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 3622fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 363a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (DEBUG) { 364a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()"); 365a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 366a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 367a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mContext.bindServiceAsUser(mIntent, mServiceConnection, 368597945fd3a6b52ac70bb9afc5ec8c59039fffd77Svetoslav Context.BIND_AUTO_CREATE, mUserHandle); 369a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 370a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long startMillis = SystemClock.uptimeMillis(); 371a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov while (true) { 372a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mRemoteInstance != null) { 373a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov break; 374a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 375a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; 376a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; 377a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (remainingMillis <= 0) { 378a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new TimeoutException("Cannot get spooler!"); 379a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 380a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 381a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock.wait(remainingMillis); 382a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (InterruptedException ie) { 383a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* ignore */ 384a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 385a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 38685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 38785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 38885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 389a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 390a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 391a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void unbindLocked() { 3922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (mRemoteInstance == null) { 3932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 3942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 39585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov while (true) { 39685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov if (mCanUnbind) { 39785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov if (DEBUG) { 39885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] unbindLocked()"); 39985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 40085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov clearClientLocked(); 40185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mRemoteInstance = null; 40285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mContext.unbindService(mServiceConnection); 40385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov return; 40485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 40585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov try { 40685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.wait(); 40785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } catch (InterruptedException ie) { 40885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov /* ignore */ 40985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 410a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 41185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 412a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 413a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 414a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void setClientLocked() { 415a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 416a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance.setClient(mClient); 417a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 418a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.d(LOG_TAG, "Error setting print spooler client", re); 419a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 420a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 421a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 422a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void clearClientLocked() { 423a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 424a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance.setClient(null); 425a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 426a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.d(LOG_TAG, "Error clearing print spooler client", re); 427a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 428a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 429a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 430a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 431a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfDestroyedLocked() { 432a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mDestroyed) { 433a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new IllegalStateException("Cannot interact with a destroyed instance."); 434a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 435a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 436a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 437a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfCalledOnMainThread() { 438a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (Thread.currentThread() == mContext.getMainLooper().getThread()) { 439a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new RuntimeException("Cannot invoke on the main thread"); 440a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 441a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 442a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 443a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final class MyServiceConnection implements ServiceConnection { 444a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 445a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onServiceConnected(ComponentName name, IBinder service) { 446a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 447a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance = IPrintSpooler.Stub.asInterface(service); 448a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov setClientLocked(); 449a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock.notifyAll(); 450a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 451a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 452a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 453a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 454a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onServiceDisconnected(ComponentName name) { 455a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 456a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov clearClientLocked(); 457a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance = null; 458a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 459a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 460a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 461a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 462a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class GetPrintJobInfosCaller 463a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov extends TimedRemoteCaller<List<PrintJobInfo>> { 464a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 465a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 466a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public GetPrintJobInfosCaller() { 467a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 468a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 469a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 470a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobs, int sequence) { 471a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(printJobs, sequence); 472a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 473a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 474a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 475a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 476a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public List<PrintJobInfo> getPrintJobInfos(IPrintSpooler target, 477a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ComponentName componentName, int state, int appId) 478a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throws RemoteException, TimeoutException { 479a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 480a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.getPrintJobInfos(mCallback, componentName, state, appId, sequence); 481a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 482a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 483a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 484a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 485a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> { 486a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 487a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 488a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public GetPrintJobInfoCaller() { 489a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 490a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 491a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 492a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) { 493a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(printJob, sequence); 494a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 495a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 496a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 497a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 4982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public PrintJobInfo getPrintJobInfo(IPrintSpooler target, PrintJobId printJobId, 499a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov int appId) throws RemoteException, TimeoutException { 500a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 501a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.getPrintJobInfo(printJobId, mCallback, appId, sequence); 502a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 503a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 504a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 505a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 506a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class SetPrintJobStateCaller extends TimedRemoteCaller<Boolean> { 507a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 508a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 509a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public SetPrintJobStateCaller() { 510a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 511a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 512a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 513a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobStateResult(boolean success, int sequence) { 514a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(success, sequence); 515a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 516a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 517a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 518a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 5192fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobState(IPrintSpooler target, PrintJobId printJobId, 520269403b032f965ff3847eb982c2f697229dc5a92Svetoslav int status, String error) throws RemoteException, TimeoutException { 521a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 5228c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov target.setPrintJobState(printJobId, status, error, mCallback, sequence); 523a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 524a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 525a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 526a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 527a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class SetPrintJobTagCaller extends TimedRemoteCaller<Boolean> { 528a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 529a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 530a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public SetPrintJobTagCaller() { 531a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 532a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 533a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 534a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobTagResult(boolean success, int sequence) { 535a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(success, sequence); 536a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 537a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 538a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 539a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 5402fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobTag(IPrintSpooler target, PrintJobId printJobId, 541a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov String tag) throws RemoteException, TimeoutException { 542a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 543a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.setPrintJobTag(printJobId, tag, mCallback, sequence); 544a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 545a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 546a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 547a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 548a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static abstract class BasePrintSpoolerServiceCallbacks 549a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov extends IPrintSpoolerCallbacks.Stub { 550a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 551a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobIds, int sequence) { 552a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 553a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 554a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 555a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 556a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) { 557a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 558a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 559a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 560a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 561a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onCancelPrintJobResult(boolean canceled, int sequence) { 562a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 563a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 564a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 565a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 566a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobStateResult(boolean success, int sequece) { 567a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 568a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 569a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 570a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 571a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobTagResult(boolean success, int sequence) { 572a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 573a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 574a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 575a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 576a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class PrintSpoolerClient extends IPrintSpoolerClient.Stub { 577a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 578a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final WeakReference<RemotePrintSpooler> mWeakSpooler; 579a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 580a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public PrintSpoolerClient(RemotePrintSpooler spooler) { 581a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mWeakSpooler = new WeakReference<RemotePrintSpooler>(spooler); 582a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 583a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 584a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 585a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob) { 586a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 587a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 588a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 589a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 590a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.mCallbacks.onPrintJobQueued(printJob); 591a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 592a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 593a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 594a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 595a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 596a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 597a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 598a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService) { 599a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 600a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 601a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 602a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 603a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.mCallbacks.onAllPrintJobsForServiceHandled(printService); 604a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 605a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 606a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 607a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 608a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 609a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 610a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 611a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsHandled() { 612a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 613a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 614a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 615a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 616a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.onAllPrintJobsHandled(); 617a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 618a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 619a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 620a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 621a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 622704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 623704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 624dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob) { 625704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 626704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (spooler != null) { 627704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final long identity = Binder.clearCallingIdentity(); 628704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 629dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov spooler.onPrintJobStateChanged(printJob); 630704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } finally { 631704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Binder.restoreCallingIdentity(identity); 632704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 633704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 634704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 635a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 636a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov} 637