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 19b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmannimport android.annotation.FloatRange; 20b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmannimport android.annotation.NonNull; 21b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmannimport android.annotation.Nullable; 22d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmannimport android.annotation.StringRes; 23a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ComponentName; 24a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Context; 25a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Intent; 26a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ServiceConnection; 27bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.graphics.drawable.Icon; 28a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.Binder; 29f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganovimport android.os.Build; 30a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.IBinder; 31a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.ParcelFileDescriptor; 32a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.RemoteException; 33a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.SystemClock; 34a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.UserHandle; 35a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpooler; 36a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerCallbacks; 37a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerClient; 382fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId; 39a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.PrintJobInfo; 4066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.print.PrintManager; 41bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.print.PrinterId; 428141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmannimport android.printservice.PrintService; 43a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.Slog; 44a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.TimedRemoteCaller; 45a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 468141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmannimport libcore.io.IoUtils; 478141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann 48b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor; 49b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter; 50a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.lang.ref.WeakReference; 51a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.List; 52a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.concurrent.TimeoutException; 53a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 54a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/** 55a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * This represents the remote print spooler as a local object to the 56a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * PrintManagerService. It is responsible to connecting to the remote 57a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * spooler if needed, to make the timed remote calls, to handle 58a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * remote exceptions, and to bind/unbind to the remote instance as 59a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * needed. 601d6e7cc536cb7f49b318f630ad8f2eb348786716Philip P. Moltmann * 611d6e7cc536cb7f49b318f630ad8f2eb348786716Philip P. Moltmann * The calls might be blocking and need the main thread of to be unblocked to finish. Hence do not 621d6e7cc536cb7f49b318f630ad8f2eb348786716Philip P. Moltmann * call this while holding any monitors that might need to be acquired the main thread. 63a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */ 64a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovfinal class RemotePrintSpooler { 65a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 66a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final String LOG_TAG = "RemotePrintSpooler"; 67a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 68c6066799ad130140159230d14451b429eb828755Svetoslav private static final boolean DEBUG = false; 69a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 70f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov private static final long BIND_SPOOLER_SERVICE_TIMEOUT = 71f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov ("eng".equals(Build.TYPE)) ? 120000 : 10000; 72a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 73a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Object mLock = new Object(); 74a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 75a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller(); 76a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 77a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller(); 78a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 79a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller(); 80a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 81a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SetPrintJobTagCaller mSetPrintJobTagCaller = new SetPrintJobTagCaller(); 82a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 83bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final OnCustomPrinterIconLoadedCaller mCustomPrinterIconLoadedCaller = 84bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann new OnCustomPrinterIconLoadedCaller(); 85bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 86bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final ClearCustomPrinterIconCacheCaller mClearCustomPrinterIconCache = 87bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann new ClearCustomPrinterIconCacheCaller(); 88bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 89bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final GetCustomPrinterIconCaller mGetCustomPrinterIconCaller = 90bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann new GetCustomPrinterIconCaller(); 91bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 92a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final ServiceConnection mServiceConnection = new MyServiceConnection(); 93a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 94a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Context mContext; 95a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 96a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final UserHandle mUserHandle; 97a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 98a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final PrintSpoolerClient mClient; 99a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 100a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Intent mIntent; 101a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 102a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final PrintSpoolerCallbacks mCallbacks; 103a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 104e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann private boolean mIsLowPriority; 105e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 106a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private IPrintSpooler mRemoteInstance; 107a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 108a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean mDestroyed; 109a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 11085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov private boolean mCanUnbind; 11185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 112a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static interface PrintSpoolerCallbacks { 113a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob); 114a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService); 115dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob); 116a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 117a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 118e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann public RemotePrintSpooler(Context context, int userId, boolean lowPriority, 119a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov PrintSpoolerCallbacks callbacks) { 120a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mContext = context; 121a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mUserHandle = new UserHandle(userId); 122a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallbacks = callbacks; 123e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mIsLowPriority = lowPriority; 124a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mClient = new PrintSpoolerClient(this); 125a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mIntent = new Intent(); 12666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann mIntent.setComponent(new ComponentName(PrintManager.PRINT_SPOOLER_PACKAGE_NAME, 12766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann PrintManager.PRINT_SPOOLER_PACKAGE_NAME + ".model.PrintSpoolerService")); 128a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 129a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 130e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann public void increasePriority() { 131e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann if (mIsLowPriority) { 132e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mIsLowPriority = false; 133e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 134e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann synchronized (mLock) { 135e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann throwIfDestroyedLocked(); 136e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 137e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann while (!mCanUnbind) { 138e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann try { 139e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mLock.wait(); 140e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } catch (InterruptedException e) { 141e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann Slog.e(LOG_TAG, "Interrupted while waiting for operation to complete"); 142e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 143e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 144e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 145e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann if (DEBUG) { 146e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann Slog.i(LOG_TAG, "Unbinding as previous binding was low priority"); 147e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 148e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 149e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann unbindLocked(); 150e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 151e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 152e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 153e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 154a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state, 155a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov int appId) { 156a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 157a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 158a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 15985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 160a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 161a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 162a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(), 163a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov componentName, state, appId); 164a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 165a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print jobs.", re); 166a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 167a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print jobs.", te); 16885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 169835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 170835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); 171835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 17285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 17385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 17485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 17585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 176a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 177a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return null; 178a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 179a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 1807bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public final void createPrintJob(PrintJobInfo printJob) { 181a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 182a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 183a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 18485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 185a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 186a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 1877bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav getRemoteInstanceLazy().createPrintJob(printJob); 188a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 189a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error creating print job.", re); 190a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 191a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error creating print job.", te); 19285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 193835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 194835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); 195835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 19685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 19785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 19885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 19985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 200a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 201a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 202a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2032fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) { 204a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 205a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 206a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 20785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 208a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 209a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 210a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov getRemoteInstanceLazy().writePrintJobData(fd, printJobId); 211a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 212a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error writing print job data.", re); 213a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 214a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error writing print job data.", te); 215a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 216835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 217835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); 218835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 219a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // We passed the file descriptor across and now the other 220a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // side is responsible to close it, so close the local copy. 221a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov IoUtils.closeQuietly(fd); 22285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 22385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 22485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 22585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 226a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 227a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 228a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2292fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) { 230a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 231a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 232a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 23385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 234a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 235a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 236a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(), 237a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov printJobId, appId); 238a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 239a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print job info.", re); 240a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 241a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error getting print job info.", te); 24285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 243835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 244835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()"); 245835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 24685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 24785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 24885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 24985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 250a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 251a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return null; 252a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 253a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2542fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final boolean setPrintJobState(PrintJobId printJobId, int state, String error) { 255a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 256a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 257a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 25885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 259a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 260a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 261a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(), 2628c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov printJobId, state, error); 263a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 264a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job state.", re); 265a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 266a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job state.", te); 26785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 268835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 269835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); 270835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 27185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 27285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 27385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 27485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 275a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 276a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 277a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 278a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 279b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann /** 280b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * Set progress of a print job. 281b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * 282b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param printJobId The print job to update 283b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param progress The new progress 284b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann */ 285b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann public final void setProgress(@NonNull PrintJobId printJobId, 286b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann @FloatRange(from=0.0, to=1.0) float progress) { 287b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfCalledOnMainThread(); 288b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 289b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfDestroyedLocked(); 290b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = false; 291b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 292b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann try { 293b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann getRemoteInstanceLazy().setProgress(printJobId, progress); 294b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 295b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.e(LOG_TAG, "Error setting progress.", re); 296b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } finally { 297b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann if (DEBUG) { 298b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setProgress()"); 299b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 300b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 301b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = true; 302b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mLock.notifyAll(); 303b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 304b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 305b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 306b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann 307b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann /** 308b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * Set status of a print job. 309b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * 310b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param printJobId The print job to update 311b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param status The new status 312b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann */ 313b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann public final void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) { 314b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfCalledOnMainThread(); 315b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 316b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfDestroyedLocked(); 317b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = false; 318b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 319b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann try { 320b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann getRemoteInstanceLazy().setStatus(printJobId, status); 321b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 322b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.e(LOG_TAG, "Error setting status.", re); 323b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } finally { 324b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann if (DEBUG) { 325b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); 326d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 327d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann synchronized (mLock) { 328d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann mCanUnbind = true; 329d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann mLock.notifyAll(); 330d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 331d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 332d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 333d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann 334d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann /** 335d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * Set status of a print job. 336d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * 337d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * @param printJobId The print job to update 338d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * @param status The new status as a string resource 339d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * @param appPackageName The app package name the string res belongs to 340d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann */ 341d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann public final void setStatus(@NonNull PrintJobId printJobId, @StringRes int status, 342d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann @NonNull CharSequence appPackageName) { 343d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann throwIfCalledOnMainThread(); 344d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann synchronized (mLock) { 345d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann throwIfDestroyedLocked(); 346d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann mCanUnbind = false; 347d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 348d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann try { 349d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann getRemoteInstanceLazy().setStatusRes(printJobId, status, appPackageName); 350d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 351d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann Slog.e(LOG_TAG, "Error setting status.", re); 352d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } finally { 353d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann if (DEBUG) { 354d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); 355b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 356b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 357b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = true; 358b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mLock.notifyAll(); 359b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 360b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 361b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 362b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann 363bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /** 364bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * Handle that a custom icon for a printer was loaded. 365bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * 366bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @param printerId the id of the printer the icon belongs to 367bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @param icon the icon that was loaded 368bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon() 369bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann */ 370bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public final void onCustomPrinterIconLoaded(@NonNull PrinterId printerId, 371bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Nullable Icon icon) { 372bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfCalledOnMainThread(); 373bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 374bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfDestroyedLocked(); 375bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = false; 376bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 377bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann try { 378bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCustomPrinterIconLoadedCaller.onCustomPrinterIconLoaded(getRemoteInstanceLazy(), 379bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann printerId, icon); 380bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 381bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.e(LOG_TAG, "Error loading new custom printer icon.", re); 382bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } finally { 383bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann if (DEBUG) { 384bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.i(LOG_TAG, 385bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann "[user: " + mUserHandle.getIdentifier() + "] onCustomPrinterIconLoaded()"); 386bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 387bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 388bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = true; 389bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mLock.notifyAll(); 390bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 391bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 392bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 393bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 394bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /** 395bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * Get the custom icon for a printer. If the icon is not cached, the icon is 396bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * requested asynchronously. Once it is available the printer is updated. 397bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * 398bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @param printerId the id of the printer the icon should be loaded for 399bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @return the custom icon to be used for the printer or null if the icon is 400bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * not yet available 401bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon() 402bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann */ 403bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public final @Nullable Icon getCustomPrinterIcon(@NonNull PrinterId printerId) { 404bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfCalledOnMainThread(); 405bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 406bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfDestroyedLocked(); 407bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = false; 408bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 409bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann try { 410bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return mGetCustomPrinterIconCaller.getCustomPrinterIcon(getRemoteInstanceLazy(), 411bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann printerId); 412bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 413bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.e(LOG_TAG, "Error getting custom printer icon.", re); 414bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return null; 415bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } finally { 416bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann if (DEBUG) { 417bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.i(LOG_TAG, 418bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann "[user: " + mUserHandle.getIdentifier() + "] getCustomPrinterIcon()"); 419bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 420bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 421bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = true; 422bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mLock.notifyAll(); 423bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 424bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 425bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 426bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 427bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /** 428bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * Clear the custom printer icon cache 429bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann */ 430bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void clearCustomPrinterIconCache() { 431bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfCalledOnMainThread(); 432bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 433bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfDestroyedLocked(); 434bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = false; 435bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 436bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann try { 437bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mClearCustomPrinterIconCache.clearCustomPrinterIconCache(getRemoteInstanceLazy()); 438bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 439bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", re); 440bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } finally { 441bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann if (DEBUG) { 442bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.i(LOG_TAG, 443bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann "[user: " + mUserHandle.getIdentifier() 444bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann + "] clearCustomPrinterIconCache()"); 445bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 446bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 447bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = true; 448bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mLock.notifyAll(); 449bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 450bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 451bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 452bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 4532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final boolean setPrintJobTag(PrintJobId printJobId, String tag) { 454a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 455a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 456a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 45785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 458a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 459a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 460a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(), 461a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov printJobId, tag); 462a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 463a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job tag.", re); 464a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (TimeoutException te) { 465a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job tag.", te); 46685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 467835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 468835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); 469835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 47085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 47185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 47285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 47385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 474a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 475a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 476a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 477a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 478a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov public final void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) { 479a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov throwIfCalledOnMainThread(); 480a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 481a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov throwIfDestroyedLocked(); 482a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mCanUnbind = false; 483a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 484a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov try { 485a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov getRemoteInstanceLazy().setPrintJobCancelling(printJobId, 486a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov cancelling); 487a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } catch (RemoteException re) { 488a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job cancelling.", re); 489a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } catch (TimeoutException te) { 490a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.e(LOG_TAG, "Error setting print job cancelling.", te); 491a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } finally { 492a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (DEBUG) { 493a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 494a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov + "] setPrintJobCancelling()"); 495a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 496a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 497a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mCanUnbind = true; 498a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mLock.notifyAll(); 499853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 500853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 501853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 502853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann 503853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann /** 5048141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann * Remove all approved {@link PrintService print services} that are not in the given set. 505853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann * 5068141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann * @param servicesToKeep The {@link ComponentName names } of the services to keep 507853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann */ 5088141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann public final void pruneApprovedPrintServices(List<ComponentName> servicesToKeep) { 509853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann throwIfCalledOnMainThread(); 510853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann synchronized (mLock) { 511853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann throwIfDestroyedLocked(); 512853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann mCanUnbind = false; 513853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 514853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann try { 5158141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann getRemoteInstanceLazy().pruneApprovedPrintServices(servicesToKeep); 5168141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann } catch (RemoteException|TimeoutException re) { 5178141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann Slog.e(LOG_TAG, "Error pruning approved print services.", re); 518853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } finally { 519853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann if (DEBUG) { 520853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 5218141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann + "] pruneApprovedPrintServices()"); 522853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 523853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann synchronized (mLock) { 524853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann mCanUnbind = true; 525853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann mLock.notifyAll(); 526a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 527a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 528a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 529a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 5302fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final void removeObsoletePrintJobs() { 5312fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav throwIfCalledOnMainThread(); 5322fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 5332fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav throwIfDestroyedLocked(); 5342fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mCanUnbind = false; 5352fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5362fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav try { 5372fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav getRemoteInstanceLazy().removeObsoletePrintJobs(); 5382fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } catch (RemoteException re) { 5392fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re); 5402fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } catch (TimeoutException te) { 5412fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te); 5422fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } finally { 5432fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (DEBUG) { 5442fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 5452fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav + "] removeObsoletePrintJobs()"); 5462fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5472fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 5482fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mCanUnbind = true; 5492fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mLock.notifyAll(); 5502fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5512fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5522fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 554a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public final void destroy() { 555a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 556a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (DEBUG) { 557a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] destroy()"); 558a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 559a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 560a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 561a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov unbindLocked(); 562a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDestroyed = true; 56385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 564a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 565a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 566a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 567b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov public void dump(FileDescriptor fd, PrintWriter pw, String prefix) { 568b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov synchronized (mLock) { 569b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("destroyed=") 570b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(String.valueOf(mDestroyed)).println(); 571b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("bound=") 572b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append((mRemoteInstance != null) ? "true" : "false").println(); 573dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 574dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.flush(); 575dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 576dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov try { 577dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov getRemoteInstanceLazy().asBinder().dump(fd, new String[]{prefix}); 578dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } catch (TimeoutException te) { 579dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov /* ignore */ 580dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } catch (RemoteException re) { 581dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov /* ignore */ 582b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 583b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 584b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 585b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 586a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void onAllPrintJobsHandled() { 587a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 588a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 589a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov unbindLocked(); 590a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 591a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 592a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 593dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private void onPrintJobStateChanged(PrintJobInfo printJob) { 594dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mCallbacks.onPrintJobStateChanged(printJob); 595704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 596704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 597a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException { 598a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 599a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mRemoteInstance != null) { 600a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mRemoteInstance; 601a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 602a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov bindLocked(); 603a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mRemoteInstance; 604a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 605a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 606a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 607a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void bindLocked() throws TimeoutException { 6082fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (mRemoteInstance != null) { 6092fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 6102fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 611a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (DEBUG) { 612e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " + 613e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann (mIsLowPriority ? "low priority" : "")); 614e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 615e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 616e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann int flags; 617e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann if (mIsLowPriority) { 618e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann flags = Context.BIND_AUTO_CREATE; 619e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } else { 620e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; 621a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 622a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 623e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle); 624a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 625a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long startMillis = SystemClock.uptimeMillis(); 626a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov while (true) { 627a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mRemoteInstance != null) { 628a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov break; 629a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 630a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; 631a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; 632a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (remainingMillis <= 0) { 633a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new TimeoutException("Cannot get spooler!"); 634a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 635a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 636a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock.wait(remainingMillis); 637a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (InterruptedException ie) { 638a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* ignore */ 639a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 640a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 64185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 64285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 64385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 644a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 645a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 646a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void unbindLocked() { 6472fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (mRemoteInstance == null) { 6482fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 6492fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 65085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov while (true) { 65185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov if (mCanUnbind) { 65285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov if (DEBUG) { 65385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] unbindLocked()"); 65485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 65585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov clearClientLocked(); 65685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mRemoteInstance = null; 65785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mContext.unbindService(mServiceConnection); 65885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov return; 65985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 66085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov try { 66185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.wait(); 66285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } catch (InterruptedException ie) { 66385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov /* ignore */ 66485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 665a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 66685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 667a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 668a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 669a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void setClientLocked() { 670a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 671a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance.setClient(mClient); 672a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 673a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.d(LOG_TAG, "Error setting print spooler client", re); 674a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 675a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 676a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 677a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void clearClientLocked() { 678a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 679a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance.setClient(null); 680a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 681a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.d(LOG_TAG, "Error clearing print spooler client", re); 682a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 683a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 684a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 685a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 686a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfDestroyedLocked() { 687a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mDestroyed) { 688a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new IllegalStateException("Cannot interact with a destroyed instance."); 689a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 690a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 691a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 692a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfCalledOnMainThread() { 693a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (Thread.currentThread() == mContext.getMainLooper().getThread()) { 694a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new RuntimeException("Cannot invoke on the main thread"); 695a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 696a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 697a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 698a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final class MyServiceConnection implements ServiceConnection { 699a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 700a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onServiceConnected(ComponentName name, IBinder service) { 701a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 702a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance = IPrintSpooler.Stub.asInterface(service); 703a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov setClientLocked(); 704a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock.notifyAll(); 705a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 706a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 707a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 708a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 709a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onServiceDisconnected(ComponentName name) { 710a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 711a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov clearClientLocked(); 712a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance = null; 713a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 714a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 715a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 716a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 717a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class GetPrintJobInfosCaller 718a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov extends TimedRemoteCaller<List<PrintJobInfo>> { 719a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 720a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 721a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public GetPrintJobInfosCaller() { 722a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 723a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 724a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 725a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobs, int sequence) { 726a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(printJobs, sequence); 727a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 728a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 729a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 730a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 731a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public List<PrintJobInfo> getPrintJobInfos(IPrintSpooler target, 732a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ComponentName componentName, int state, int appId) 733a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throws RemoteException, TimeoutException { 734a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 735a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.getPrintJobInfos(mCallback, componentName, state, appId, sequence); 736a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 737a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 738a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 739a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 740a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> { 741a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 742a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 743a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public GetPrintJobInfoCaller() { 744a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 745a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 746a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 747a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) { 748a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(printJob, sequence); 749a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 750a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 751a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 752a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public PrintJobInfo getPrintJobInfo(IPrintSpooler target, PrintJobId printJobId, 754a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov int appId) throws RemoteException, TimeoutException { 755a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 756a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.getPrintJobInfo(printJobId, mCallback, appId, sequence); 757a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 758a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 759a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 760a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 761a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class SetPrintJobStateCaller extends TimedRemoteCaller<Boolean> { 762a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 763a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 764a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public SetPrintJobStateCaller() { 765a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 766a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 767a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 768a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobStateResult(boolean success, int sequence) { 769a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(success, sequence); 770a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 771a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 772a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 773a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7742fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobState(IPrintSpooler target, PrintJobId printJobId, 775269403b032f965ff3847eb982c2f697229dc5a92Svetoslav int status, String error) throws RemoteException, TimeoutException { 776a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 7778c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov target.setPrintJobState(printJobId, status, error, mCallback, sequence); 778a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 779a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 780a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 781a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 782a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class SetPrintJobTagCaller extends TimedRemoteCaller<Boolean> { 783a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 784a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 785a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public SetPrintJobTagCaller() { 786a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 787a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 788a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 789a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobTagResult(boolean success, int sequence) { 790a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(success, sequence); 791a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 792a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 793a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 794a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobTag(IPrintSpooler target, PrintJobId printJobId, 796a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov String tag) throws RemoteException, TimeoutException { 797a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 798a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.setPrintJobTag(printJobId, tag, mCallback, sequence); 799a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 800a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 801a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 802a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 803bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private static final class OnCustomPrinterIconLoadedCaller extends TimedRemoteCaller<Void> { 804bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final IPrintSpoolerCallbacks mCallback; 805bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 806bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public OnCustomPrinterIconLoadedCaller() { 807bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 808bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCallback = new BasePrintSpoolerServiceCallbacks() { 809bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 810bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onCustomPrinterIconCached(int sequence) { 811bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann onRemoteMethodResult(null, sequence); 812bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 813bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann }; 814bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 815bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 816bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public Void onCustomPrinterIconLoaded(IPrintSpooler target, PrinterId printerId, 817bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Icon icon) throws RemoteException, TimeoutException { 818bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann final int sequence = onBeforeRemoteCall(); 819bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann target.onCustomPrinterIconLoaded(printerId, icon, mCallback, sequence); 820bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return getResultTimed(sequence); 821bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 822bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 823bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 824bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private static final class ClearCustomPrinterIconCacheCaller extends TimedRemoteCaller<Void> { 825bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final IPrintSpoolerCallbacks mCallback; 826bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 827bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public ClearCustomPrinterIconCacheCaller() { 828bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 829bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCallback = new BasePrintSpoolerServiceCallbacks() { 830bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 831bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void customPrinterIconCacheCleared(int sequence) { 832bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann onRemoteMethodResult(null, sequence); 833bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 834bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann }; 835bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 836bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 837bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public Void clearCustomPrinterIconCache(IPrintSpooler target) 838bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throws RemoteException, TimeoutException { 839bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann final int sequence = onBeforeRemoteCall(); 840bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann target.clearCustomPrinterIconCache(mCallback, sequence); 841bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return getResultTimed(sequence); 842bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 843bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 844bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 845bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private static final class GetCustomPrinterIconCaller extends TimedRemoteCaller<Icon> { 846bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final IPrintSpoolerCallbacks mCallback; 847bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 848bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public GetCustomPrinterIconCaller() { 849bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 850bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCallback = new BasePrintSpoolerServiceCallbacks() { 851bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 852bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onGetCustomPrinterIconResult(Icon icon, int sequence) { 853bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann onRemoteMethodResult(icon, sequence); 854bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 855bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann }; 856bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 857bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 858bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public Icon getCustomPrinterIcon(IPrintSpooler target, PrinterId printerId) 859bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throws RemoteException, TimeoutException { 860bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann final int sequence = onBeforeRemoteCall(); 861bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann target.getCustomPrinterIcon(printerId, mCallback, sequence); 862bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return getResultTimed(sequence); 863bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 864bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 865bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 866a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static abstract class BasePrintSpoolerServiceCallbacks 867a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov extends IPrintSpoolerCallbacks.Stub { 868a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 869a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobIds, int sequence) { 870a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 871a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 872a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 873a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 874a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) { 875a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 876a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 877a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 878a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 879a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onCancelPrintJobResult(boolean canceled, int sequence) { 880a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 881a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 882a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 883a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 884a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobStateResult(boolean success, int sequece) { 885a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 886a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 887a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 888a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 889a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobTagResult(boolean success, int sequence) { 890a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 891a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 892bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 893bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 894bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onCustomPrinterIconCached(int sequence) { 895bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /* do nothing */ 896bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 897bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 898bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 899bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onGetCustomPrinterIconResult(@Nullable Icon icon, int sequence) { 900bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /* do nothing */ 901bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 902bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 903bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 904bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void customPrinterIconCacheCleared(int sequence) { 905bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /* do nothing */ 906bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 907a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 908a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 909a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class PrintSpoolerClient extends IPrintSpoolerClient.Stub { 910a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 911a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final WeakReference<RemotePrintSpooler> mWeakSpooler; 912a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 913a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public PrintSpoolerClient(RemotePrintSpooler spooler) { 914a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mWeakSpooler = new WeakReference<RemotePrintSpooler>(spooler); 915a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 916a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 917a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 918a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob) { 919a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 920a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 921a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 922a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 923a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.mCallbacks.onPrintJobQueued(printJob); 924a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 925a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 926a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 927a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 928a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 929a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 930a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 931a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService) { 932a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 933a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 934a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 935a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 936a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.mCallbacks.onAllPrintJobsForServiceHandled(printService); 937a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 938a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 939a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 940a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 941a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 942a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 943a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 944a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsHandled() { 945a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 946a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 947a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 948a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 949a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.onAllPrintJobsHandled(); 950a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 951a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 952a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 953a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 954a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 955704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 956704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 957dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob) { 958704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 959704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (spooler != null) { 960704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final long identity = Binder.clearCallingIdentity(); 961704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 962dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov spooler.onPrintJobStateChanged(printJob); 963704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } finally { 964704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Binder.restoreCallingIdentity(identity); 965704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 966704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 967704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 968a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 969a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov} 970