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 4693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmannimport com.android.internal.annotations.GuardedBy; 47850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkeyimport com.android.internal.os.TransferPipe; 48850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey 498141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmannimport libcore.io.IoUtils; 508141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann 51b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor; 52850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkeyimport java.io.IOException; 53b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter; 54a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.lang.ref.WeakReference; 55a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.List; 56a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.concurrent.TimeoutException; 57a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 58a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/** 59a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * This represents the remote print spooler as a local object to the 60a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * PrintManagerService. It is responsible to connecting to the remote 61a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * spooler if needed, to make the timed remote calls, to handle 62a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * remote exceptions, and to bind/unbind to the remote instance as 63a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * needed. 64e2ad85d230392e18013bc50f37b46268aa4245a6Philip P. Moltmann * 65e2ad85d230392e18013bc50f37b46268aa4245a6Philip P. Moltmann * The calls might be blocking and need the main thread of to be unblocked to finish. Hence do not 66e2ad85d230392e18013bc50f37b46268aa4245a6Philip P. Moltmann * call this while holding any monitors that might need to be acquired the main thread. 67a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */ 68a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovfinal class RemotePrintSpooler { 69a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 70a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final String LOG_TAG = "RemotePrintSpooler"; 71a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 72c6066799ad130140159230d14451b429eb828755Svetoslav private static final boolean DEBUG = false; 73a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 74f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov private static final long BIND_SPOOLER_SERVICE_TIMEOUT = 75f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov ("eng".equals(Build.TYPE)) ? 120000 : 10000; 76a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 77a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Object mLock = new Object(); 78a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 79a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller(); 80a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 81a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller(); 82a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 83a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller(); 84a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 85a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SetPrintJobTagCaller mSetPrintJobTagCaller = new SetPrintJobTagCaller(); 86a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 87bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final OnCustomPrinterIconLoadedCaller mCustomPrinterIconLoadedCaller = 88bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann new OnCustomPrinterIconLoadedCaller(); 89bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 90bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final ClearCustomPrinterIconCacheCaller mClearCustomPrinterIconCache = 91bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann new ClearCustomPrinterIconCacheCaller(); 92bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 93bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final GetCustomPrinterIconCaller mGetCustomPrinterIconCaller = 94bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann new GetCustomPrinterIconCaller(); 95bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 96a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final ServiceConnection mServiceConnection = new MyServiceConnection(); 97a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 98a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Context mContext; 99a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 100a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final UserHandle mUserHandle; 101a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 102a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final PrintSpoolerClient mClient; 103a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 104a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Intent mIntent; 105a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 106a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final PrintSpoolerCallbacks mCallbacks; 107a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 108e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann private boolean mIsLowPriority; 109e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 110a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private IPrintSpooler mRemoteInstance; 111a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 112a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean mDestroyed; 113a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 11485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov private boolean mCanUnbind; 11585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 11693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann /** Whether a thread is currently trying to {@link #bindLocked() bind to the print service} */ 11793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann @GuardedBy("mLock") 11893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann private boolean mIsBinding; 11993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann 120a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public static interface PrintSpoolerCallbacks { 121a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob); 122a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService); 123dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob); 124a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 125a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 126e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann public RemotePrintSpooler(Context context, int userId, boolean lowPriority, 127a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov PrintSpoolerCallbacks callbacks) { 128a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mContext = context; 129a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mUserHandle = new UserHandle(userId); 130a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallbacks = callbacks; 131e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mIsLowPriority = lowPriority; 132a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mClient = new PrintSpoolerClient(this); 133a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mIntent = new Intent(); 13466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann mIntent.setComponent(new ComponentName(PrintManager.PRINT_SPOOLER_PACKAGE_NAME, 13566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann PrintManager.PRINT_SPOOLER_PACKAGE_NAME + ".model.PrintSpoolerService")); 136a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 137a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 138e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann public void increasePriority() { 139e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann if (mIsLowPriority) { 140e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mIsLowPriority = false; 141e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 142e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann synchronized (mLock) { 143e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann throwIfDestroyedLocked(); 144e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 145e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann while (!mCanUnbind) { 146e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann try { 147e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann mLock.wait(); 148e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } catch (InterruptedException e) { 149e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann Slog.e(LOG_TAG, "Interrupted while waiting for operation to complete"); 150e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 151e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 152e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 153e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann if (DEBUG) { 154e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann Slog.i(LOG_TAG, "Unbinding as previous binding was low priority"); 155e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 156e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 157e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann unbindLocked(); 158e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 159e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 160e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 161e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 162a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state, 163a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov int appId) { 164a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 165a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 166a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 16785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 168a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 169a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 170a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(), 171a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov componentName, state, appId); 17293a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 17393a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error getting print jobs.", e); 17485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 175835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 176835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); 177835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 17885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 17985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 18085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 18185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 182a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 183a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return null; 184a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 185a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 1867bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public final void createPrintJob(PrintJobInfo printJob) { 187a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 188a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 189a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 19085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 191a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 192a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 1937bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav getRemoteInstanceLazy().createPrintJob(printJob); 19493a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 19593a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error creating print job.", e); 19685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 197835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 198835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); 199835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 20085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 20185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 20285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 20385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 204a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 205a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 206a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2072fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) { 208a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 209a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 210a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 21185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 212a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 213a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 214a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov getRemoteInstanceLazy().writePrintJobData(fd, printJobId); 21593a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 21693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error writing print job data.", e); 217a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 218835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 219835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); 220835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 221a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // We passed the file descriptor across and now the other 222a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov // side is responsible to close it, so close the local copy. 223a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov IoUtils.closeQuietly(fd); 22485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 22585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 22685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 22785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 228a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 229a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 230a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 2312fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) { 232a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 233a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 234a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 23585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 236a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 237a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 238a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(), 239a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov printJobId, appId); 24093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 24193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error getting print job info.", e); 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); 26393a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 26493a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error setting print job state.", e); 26585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 266835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 267835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); 268835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 26985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 27085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 27185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 27285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 273a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 274a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 275a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 276a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 277b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann /** 278b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * Set progress of a print job. 279b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * 280b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param printJobId The print job to update 281b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param progress The new progress 282b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann */ 283b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann public final void setProgress(@NonNull PrintJobId printJobId, 284b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann @FloatRange(from=0.0, to=1.0) float progress) { 285b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfCalledOnMainThread(); 286b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 287b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfDestroyedLocked(); 288b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = false; 289b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 290b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann try { 291b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann getRemoteInstanceLazy().setProgress(printJobId, progress); 29293a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException re) { 293b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.e(LOG_TAG, "Error setting progress.", re); 294b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } finally { 295b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann if (DEBUG) { 296b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setProgress()"); 297b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 298b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 299b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = true; 300b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mLock.notifyAll(); 301b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 302b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 303b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 304b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann 305b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann /** 306b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * Set status of a print job. 307b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * 308b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param printJobId The print job to update 309b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann * @param status The new status 310b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann */ 311b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann public final void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) { 312b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfCalledOnMainThread(); 313b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 314b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann throwIfDestroyedLocked(); 315b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = false; 316b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 317b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann try { 318b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann getRemoteInstanceLazy().setStatus(printJobId, status); 31993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 32093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error setting status.", e); 321b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } finally { 322b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann if (DEBUG) { 323b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); 324d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 325d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann synchronized (mLock) { 326d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann mCanUnbind = true; 327d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann mLock.notifyAll(); 328d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 329d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 330d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 331d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann 332d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann /** 333d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * Set status of a print job. 334d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * 335d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * @param printJobId The print job to update 336d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * @param status The new status as a string resource 337d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann * @param appPackageName The app package name the string res belongs to 338d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann */ 339d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann public final void setStatus(@NonNull PrintJobId printJobId, @StringRes int status, 340d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann @NonNull CharSequence appPackageName) { 341d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann throwIfCalledOnMainThread(); 342d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann synchronized (mLock) { 343d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann throwIfDestroyedLocked(); 344d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann mCanUnbind = false; 345d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } 346d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann try { 347d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann getRemoteInstanceLazy().setStatusRes(printJobId, status, appPackageName); 34893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 34993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error setting status.", e); 350d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann } finally { 351d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann if (DEBUG) { 352d74d1e549168ba521e8009961b76e8718be37aa1Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); 353b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 354b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann synchronized (mLock) { 355b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mCanUnbind = true; 356b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann mLock.notifyAll(); 357b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 358b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 359b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann } 360b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann 361bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /** 362bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * Handle that a custom icon for a printer was loaded. 363bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * 364bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @param printerId the id of the printer the icon belongs to 365bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @param icon the icon that was loaded 366bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon() 367bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann */ 368bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public final void onCustomPrinterIconLoaded(@NonNull PrinterId printerId, 369bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Nullable Icon icon) { 370bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfCalledOnMainThread(); 371bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 372bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfDestroyedLocked(); 373bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = false; 374bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 375bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann try { 376bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCustomPrinterIconLoadedCaller.onCustomPrinterIconLoaded(getRemoteInstanceLazy(), 377bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann printerId, icon); 37893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException re) { 379bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.e(LOG_TAG, "Error loading new custom printer icon.", re); 380bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } finally { 381bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann if (DEBUG) { 382bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.i(LOG_TAG, 383bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann "[user: " + mUserHandle.getIdentifier() + "] onCustomPrinterIconLoaded()"); 384bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 385bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 386bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = true; 387bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mLock.notifyAll(); 388bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 389bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 390bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 391bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 392bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /** 393bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * Get the custom icon for a printer. If the icon is not cached, the icon is 394bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * requested asynchronously. Once it is available the printer is updated. 395bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * 396bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @param printerId the id of the printer the icon should be loaded for 397bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @return the custom icon to be used for the printer or null if the icon is 398bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * not yet available 399bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon() 400bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann */ 401bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public final @Nullable Icon getCustomPrinterIcon(@NonNull PrinterId printerId) { 402bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfCalledOnMainThread(); 403bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 404bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfDestroyedLocked(); 405bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = false; 406bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 407bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann try { 408bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return mGetCustomPrinterIconCaller.getCustomPrinterIcon(getRemoteInstanceLazy(), 409bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann printerId); 41093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 41193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error getting custom printer icon.", e); 412bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return null; 413bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } finally { 414bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann if (DEBUG) { 415bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.i(LOG_TAG, 416bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann "[user: " + mUserHandle.getIdentifier() + "] getCustomPrinterIcon()"); 417bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 418bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 419bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = true; 420bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mLock.notifyAll(); 421bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 422bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 423bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 424bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 425bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /** 426bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann * Clear the custom printer icon cache 427bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann */ 428bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void clearCustomPrinterIconCache() { 429bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfCalledOnMainThread(); 430bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 431bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throwIfDestroyedLocked(); 432bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = false; 433bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 434bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann try { 435bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mClearCustomPrinterIconCache.clearCustomPrinterIconCache(getRemoteInstanceLazy()); 43693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 43793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", e); 438bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } finally { 439bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann if (DEBUG) { 440bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Slog.i(LOG_TAG, 441bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann "[user: " + mUserHandle.getIdentifier() 442bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann + "] clearCustomPrinterIconCache()"); 443bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 444bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann synchronized (mLock) { 445bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCanUnbind = true; 446bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mLock.notifyAll(); 447bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 448bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 449bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 450bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 4512fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final boolean setPrintJobTag(PrintJobId printJobId, String tag) { 452a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 453a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 454a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 45585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 456a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 457a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 458a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(), 459a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov printJobId, tag); 46093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 46193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error setting print job tag.", e); 46285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } finally { 463835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov if (DEBUG) { 464835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); 465835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov } 46685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov synchronized (mLock) { 46785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = true; 46885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.notifyAll(); 46985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 470a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 471a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 472a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 473a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 474a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov public final void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) { 475a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov throwIfCalledOnMainThread(); 476a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 477a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov throwIfDestroyedLocked(); 478a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mCanUnbind = false; 479a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 480a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov try { 481a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov getRemoteInstanceLazy().setPrintJobCancelling(printJobId, 482a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov cancelling); 48393a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 48493a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error setting print job cancelling.", e); 485a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } finally { 486a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov if (DEBUG) { 487a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 488a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov + "] setPrintJobCancelling()"); 489a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 490a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov synchronized (mLock) { 491a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mCanUnbind = true; 492a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mLock.notifyAll(); 493853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 494853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 495853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 496853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann 497853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann /** 4988141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann * Remove all approved {@link PrintService print services} that are not in the given set. 499853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann * 5008141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann * @param servicesToKeep The {@link ComponentName names } of the services to keep 501853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann */ 5028141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann public final void pruneApprovedPrintServices(List<ComponentName> servicesToKeep) { 503853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann throwIfCalledOnMainThread(); 504853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann synchronized (mLock) { 505853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann throwIfDestroyedLocked(); 506853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann mCanUnbind = false; 507853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 508853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann try { 5098141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann getRemoteInstanceLazy().pruneApprovedPrintServices(servicesToKeep); 51093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException e) { 51193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann Slog.e(LOG_TAG, "Error pruning approved print services.", e); 512853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } finally { 513853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann if (DEBUG) { 514853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 5158141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann + "] pruneApprovedPrintServices()"); 516853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann } 517853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann synchronized (mLock) { 518853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann mCanUnbind = true; 519853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann mLock.notifyAll(); 520a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 521a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 522a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov } 523a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 5242fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public final void removeObsoletePrintJobs() { 5252fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav throwIfCalledOnMainThread(); 5262fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 5272fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav throwIfDestroyedLocked(); 5282fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mCanUnbind = false; 5292fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5302fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav try { 5312fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav getRemoteInstanceLazy().removeObsoletePrintJobs(); 53293a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (RemoteException | TimeoutException | InterruptedException te) { 5332fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te); 5342fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } finally { 5352fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (DEBUG) { 5362fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() 5372fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav + "] removeObsoletePrintJobs()"); 5382fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5392fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 5402fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mCanUnbind = true; 5412fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mLock.notifyAll(); 5422fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5432fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5442fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 5452fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 546a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public final void destroy() { 547a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfCalledOnMainThread(); 548a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (DEBUG) { 549a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] destroy()"); 550a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 551a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 552a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 553a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov unbindLocked(); 554a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDestroyed = true; 55585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mCanUnbind = false; 556a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 557a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 558a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 559b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov public void dump(FileDescriptor fd, PrintWriter pw, String prefix) { 560b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov synchronized (mLock) { 561b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("destroyed=") 562b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(String.valueOf(mDestroyed)).println(); 563b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("bound=") 564b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append((mRemoteInstance != null) ? "true" : "false").println(); 565dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 566dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.flush(); 567dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov try { 568850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd, 569850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey new String[] { prefix }); 57093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } catch (IOException | TimeoutException | RemoteException | InterruptedException e) { 571850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey pw.println("Failed to dump remote instance: " + e); 572b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 573b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 574b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 575b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 576a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void onAllPrintJobsHandled() { 577a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 578a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 579a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov unbindLocked(); 580a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 581a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 582a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 583dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private void onPrintJobStateChanged(PrintJobInfo printJob) { 584dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mCallbacks.onPrintJobStateChanged(printJob); 585704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 586704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 58793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException, InterruptedException { 588a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 589a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mRemoteInstance != null) { 590a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mRemoteInstance; 591a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 592a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov bindLocked(); 593a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mRemoteInstance; 594a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 595a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 596a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 59793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann private void bindLocked() throws TimeoutException, InterruptedException { 59893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann while (mIsBinding) { 59993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann mLock.wait(); 60093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } 60193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann 6022fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (mRemoteInstance != null) { 6032fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 6042fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 60593a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann 60693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann mIsBinding = true; 60793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann 608a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (DEBUG) { 609e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " + 610e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann (mIsLowPriority ? "low priority" : "")); 611e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann } 612e8ae15482eef7617494cb3187899983e27cb8a35Philip P. Moltmann 61393a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann try { 61493a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann int flags; 61593a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann if (mIsLowPriority) { 61693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann flags = Context.BIND_AUTO_CREATE; 61793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } else { 61893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; 61993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } 620a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 62193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle); 622a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 62393a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann final long startMillis = SystemClock.uptimeMillis(); 62493a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann while (true) { 62593a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann if (mRemoteInstance != null) { 62693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann break; 62793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } 62893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; 62993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; 63093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann if (remainingMillis <= 0) { 63193a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann throw new TimeoutException("Cannot get spooler!"); 63293a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } 633a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock.wait(remainingMillis); 634a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 63585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 63693a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann mCanUnbind = true; 63793a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } finally { 63893a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann mIsBinding = false; 63993a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann mLock.notifyAll(); 64093a224936945d1fd773c761279b8949d30325bacPhilip P. Moltmann } 641a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 642a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 643a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void unbindLocked() { 6442fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (mRemoteInstance == null) { 6452fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 6462fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 64785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov while (true) { 64885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov if (mCanUnbind) { 64985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov if (DEBUG) { 65085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] unbindLocked()"); 65185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 65285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov clearClientLocked(); 65385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mRemoteInstance = null; 65485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mContext.unbindService(mServiceConnection); 65585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov return; 65685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 65785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov try { 65885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov mLock.wait(); 65985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } catch (InterruptedException ie) { 66085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov /* ignore */ 66185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov } 662a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 66385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov 664a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 665a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 666a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void setClientLocked() { 667a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 668a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance.setClient(mClient); 669a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 670a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.d(LOG_TAG, "Error setting print spooler client", re); 671a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 672a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 673a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 674a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void clearClientLocked() { 675a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 676a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance.setClient(null); 677a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } catch (RemoteException re) { 678a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.d(LOG_TAG, "Error clearing print spooler client", re); 679a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 680a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 681a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 682a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 683a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfDestroyedLocked() { 684a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mDestroyed) { 685a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new IllegalStateException("Cannot interact with a destroyed instance."); 686a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 687a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 688a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 689a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfCalledOnMainThread() { 690a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (Thread.currentThread() == mContext.getMainLooper().getThread()) { 691a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new RuntimeException("Cannot invoke on the main thread"); 692a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 693a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 694a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 695a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final class MyServiceConnection implements ServiceConnection { 696a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 697a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onServiceConnected(ComponentName name, IBinder service) { 698a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 699a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance = IPrintSpooler.Stub.asInterface(service); 700a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov setClientLocked(); 701a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock.notifyAll(); 702a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 703a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 704a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 705a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 706a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onServiceDisconnected(ComponentName name) { 707a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 708a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov clearClientLocked(); 709a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mRemoteInstance = null; 710a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 711a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 712a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 713a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 714a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class GetPrintJobInfosCaller 715a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov extends TimedRemoteCaller<List<PrintJobInfo>> { 716a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 717a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 718a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public GetPrintJobInfosCaller() { 719a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 720a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 721a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 722a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobs, int sequence) { 723a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(printJobs, sequence); 724a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 725a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 726a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 727a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 728a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public List<PrintJobInfo> getPrintJobInfos(IPrintSpooler target, 729a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ComponentName componentName, int state, int appId) 730a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throws RemoteException, TimeoutException { 731a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 732a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.getPrintJobInfos(mCallback, componentName, state, appId, sequence); 733a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 734a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 735a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 736a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 737a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> { 738a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 739a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 740a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public GetPrintJobInfoCaller() { 741a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 742a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 743a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 744a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) { 745a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(printJob, sequence); 746a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 747a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 748a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 749a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7502fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public PrintJobInfo getPrintJobInfo(IPrintSpooler target, PrintJobId printJobId, 751a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov int appId) throws RemoteException, TimeoutException { 752a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 753a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.getPrintJobInfo(printJobId, mCallback, appId, sequence); 754a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 755a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 756a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 757a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 758a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class SetPrintJobStateCaller extends TimedRemoteCaller<Boolean> { 759a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 760a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 761a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public SetPrintJobStateCaller() { 762a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 763a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 764a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 765a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobStateResult(boolean success, int sequence) { 766a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(success, sequence); 767a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 768a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 769a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 770a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7712fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobState(IPrintSpooler target, PrintJobId printJobId, 772269403b032f965ff3847eb982c2f697229dc5a92Svetoslav int status, String error) throws RemoteException, TimeoutException { 773a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 7748c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov target.setPrintJobState(printJobId, status, error, mCallback, sequence); 775a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 776a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 777a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 778a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 779a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class SetPrintJobTagCaller extends TimedRemoteCaller<Boolean> { 780a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final IPrintSpoolerCallbacks mCallback; 781a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 782a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public SetPrintJobTagCaller() { 783a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 784a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mCallback = new BasePrintSpoolerServiceCallbacks() { 785a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 786a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobTagResult(boolean success, int sequence) { 787a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onRemoteMethodResult(success, sequence); 788a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 789a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov }; 790a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 791a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public boolean setPrintJobTag(IPrintSpooler target, PrintJobId printJobId, 793a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov String tag) throws RemoteException, TimeoutException { 794a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int sequence = onBeforeRemoteCall(); 795a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov target.setPrintJobTag(printJobId, tag, mCallback, sequence); 796a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return getResultTimed(sequence); 797a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 798a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 799a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 800bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private static final class OnCustomPrinterIconLoadedCaller extends TimedRemoteCaller<Void> { 801bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final IPrintSpoolerCallbacks mCallback; 802bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 803bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public OnCustomPrinterIconLoadedCaller() { 804bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 805bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCallback = new BasePrintSpoolerServiceCallbacks() { 806bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 807bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onCustomPrinterIconCached(int sequence) { 808bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann onRemoteMethodResult(null, sequence); 809bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 810bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann }; 811bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 812bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 813bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public Void onCustomPrinterIconLoaded(IPrintSpooler target, PrinterId printerId, 814bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann Icon icon) throws RemoteException, TimeoutException { 815bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann final int sequence = onBeforeRemoteCall(); 816bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann target.onCustomPrinterIconLoaded(printerId, icon, mCallback, sequence); 817bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return getResultTimed(sequence); 818bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 819bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 820bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 821bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private static final class ClearCustomPrinterIconCacheCaller extends TimedRemoteCaller<Void> { 822bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final IPrintSpoolerCallbacks mCallback; 823bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 824bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public ClearCustomPrinterIconCacheCaller() { 825bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 826bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCallback = new BasePrintSpoolerServiceCallbacks() { 827bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 828bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void customPrinterIconCacheCleared(int sequence) { 829bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann onRemoteMethodResult(null, sequence); 830bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 831bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann }; 832bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 833bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 834bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public Void clearCustomPrinterIconCache(IPrintSpooler target) 835bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throws RemoteException, TimeoutException { 836bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann final int sequence = onBeforeRemoteCall(); 837bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann target.clearCustomPrinterIconCache(mCallback, sequence); 838bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return getResultTimed(sequence); 839bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 840bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 841bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 842bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private static final class GetCustomPrinterIconCaller extends TimedRemoteCaller<Icon> { 843bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann private final IPrintSpoolerCallbacks mCallback; 844bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 845bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public GetCustomPrinterIconCaller() { 846bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); 847bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann mCallback = new BasePrintSpoolerServiceCallbacks() { 848bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 849bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onGetCustomPrinterIconResult(Icon icon, int sequence) { 850bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann onRemoteMethodResult(icon, sequence); 851bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 852bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann }; 853bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 854bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 855bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public Icon getCustomPrinterIcon(IPrintSpooler target, PrinterId printerId) 856bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann throws RemoteException, TimeoutException { 857bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann final int sequence = onBeforeRemoteCall(); 858bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann target.getCustomPrinterIcon(printerId, mCallback, sequence); 859bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann return getResultTimed(sequence); 860bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 861bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 862bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 863a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static abstract class BasePrintSpoolerServiceCallbacks 864a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov extends IPrintSpoolerCallbacks.Stub { 865a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 866a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobIds, int sequence) { 867a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 868a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 869a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 870a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 871a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) { 872a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 873a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 874a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 875a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 876a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onCancelPrintJobResult(boolean canceled, int sequence) { 877a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 878a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 879a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 880a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 881a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobStateResult(boolean success, int sequece) { 882a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 883a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 884a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 885a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 886a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onSetPrintJobTagResult(boolean success, int sequence) { 887a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov /* do nothing */ 888a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 889bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 890bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 891bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onCustomPrinterIconCached(int sequence) { 892bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /* do nothing */ 893bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 894bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 895bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 896bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void onGetCustomPrinterIconResult(@Nullable Icon icon, int sequence) { 897bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /* do nothing */ 898bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 899bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann 900bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann @Override 901bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann public void customPrinterIconCacheCleared(int sequence) { 902bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann /* do nothing */ 903bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann } 904a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 905a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 906a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final class PrintSpoolerClient extends IPrintSpoolerClient.Stub { 907a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 908a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final WeakReference<RemotePrintSpooler> mWeakSpooler; 909a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 910a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public PrintSpoolerClient(RemotePrintSpooler spooler) { 911a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mWeakSpooler = new WeakReference<RemotePrintSpooler>(spooler); 912a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 913a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 914a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 915a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob) { 916a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 917a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 918a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 919a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 920a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.mCallbacks.onPrintJobQueued(printJob); 921a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 922a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 923a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 924a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 925a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 926a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 927a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 928a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService) { 929a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 930a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 931a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 932a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 933a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.mCallbacks.onAllPrintJobsForServiceHandled(printService); 934a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 935a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 936a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 937a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 938a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 939a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 940a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 941a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsHandled() { 942a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 943a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (spooler != null) { 944a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 945a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov try { 946a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov spooler.onAllPrintJobsHandled(); 947a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } finally { 948a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Binder.restoreCallingIdentity(identity); 949a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 950a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 951a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 952704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 953704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 954dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob) { 955704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov RemotePrintSpooler spooler = mWeakSpooler.get(); 956704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (spooler != null) { 957704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final long identity = Binder.clearCallingIdentity(); 958704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 959dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov spooler.onPrintJobStateChanged(printJob); 960704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } finally { 961704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Binder.restoreCallingIdentity(identity); 962704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 963704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 964704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 965a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 966a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov} 967