RemotePrintSpooler.java revision 8141bdfa56f13c3946bed12ba7801e492ec25c11
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;
22a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ComponentName;
23a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Context;
24a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Intent;
25a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ServiceConnection;
26bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.graphics.drawable.Icon;
27a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.Binder;
28f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganovimport android.os.Build;
29a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.IBinder;
30a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.ParcelFileDescriptor;
31a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.RemoteException;
32a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.SystemClock;
33a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.os.UserHandle;
34a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpooler;
35a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerCallbacks;
36a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintSpoolerClient;
372fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId;
38a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.PrintJobInfo;
39bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.print.PrinterId;
408141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmannimport android.printservice.PrintService;
41a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.Slog;
42a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.TimedRemoteCaller;
43a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
448141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmannimport libcore.io.IoUtils;
458141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann
46b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor;
47b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter;
48a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.lang.ref.WeakReference;
49a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.List;
50a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.concurrent.TimeoutException;
51a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
52a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/**
53a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * This represents the remote print spooler as a local object to the
54a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * PrintManagerService. It is responsible to connecting to the remote
55a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * spooler if needed, to make the timed remote calls, to handle
56a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * remote exceptions, and to bind/unbind to the remote instance as
57a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * needed.
58a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */
59a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovfinal class RemotePrintSpooler {
60a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
61a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static final String LOG_TAG = "RemotePrintSpooler";
62a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
63c6066799ad130140159230d14451b429eb828755Svetoslav    private static final boolean DEBUG = false;
64a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
65f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov    private static final long BIND_SPOOLER_SERVICE_TIMEOUT =
66f983d084e7b8a6de722d9cede1c0cf73831c8e92Svet Ganov            ("eng".equals(Build.TYPE)) ? 120000 : 10000;
67a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
68a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final Object mLock = new Object();
69a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
70a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller();
71a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
72a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller();
73a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
74a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller();
75a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
76a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final SetPrintJobTagCaller mSetPrintJobTagCaller = new SetPrintJobTagCaller();
77a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
78bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    private final OnCustomPrinterIconLoadedCaller mCustomPrinterIconLoadedCaller =
79bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            new OnCustomPrinterIconLoadedCaller();
80bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
81bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    private final ClearCustomPrinterIconCacheCaller mClearCustomPrinterIconCache =
82bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            new ClearCustomPrinterIconCacheCaller();
83bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
84bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    private final GetCustomPrinterIconCaller mGetCustomPrinterIconCaller =
85bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            new GetCustomPrinterIconCaller();
86bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
87a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final ServiceConnection mServiceConnection = new MyServiceConnection();
88a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
89a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final Context mContext;
90a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
91a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final UserHandle mUserHandle;
92a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
93a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final PrintSpoolerClient mClient;
94a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
95a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final Intent mIntent;
96a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
97a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final PrintSpoolerCallbacks mCallbacks;
98a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
99a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private IPrintSpooler mRemoteInstance;
100a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
101a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private boolean mDestroyed;
102a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
10385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov    private boolean mCanUnbind;
10485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov
105a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    public static interface PrintSpoolerCallbacks {
106a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onPrintJobQueued(PrintJobInfo printJob);
107a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onAllPrintJobsForServiceHandled(ComponentName printService);
108dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov        public void onPrintJobStateChanged(PrintJobInfo printJob);
109a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
110a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
111a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    public RemotePrintSpooler(Context context, int userId,
112a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            PrintSpoolerCallbacks callbacks) {
113a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mContext = context;
114a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mUserHandle = new UserHandle(userId);
115a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mCallbacks = callbacks;
116a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mClient = new PrintSpoolerClient(this);
117a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mIntent = new Intent();
118a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mIntent.setComponent(new ComponentName("com.android.printspooler",
119a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                "com.android.printspooler.model.PrintSpoolerService"));
120a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
121a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
122a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state,
123a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            int appId) {
124a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
125a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
126a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
12785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
128a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
129a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
130a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(),
131a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    componentName, state, appId);
132a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
133a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error getting print jobs.", re);
134a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (TimeoutException te) {
135a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error getting print jobs.", te);
13685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        } finally {
137835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            if (DEBUG) {
138835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()");
139835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            }
14085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            synchronized (mLock) {
14185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mCanUnbind = true;
14285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.notifyAll();
14385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
144a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
145a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        return null;
146a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
147a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
1487bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav    public final void createPrintJob(PrintJobInfo printJob) {
149a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
150a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
151a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
15285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
153a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
154a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
1557bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav            getRemoteInstanceLazy().createPrintJob(printJob);
156a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
157a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error creating print job.", re);
158a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (TimeoutException te) {
159a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error creating print job.", te);
16085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        } finally {
161835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            if (DEBUG) {
162835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()");
163835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            }
16485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            synchronized (mLock) {
16585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mCanUnbind = true;
16685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.notifyAll();
16785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
168a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
169a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
170a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
1712fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav    public final void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
172a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
173a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
174a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
17585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
176a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
177a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
178a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            getRemoteInstanceLazy().writePrintJobData(fd, printJobId);
179a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
180a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error writing print job data.", re);
181a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (TimeoutException te) {
182a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error writing print job data.", te);
183a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } finally {
184835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            if (DEBUG) {
185835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()");
186835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            }
187a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            // We passed the file descriptor across and now the other
188a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            // side is responsible to close it, so close the local copy.
189a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            IoUtils.closeQuietly(fd);
19085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            synchronized (mLock) {
19185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mCanUnbind = true;
19285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.notifyAll();
19385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
194a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
195a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
196a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
1972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav    public final PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
198a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
199a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
200a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
20185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
202a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
203a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
204a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(),
205a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    printJobId, appId);
206a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
207a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error getting print job info.", re);
208a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (TimeoutException te) {
209a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error getting print job info.", te);
21085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        } finally {
211835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            if (DEBUG) {
212835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()");
213835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            }
21485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            synchronized (mLock) {
21585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mCanUnbind = true;
21685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.notifyAll();
21785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
218a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
219a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        return null;
220a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
221a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
2222fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav    public final boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
223a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
224a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
225a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
22685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
227a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
228a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
229a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(),
2308c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov                    printJobId, state, error);
231a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
232a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error setting print job state.", re);
233a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (TimeoutException te) {
234a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error setting print job state.", te);
23585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        } finally {
236835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            if (DEBUG) {
237835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()");
238835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            }
23985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            synchronized (mLock) {
24085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mCanUnbind = true;
24185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.notifyAll();
24285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
243a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
244a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        return false;
245a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
246a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
247b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann    /**
248b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     * Set progress of a print job.
249b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     *
250b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     * @param printJobId The print job to update
251b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     * @param progress The new progress
252b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     */
253b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann    public final void setProgress(@NonNull PrintJobId printJobId,
254b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            @FloatRange(from=0.0, to=1.0) float progress) {
255b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        throwIfCalledOnMainThread();
256b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        synchronized (mLock) {
257b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            throwIfDestroyedLocked();
258b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            mCanUnbind = false;
259b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        }
260b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        try {
261b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            getRemoteInstanceLazy().setProgress(printJobId, progress);
262b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        } catch (RemoteException|TimeoutException re) {
263b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            Slog.e(LOG_TAG, "Error setting progress.", re);
264b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        } finally {
265b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            if (DEBUG) {
266b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setProgress()");
267b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            }
268b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            synchronized (mLock) {
269b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann                mCanUnbind = true;
270b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann                mLock.notifyAll();
271b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            }
272b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        }
273b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann    }
274b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann
275b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann    /**
276b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     * Set status of a print job.
277b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     *
278b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     * @param printJobId The print job to update
279b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     * @param status The new status
280b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann     */
281b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann    public final void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
282b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        throwIfCalledOnMainThread();
283b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        synchronized (mLock) {
284b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            throwIfDestroyedLocked();
285b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            mCanUnbind = false;
286b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        }
287b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        try {
288b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            getRemoteInstanceLazy().setStatus(printJobId, status);
289b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        } catch (RemoteException|TimeoutException re) {
290b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            Slog.e(LOG_TAG, "Error setting status.", re);
291b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        } finally {
292b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            if (DEBUG) {
293b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()");
294b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            }
295b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            synchronized (mLock) {
296b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann                mCanUnbind = true;
297b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann                mLock.notifyAll();
298b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann            }
299b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann        }
300b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann    }
301b3078c235e7674fd61be75fb469105ba6174aba5Philip P. Moltmann
302bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
303bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * Handle that a custom icon for a printer was loaded.
304bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
305bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param printerId the id of the printer the icon belongs to
306bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param icon the icon that was loaded
307bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
308bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
309bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    public final void onCustomPrinterIconLoaded(@NonNull PrinterId printerId,
310bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            @Nullable Icon icon) {
311bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        throwIfCalledOnMainThread();
312bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        synchronized (mLock) {
313bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            throwIfDestroyedLocked();
314bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            mCanUnbind = false;
315bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
316bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        try {
317bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            mCustomPrinterIconLoadedCaller.onCustomPrinterIconLoaded(getRemoteInstanceLazy(),
318bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    printerId, icon);
319bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        } catch (RemoteException|TimeoutException re) {
320bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            Slog.e(LOG_TAG, "Error loading new custom printer icon.", re);
321bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        } finally {
322bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            if (DEBUG) {
323bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                Slog.i(LOG_TAG,
324bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                        "[user: " + mUserHandle.getIdentifier() + "] onCustomPrinterIconLoaded()");
325bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
326bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            synchronized (mLock) {
327bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                mCanUnbind = true;
328bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                mLock.notifyAll();
329bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
330bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
331bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
332bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
333bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
334bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * Get the custom icon for a printer. If the icon is not cached, the icon is
335bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * requested asynchronously. Once it is available the printer is updated.
336bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
337bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param printerId the id of the printer the icon should be loaded for
338bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @return the custom icon to be used for the printer or null if the icon is
339bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *         not yet available
340bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
341bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
342bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    public final @Nullable Icon getCustomPrinterIcon(@NonNull PrinterId printerId) {
343bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        throwIfCalledOnMainThread();
344bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        synchronized (mLock) {
345bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            throwIfDestroyedLocked();
346bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            mCanUnbind = false;
347bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
348bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        try {
349bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            return mGetCustomPrinterIconCaller.getCustomPrinterIcon(getRemoteInstanceLazy(),
350bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    printerId);
351bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        } catch (RemoteException|TimeoutException re) {
352bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            Slog.e(LOG_TAG, "Error getting custom printer icon.", re);
353bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            return null;
354bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        } finally {
355bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            if (DEBUG) {
356bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                Slog.i(LOG_TAG,
357bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                        "[user: " + mUserHandle.getIdentifier() + "] getCustomPrinterIcon()");
358bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
359bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            synchronized (mLock) {
360bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                mCanUnbind = true;
361bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                mLock.notifyAll();
362bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
363bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
364bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
365bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
366bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
367bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * Clear the custom printer icon cache
368bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
369bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    public void clearCustomPrinterIconCache() {
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            mClearCustomPrinterIconCache.clearCustomPrinterIconCache(getRemoteInstanceLazy());
377bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        } catch (RemoteException|TimeoutException re) {
378bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", re);
379bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        } finally {
380bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            if (DEBUG) {
381bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                Slog.i(LOG_TAG,
382bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                        "[user: " + mUserHandle.getIdentifier()
383bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                                + "] clearCustomPrinterIconCache()");
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
3922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav    public final boolean setPrintJobTag(PrintJobId printJobId, String tag) {
393a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
394a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
395a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
39685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
397a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
398a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
399a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(),
400a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    printJobId, tag);
401a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
402a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error setting print job tag.", re);
403a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (TimeoutException te) {
404a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.e(LOG_TAG, "Error setting print job tag.", te);
40585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        } finally {
406835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            if (DEBUG) {
407835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()");
408835835ee6f913408ac91678d6056896a2c5b25e3Svetoslav Ganov            }
40985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            synchronized (mLock) {
41085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mCanUnbind = true;
41185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.notifyAll();
41285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
413a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
414a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        return false;
415a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
416a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
417a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov    public final void setPrintJobCancelling(PrintJobId printJobId, boolean cancelling) {
418a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        throwIfCalledOnMainThread();
419a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        synchronized (mLock) {
420a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            throwIfDestroyedLocked();
421a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            mCanUnbind = false;
422a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        }
423a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        try {
424a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            getRemoteInstanceLazy().setPrintJobCancelling(printJobId,
425a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov                    cancelling);
426a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        } catch (RemoteException re) {
427a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            Slog.e(LOG_TAG, "Error setting print job cancelling.", re);
428a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        } catch (TimeoutException te) {
429a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            Slog.e(LOG_TAG, "Error setting print job cancelling.", te);
430a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        } finally {
431a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            if (DEBUG) {
432a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
433a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov                        + "] setPrintJobCancelling()");
434a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            }
435a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            synchronized (mLock) {
436a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov                mCanUnbind = true;
437a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov                mLock.notifyAll();
438853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann            }
439853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann        }
440853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann    }
441853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann
442853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann    /**
4438141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann     * Remove all approved {@link PrintService print services} that are not in the given set.
444853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann     *
4458141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann     * @param servicesToKeep The {@link ComponentName names } of the services to keep
446853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann     */
4478141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann    public final void pruneApprovedPrintServices(List<ComponentName> servicesToKeep) {
448853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann        throwIfCalledOnMainThread();
449853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann        synchronized (mLock) {
450853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann            throwIfDestroyedLocked();
451853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann            mCanUnbind = false;
452853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann        }
453853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann        try {
4548141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann            getRemoteInstanceLazy().pruneApprovedPrintServices(servicesToKeep);
4558141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann        } catch (RemoteException|TimeoutException re) {
4568141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann            Slog.e(LOG_TAG, "Error pruning approved print services.", re);
457853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann        } finally {
458853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann            if (DEBUG) {
459853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
4608141bdfa56f13c3946bed12ba7801e492ec25c11Philip P. Moltmann                        + "] pruneApprovedPrintServices()");
461853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann            }
462853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann            synchronized (mLock) {
463853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann                mCanUnbind = true;
464853a6f564abaf8acbd88c6704008c5d150d00471Philip P. Moltmann                mLock.notifyAll();
465a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov            }
466a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov        }
467a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov    }
468a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov
4692fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav    public final void removeObsoletePrintJobs() {
4702fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        throwIfCalledOnMainThread();
4712fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        synchronized (mLock) {
4722fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            throwIfDestroyedLocked();
4732fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            mCanUnbind = false;
4742fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        }
4752fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        try {
4762fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            getRemoteInstanceLazy().removeObsoletePrintJobs();
4772fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        } catch (RemoteException re) {
4782fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re);
4792fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        } catch (TimeoutException te) {
4802fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te);
4812fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        } finally {
4822fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            if (DEBUG) {
4832fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
4842fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                        + "] removeObsoletePrintJobs()");
4852fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
4862fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            synchronized (mLock) {
4872fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mCanUnbind = true;
4882fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mLock.notifyAll();
4892fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
4902fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        }
4912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav    }
4922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav
493a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    public final void destroy() {
494a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        throwIfCalledOnMainThread();
495a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        if (DEBUG) {
496a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] destroy()");
497a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
498a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
499a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
500a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            unbindLocked();
501a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mDestroyed = true;
50285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            mCanUnbind = false;
503a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
504a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
505a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
506b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov    public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
507b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov        synchronized (mLock) {
508b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov            pw.append(prefix).append("destroyed=")
509b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov                    .append(String.valueOf(mDestroyed)).println();
510b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov            pw.append(prefix).append("bound=")
511b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov                    .append((mRemoteInstance != null) ? "true" : "false").println();
512dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov
513dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov            pw.flush();
514dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov
515dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov            try {
516dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov                getRemoteInstanceLazy().asBinder().dump(fd, new String[]{prefix});
517dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov            } catch (TimeoutException te) {
518dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov                /* ignore */
519dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov            } catch (RemoteException re) {
520dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov                /* ignore */
521b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov            }
522b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov        }
523b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov    }
524b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov
525a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void onAllPrintJobsHandled() {
526a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
527a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throwIfDestroyedLocked();
528a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            unbindLocked();
529a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
530a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
531a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
532dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov    private void onPrintJobStateChanged(PrintJobInfo printJob) {
533dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov        mCallbacks.onPrintJobStateChanged(printJob);
534704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov    }
535704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
536a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException {
537a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        synchronized (mLock) {
538a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            if (mRemoteInstance != null) {
539a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                return mRemoteInstance;
540a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
541a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            bindLocked();
542a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return mRemoteInstance;
543a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
544a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
545a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
546a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void bindLocked() throws TimeoutException {
5472fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        if (mRemoteInstance != null) {
5482fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            return;
5492fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        }
550a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        if (DEBUG) {
551a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()");
552a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
553a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
554a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        mContext.bindServiceAsUser(mIntent, mServiceConnection,
555d69e4c1460017062e7c36be55801cb434ad19d97Dianne Hackborn                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, mUserHandle);
556a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
557a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        final long startMillis = SystemClock.uptimeMillis();
558a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        while (true) {
559a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            if (mRemoteInstance != null) {
560a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                break;
561a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
562a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
563a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis;
564a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            if (remainingMillis <= 0) {
565a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                throw new TimeoutException("Cannot get spooler!");
566a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
567a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            try {
568a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                mLock.wait(remainingMillis);
569a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            } catch (InterruptedException ie) {
570a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                /* ignore */
571a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
572a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
57385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov
57485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        mCanUnbind = true;
57585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        mLock.notifyAll();
576a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
577a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
578a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void unbindLocked() {
5792fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        if (mRemoteInstance == null) {
5802fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            return;
5812fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        }
58285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov        while (true) {
58385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            if (mCanUnbind) {
58485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                if (DEBUG) {
58585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                    Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] unbindLocked()");
58685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                }
58785b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                clearClientLocked();
58885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mRemoteInstance = null;
58985b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mContext.unbindService(mServiceConnection);
59085b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                return;
59185b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
59285b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            try {
59385b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                mLock.wait();
59485b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            } catch (InterruptedException ie) {
59585b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov                /* ignore */
59685b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov            }
597a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
59885b1f883056a1d74473fd9ce774948878f389ab6Svetoslav Ganov
599a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
600a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
601a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void setClientLocked() {
602a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
603a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mRemoteInstance.setClient(mClient);
604a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
605a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.d(LOG_TAG, "Error setting print spooler client", re);
606a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
607a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
608a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
609a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void clearClientLocked() {
610a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        try {
611a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mRemoteInstance.setClient(null);
612a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        } catch (RemoteException re) {
613a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            Slog.d(LOG_TAG, "Error clearing print spooler client", re);
614a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
615a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
616a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
617a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
618a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void throwIfDestroyedLocked() {
619a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        if (mDestroyed) {
620a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throw new IllegalStateException("Cannot interact with a destroyed instance.");
621a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
622a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
623a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
624a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private void throwIfCalledOnMainThread() {
625a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        if (Thread.currentThread() == mContext.getMainLooper().getThread()) {
626a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            throw new RuntimeException("Cannot invoke on the main thread");
627a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
628a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
629a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
630a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private final class MyServiceConnection implements ServiceConnection {
631a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
632a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onServiceConnected(ComponentName name, IBinder service) {
633a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            synchronized (mLock) {
634a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                mRemoteInstance = IPrintSpooler.Stub.asInterface(service);
635a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                setClientLocked();
636a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                mLock.notifyAll();
637a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
638a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
639a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
640a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
641a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onServiceDisconnected(ComponentName name) {
642a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            synchronized (mLock) {
643a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                clearClientLocked();
644a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                mRemoteInstance = null;
645a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
646a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
647a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
648a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
649a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static final class GetPrintJobInfosCaller
650a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            extends TimedRemoteCaller<List<PrintJobInfo>> {
651a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        private final IPrintSpoolerCallbacks mCallback;
652a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
653a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public GetPrintJobInfosCaller() {
654a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
655a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mCallback = new BasePrintSpoolerServiceCallbacks() {
656a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                @Override
657a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobs, int sequence) {
658a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    onRemoteMethodResult(printJobs, sequence);
659a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
660a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            };
661a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
662a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
663a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public List<PrintJobInfo> getPrintJobInfos(IPrintSpooler target,
664a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                ComponentName componentName, int state, int appId)
665a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                        throws RemoteException, TimeoutException {
666a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            final int sequence = onBeforeRemoteCall();
667a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            target.getPrintJobInfos(mCallback, componentName, state, appId, sequence);
668a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return getResultTimed(sequence);
669a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
670a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
671a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
672a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> {
673a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        private final IPrintSpoolerCallbacks mCallback;
674a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
675a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public GetPrintJobInfoCaller() {
676a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
677a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mCallback = new BasePrintSpoolerServiceCallbacks() {
678a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                @Override
679a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) {
680a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    onRemoteMethodResult(printJob, sequence);
681a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
682a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            };
683a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
684a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
6852fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        public PrintJobInfo getPrintJobInfo(IPrintSpooler target, PrintJobId printJobId,
686a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                int appId) throws RemoteException, TimeoutException {
687a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            final int sequence = onBeforeRemoteCall();
688a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            target.getPrintJobInfo(printJobId, mCallback, appId, sequence);
689a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return getResultTimed(sequence);
690a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
691a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
692a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
693a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static final class SetPrintJobStateCaller extends TimedRemoteCaller<Boolean> {
694a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        private final IPrintSpoolerCallbacks mCallback;
695a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
696a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public SetPrintJobStateCaller() {
697a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
698a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mCallback = new BasePrintSpoolerServiceCallbacks() {
699a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                @Override
700a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                public void onSetPrintJobStateResult(boolean success, int sequence) {
701a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    onRemoteMethodResult(success, sequence);
702a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
703a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            };
704a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
705a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
7062fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        public boolean setPrintJobState(IPrintSpooler target, PrintJobId printJobId,
707269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                int status, String error) throws RemoteException, TimeoutException {
708a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            final int sequence = onBeforeRemoteCall();
7098c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov            target.setPrintJobState(printJobId, status, error, mCallback, sequence);
710a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return getResultTimed(sequence);
711a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
712a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
713a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
714a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static final class SetPrintJobTagCaller extends TimedRemoteCaller<Boolean> {
715a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        private final IPrintSpoolerCallbacks mCallback;
716a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
717a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public SetPrintJobTagCaller() {
718a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
719a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mCallback = new BasePrintSpoolerServiceCallbacks() {
720a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                @Override
721a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                public void onSetPrintJobTagResult(boolean success, int sequence) {
722a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    onRemoteMethodResult(success, sequence);
723a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
724a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            };
725a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
726a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
7272fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav        public boolean setPrintJobTag(IPrintSpooler target, PrintJobId printJobId,
728a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                String tag) throws RemoteException, TimeoutException {
729a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            final int sequence = onBeforeRemoteCall();
730a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            target.setPrintJobTag(printJobId, tag, mCallback, sequence);
731a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            return getResultTimed(sequence);
732a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
733a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
734a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
735bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    private static final class OnCustomPrinterIconLoadedCaller extends TimedRemoteCaller<Void> {
736bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        private final IPrintSpoolerCallbacks mCallback;
737bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
738bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public OnCustomPrinterIconLoadedCaller() {
739bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
740bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            mCallback = new BasePrintSpoolerServiceCallbacks() {
741bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                @Override
742bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                public void onCustomPrinterIconCached(int sequence) {
743bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    onRemoteMethodResult(null, sequence);
744bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                }
745bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            };
746bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
747bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
748bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public Void onCustomPrinterIconLoaded(IPrintSpooler target, PrinterId printerId,
749bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                Icon icon) throws RemoteException, TimeoutException {
750bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            final int sequence = onBeforeRemoteCall();
751bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            target.onCustomPrinterIconLoaded(printerId, icon, mCallback, sequence);
752bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            return getResultTimed(sequence);
753bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
754bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
755bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
756bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    private static final class ClearCustomPrinterIconCacheCaller extends TimedRemoteCaller<Void> {
757bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        private final IPrintSpoolerCallbacks mCallback;
758bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
759bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public ClearCustomPrinterIconCacheCaller() {
760bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
761bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            mCallback = new BasePrintSpoolerServiceCallbacks() {
762bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                @Override
763bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                public void customPrinterIconCacheCleared(int sequence) {
764bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    onRemoteMethodResult(null, sequence);
765bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                }
766bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            };
767bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
768bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
769bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public Void clearCustomPrinterIconCache(IPrintSpooler target)
770bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                throws RemoteException, TimeoutException {
771bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            final int sequence = onBeforeRemoteCall();
772bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            target.clearCustomPrinterIconCache(mCallback, sequence);
773bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            return getResultTimed(sequence);
774bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
775bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
776bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
777bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    private static final class GetCustomPrinterIconCaller extends TimedRemoteCaller<Icon> {
778bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        private final IPrintSpoolerCallbacks mCallback;
779bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
780bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public GetCustomPrinterIconCaller() {
781bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
782bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            mCallback = new BasePrintSpoolerServiceCallbacks() {
783bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                @Override
784bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                public void onGetCustomPrinterIconResult(Icon icon, int sequence) {
785bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    onRemoteMethodResult(icon, sequence);
786bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                }
787bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            };
788bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
789bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
790bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public Icon getCustomPrinterIcon(IPrintSpooler target, PrinterId printerId)
791bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                throws RemoteException, TimeoutException {
792bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            final int sequence = onBeforeRemoteCall();
793bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            target.getCustomPrinterIcon(printerId, mCallback, sequence);
794bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            return getResultTimed(sequence);
795bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
796bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
797bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
798a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static abstract class BasePrintSpoolerServiceCallbacks
799a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            extends IPrintSpoolerCallbacks.Stub {
800a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
801a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobIds, int sequence) {
802a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            /* do nothing */
803a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
804a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
805a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
806a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) {
807a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            /* do nothing */
808a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
809a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
810a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
811a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onCancelPrintJobResult(boolean canceled, int sequence) {
812a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            /* do nothing */
813a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
814a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
815a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
816a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onSetPrintJobStateResult(boolean success, int sequece) {
817a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            /* do nothing */
818a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
819a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
820a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
821a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onSetPrintJobTagResult(boolean success, int sequence) {
822a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            /* do nothing */
823a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
824bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
825bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        @Override
826bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public void onCustomPrinterIconCached(int sequence) {
827bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            /* do nothing */
828bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
829bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
830bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        @Override
831bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public void onGetCustomPrinterIconResult(@Nullable Icon icon, int sequence) {
832bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            /* do nothing */
833bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
834bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
835bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        @Override
836bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        public void customPrinterIconCacheCleared(int sequence) {
837bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            /* do nothing */
838bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
839a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
840a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
841a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    private static final class PrintSpoolerClient extends IPrintSpoolerClient.Stub {
842a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
843a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        private final WeakReference<RemotePrintSpooler> mWeakSpooler;
844a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
845a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public PrintSpoolerClient(RemotePrintSpooler spooler) {
846a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            mWeakSpooler = new WeakReference<RemotePrintSpooler>(spooler);
847a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
848a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
849a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
850a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onPrintJobQueued(PrintJobInfo printJob) {
851a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            RemotePrintSpooler spooler = mWeakSpooler.get();
852a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            if (spooler != null) {
853a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                final long identity = Binder.clearCallingIdentity();
854a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                try {
855a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    spooler.mCallbacks.onPrintJobQueued(printJob);
856a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                } finally {
857a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    Binder.restoreCallingIdentity(identity);
858a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
859a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
860a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
861a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
862a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
863a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onAllPrintJobsForServiceHandled(ComponentName printService) {
864a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            RemotePrintSpooler spooler = mWeakSpooler.get();
865a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            if (spooler != null) {
866a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                final long identity = Binder.clearCallingIdentity();
867a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                try {
868a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    spooler.mCallbacks.onAllPrintJobsForServiceHandled(printService);
869a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                } finally {
870a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    Binder.restoreCallingIdentity(identity);
871a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
872a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
873a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
874a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov
875a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        @Override
876a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        public void onAllPrintJobsHandled() {
877a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            RemotePrintSpooler spooler = mWeakSpooler.get();
878a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            if (spooler != null) {
879a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                final long identity = Binder.clearCallingIdentity();
880a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                try {
881a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    spooler.onAllPrintJobsHandled();
882a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                } finally {
883a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                    Binder.restoreCallingIdentity(identity);
884a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov                }
885a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov            }
886a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov        }
887704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov
888704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        @Override
889dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov        public void onPrintJobStateChanged(PrintJobInfo printJob) {
890704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov            RemotePrintSpooler spooler = mWeakSpooler.get();
891704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov            if (spooler != null) {
892704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                final long identity = Binder.clearCallingIdentity();
893704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                try {
894dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov                    spooler.onPrintJobStateChanged(printJob);
895704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                } finally {
896704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                    Binder.restoreCallingIdentity(identity);
897704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov                }
898704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov            }
899704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov        }
900a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov    }
901a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov}
902