PrinterDiscoverySession.java revision bb9f686b40743df2642b7d3b7778dbf7284ae665
1798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov/*
2798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * Copyright (C) 2013 The Android Open Source Project
3798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov *
4798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
5798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * you may not use this file except in compliance with the License.
6798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * You may obtain a copy of the License at
7798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov *
8798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
9798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov *
10798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software
11798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
12798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * See the License for the specific language governing permissions and
14798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * limitations under the License.
15798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov */
16798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
17798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovpackage android.printservice;
18798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
19bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.annotation.NonNull;
202fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.content.pm.ParceledListSlice;
21798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.os.RemoteException;
22269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterCapabilitiesInfo;
23798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.print.PrinterId;
24798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.print.PrinterInfo;
25269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.util.ArrayMap;
26798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.util.Log;
27798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
28269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.ArrayList;
29269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.Collections;
30798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport java.util.List;
31798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
32798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov/**
33798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * This class encapsulates the interaction between a print service and the
34798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * system during printer discovery. During printer discovery you are responsible
3599cc86f9e096b204f1e9a3754bcb9514512ddaebSvetoslav Ganov * for adding discovered printers, removing previously added printers that
36798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * disappeared, and updating already added printers.
37798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * <p>
38269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * During the lifetime of this session you may be asked to start and stop
39269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * performing printer discovery multiple times. You will receive a call to {@link
40269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * PrinterDiscoverySession#onStartPrinterDiscovery(List)} to start printer
41269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * discovery and a call to {@link PrinterDiscoverySession#onStopPrinterDiscovery()}
42269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * to stop printer discovery. When the system is no longer interested in printers
43269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * discovered by this session you will receive a call to {@link #onDestroy()} at
44269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * which point the system will no longer call into the session and all the session
45269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * methods will do nothing.
46269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * </p>
47269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * <p>
48269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Discovered printers are added by invoking {@link
49269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * PrinterDiscoverySession#addPrinters(List)}. Added printers that disappeared are
50269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * removed by invoking {@link PrinterDiscoverySession#removePrinters(List)}. Added
51269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * printers whose properties or capabilities changed are updated through a call to
52773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav * {@link PrinterDiscoverySession#addPrinters(List)}. The printers added in this
53269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * session can be acquired via {@link #getPrinters()} where the returned printers
54269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * will be an up-to-date snapshot of the printers that you reported during the
55269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * session. Printers are <strong>not</strong> persisted across sessions.
56798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * </p>
57798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * <p>
58d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * The system will make a call to {@link #onValidatePrinters(List)} if you
59d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * need to update some printers. It is possible that you add a printer without
60269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * specifying its capabilities. This enables you to avoid querying all discovered
61269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * printers for their capabilities, rather querying the capabilities of a printer
62269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * only if necessary. For example, the system will request that you update a printer
63d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * if it gets selected by the user. When validating printers you do not need to
64d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * provide the printers' capabilities but may do so.
65d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * </p>
66d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * <p>
67d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * If the system is interested in being constantly updated for the state of a
68d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * printer you will receive a call to {@link #onStartPrinterStateTracking(PrinterId)}
69d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * after which you will have to do a best effort to keep the system updated for
70d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * changes in the printer state and capabilities. You also <strong>must</strong>
71d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * update the printer capabilities if you did not provide them when adding it, or
72d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * the printer will be ignored. When the system is no longer interested in getting
73d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * updates for a printer you will receive a call to {@link #onStopPrinterStateTracking(
74d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * PrinterId)}.
75798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * </p>
76798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * <p>
77269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * <strong>Note: </strong> All callbacks in this class are executed on the main
78269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * application thread. You also have to invoke any method of this class on the main
79269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * application thread.
80798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * </p>
81798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov */
82798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovpublic abstract class PrinterDiscoverySession {
83798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    private static final String LOG_TAG = "PrinterDiscoverySession";
84798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
85798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    private static int sIdCounter = 0;
86798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
87269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private final int mId;
88798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
89269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
90269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            new ArrayMap<PrinterId, PrinterInfo>();
91798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
92773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    private final List<PrinterId> mTrackedPrinters =
93773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            new ArrayList<PrinterId>();
94773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav
95269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private ArrayMap<PrinterId, PrinterInfo> mLastSentPrinters;
96269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
97269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private IPrintServiceClient mObserver;
98798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
99269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private boolean mIsDestroyed;
100798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
101269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private boolean mIsDiscoveryStarted;
102798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
103798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
104798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * Constructor.
105798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
106269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public PrinterDiscoverySession() {
107798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        mId = sIdCounter++;
108798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
109798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
110269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void setObserver(IPrintServiceClient observer) {
111269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        mObserver = observer;
112269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // If some printers were added in the method that
113269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // created the session, send them over.
114269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mPrinters.isEmpty()) {
1152fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            try {
1162fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(getPrinters()));
1172fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            } catch (RemoteException re) {
1182fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Log.e(LOG_TAG, "Error sending added printers", re);
1192fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
120798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
121798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
122798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
123798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    int getId() {
124798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        return mId;
125798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
126798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
127798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
128269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Gets the printers reported in this session. For example, if you add two
129269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * printers and remove one of them, the returned list will contain only
130269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * the printer that was added but not removed.
131269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <p>
132269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong> Calls to this method after the session is
133d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
134269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * </p>
135269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
136269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @return The printers.
137269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
138269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #addPrinters(List)
139269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #removePrinters(List)
140269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
141269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
142269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public final List<PrinterInfo> getPrinters() {
143269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
144269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDestroyed) {
145269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return Collections.emptyList();
146269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
147269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        return new ArrayList<PrinterInfo>(mPrinters.values());
148269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
149269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
150269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
151773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * Adds discovered printers. Adding an already added printer updates it.
152798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * Removed printers can be added again. You can call this method multiple
153269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * times during the life of this session. Duplicates will be ignored.
154798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
155269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong> Calls to this method after the session is
156d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
157798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
158798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
159798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @param printers The printers to add.
160798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
161798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #removePrinters(List)
162269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #getPrinters()
163269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
164798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
165798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    public final void addPrinters(List<PrinterInfo> printers) {
166269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
167269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
168269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // If the session is destroyed - nothing do to.
169269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDestroyed) {
170269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            Log.w(LOG_TAG, "Not adding printers - session destroyed.");
171269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return;
172798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
173269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
174269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDiscoveryStarted) {
175269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // If during discovery, add the new printers and send them.
176773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            List<PrinterInfo> addedPrinters = null;
177269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int addedPrinterCount = printers.size();
178269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < addedPrinterCount; i++) {
179269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterInfo addedPrinter = printers.get(i);
180773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                PrinterInfo oldPrinter = mPrinters.put(addedPrinter.getId(), addedPrinter);
181773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                if (oldPrinter == null || !oldPrinter.equals(addedPrinter)) {
182773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                    if (addedPrinters == null) {
183773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                        addedPrinters = new ArrayList<PrinterInfo>();
184773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                    }
185269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    addedPrinters.add(addedPrinter);
186269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
187269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
188269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
189269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Send the added printers, if such.
190773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            if (addedPrinters != null) {
1912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                try {
1922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
1932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                } catch (RemoteException re) {
1942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    Log.e(LOG_TAG, "Error sending added printers", re);
1952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                }
196798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov            }
19718d9c3cc6c7d69f7c5b36dafc4b66f0722b98a89Svetoslav Ganov        } else {
198269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Remember the last sent printers if needed.
199269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (mLastSentPrinters == null) {
200269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                mLastSentPrinters = new ArrayMap<PrinterId, PrinterInfo>(mPrinters);
201269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
202269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
203269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Update the printers.
204269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int addedPrinterCount = printers.size();
205269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < addedPrinterCount; i++) {
206269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterInfo addedPrinter = printers.get(i);
207269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (mPrinters.get(addedPrinter.getId()) == null) {
208269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    mPrinters.put(addedPrinter.getId(), addedPrinter);
209269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
210269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
211269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
212269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
213269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
214798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
215798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * Removes added printers. Removing an already removed or never added
216269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * printer has no effect. Removed printers can be added again. You can
217269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * call this method multiple times during the lifetime of this session.
218798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
219269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong> Calls to this method after the session is
220d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
221798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
222798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
223798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @param printerIds The ids of the removed printers.
224798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
225798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #addPrinters(List)
226269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #getPrinters()
227269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
228798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
229798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    public final void removePrinters(List<PrinterId> printerIds) {
230269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
231269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
232269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // If the session is destroyed - nothing do to.
233269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDestroyed) {
234269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            Log.w(LOG_TAG, "Not removing printers - session destroyed.");
235269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return;
236798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
237269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
238269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDiscoveryStarted) {
239269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // If during discovery, remove existing printers and send them.
240269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            List<PrinterId> removedPrinterIds = new ArrayList<PrinterId>();
241269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int removedPrinterIdCount = printerIds.size();
242269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < removedPrinterIdCount; i++) {
243269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterId removedPrinterId = printerIds.get(i);
244269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (mPrinters.remove(removedPrinterId) != null) {
245269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    removedPrinterIds.add(removedPrinterId);
246269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
247269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
248269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
249269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Send the removed printers, if such.
250269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (!removedPrinterIds.isEmpty()) {
2512fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                try {
2522fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(
2532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                            removedPrinterIds));
2542fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                } catch (RemoteException re) {
2552fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    Log.e(LOG_TAG, "Error sending removed printers", re);
2562fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                }
257798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov            }
25818d9c3cc6c7d69f7c5b36dafc4b66f0722b98a89Svetoslav Ganov        } else {
259269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Remember the last sent printers if needed.
260269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (mLastSentPrinters == null) {
261269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                mLastSentPrinters = new ArrayMap<PrinterId, PrinterInfo>(mPrinters);
262269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
263269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
264269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Update the printers.
265269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int removedPrinterIdCount = printerIds.size();
266269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < removedPrinterIdCount; i++) {
267269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterId removedPrinterId = printerIds.get(i);
268269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                mPrinters.remove(removedPrinterId);
269269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
270269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
271269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
272269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
273269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private void sendOutOfDiscoveryPeriodPrinterChanges() {
274269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Noting changed since the last discovery period - nothing to do.
275269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mLastSentPrinters == null || mLastSentPrinters.isEmpty()) {
276269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mLastSentPrinters = null;
277269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return;
278269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
279269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
280773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        // Determine the added printers.
281269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        List<PrinterInfo> addedPrinters = null;
282269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        for (PrinterInfo printer : mPrinters.values()) {
283269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            PrinterInfo sentPrinter = mLastSentPrinters.get(printer.getId());
284773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            if (sentPrinter == null || !sentPrinter.equals(printer)) {
285269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (addedPrinters == null) {
286269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    addedPrinters = new ArrayList<PrinterInfo>();
287269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
288269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                addedPrinters.add(printer);
289269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
290798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
291269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
292269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Send the added printers, if such.
293269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (addedPrinters != null) {
2942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            try {
2952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
2962fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            } catch (RemoteException re) {
2972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Log.e(LOG_TAG, "Error sending added printers", re);
2982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
299269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
300269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
301269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Determine the removed printers.
302773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        List<PrinterId> removedPrinterIds = null;
303269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        for (PrinterInfo sentPrinter : mLastSentPrinters.values()) {
304269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (!mPrinters.containsKey(sentPrinter.getId())) {
305269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (removedPrinterIds == null) {
306269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    removedPrinterIds = new ArrayList<PrinterId>();
307269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
308269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                removedPrinterIds.add(sentPrinter.getId());
309269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
310269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
311269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
312269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Send the removed printers, if such.
313269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (removedPrinterIds != null) {
3142fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            try {
3152fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(removedPrinterIds));
3162fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            } catch (RemoteException re) {
3172fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Log.e(LOG_TAG, "Error sending removed printers", re);
3182fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
319269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
320269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
321269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        mLastSentPrinters = null;
322798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
323798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
324798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
325269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Callback asking you to start printer discovery. Discovered printers should be
326269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * added via calling {@link #addPrinters(List)}. Added printers that disappeared
327269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * should be removed via calling {@link #removePrinters(List)}. Added printers
328269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * whose properties or capabilities changed should be updated via calling {@link
329773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * #addPrinters(List)}. You will receive a call to {@link #onStopPrinterDiscovery()}
330773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * when you should stop printer discovery.
331798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
332269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * During the lifetime of this session all printers that are known to your print
333269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * service have to be added. The system does not retain any printers across sessions.
334269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * However, if you were asked to start and then stop performing printer discovery
335269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * in this session, then a subsequent discovering should not re-discover already
336773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * discovered printers. You can get the printers reported during this session by
337773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * calling {@link #getPrinters()}.
338798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
339798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
340269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong>You are also given a list of printers whose availability
341269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * has to be checked first. For example, these printers could be the user's favorite
342d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * ones, therefore they have to be verified first. You do <strong>not need</strong>
343d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * to provide the capabilities of the printers, rather verify whether they exist
344d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * similarly to {@link #onValidatePrinters(List)}.
345798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
346798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
347269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @param priorityList The list of printers to validate first. Never null.
348269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
349269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStopPrinterDiscovery()
350798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #addPrinters(List)
351798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #removePrinters(List)
352269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isPrinterDiscoveryStarted()
353798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
354269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
355798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
356798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
357269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Callback notifying you that you should stop printer discovery.
358269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
359269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStartPrinterDiscovery(List)
360269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isPrinterDiscoveryStarted()
361798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
362269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public abstract void onStopPrinterDiscovery();
363798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
364798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
365d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * Callback asking you to validate that the given printers are valid, that
366d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * is they exist. You are responsible for checking whether these printers
367d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * exist and for the ones that do exist notify the system via calling
368773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * {@link #addPrinters(List)}.
369d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <p>
370d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <strong>Note: </strong> You are <strong>not required</strong> to provide
371d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * the printer capabilities when updating the printers that do exist.
372d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <p>
373d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
374d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @param printerIds The printers to validate.
375d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
376d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @see PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
377d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *      PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
378d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     */
379d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    public abstract void onValidatePrinters(List<PrinterId> printerIds);
380d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
381d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    /**
382d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * Callback asking you to start tracking the state of a printer. Tracking
383d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * the state means that you should do a best effort to observe the state
384d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * of this printer and notify the system if that state changes via calling
385773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * {@link #addPrinters(List)}.
386798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
387798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <strong>Note: </strong> A printer can be initially added without its
388798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * capabilities to avoid polling printers that the user will not select.
389798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * However, after this method is called you are expected to update the
390798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * printer <strong>including</strong> its capabilities. Otherwise, the
391798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * printer will be ignored.
392798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
393d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <p>
394d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * A scenario when you may be requested to track a printer's state is if
395d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * the user selects that printer and the system has to present print
396d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * options UI based on the printer's capabilities. In this case the user
397d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * should be promptly informed if, for example, the printer becomes
398d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * unavailable.
399798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
400798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
401d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @param printerId The printer to start tracking.
402798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
403d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @see #onStopPrinterStateTracking(PrinterId)
404798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
405798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *      PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
406798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
407d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    public abstract void onStartPrinterStateTracking(PrinterId printerId);
408d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
409d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    /**
410bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * Request the custom icon for a printer. Once the icon is available use
411bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * {@link CustomPrinterIconCallback#onCustomPrinterIconLoaded} to send the data to the print
412bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * service.
413bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
414bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param printerId The printer to icon belongs to.
415bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param callback Callback for returning the icon to the print spooler.
416bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
417bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
418bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
419bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    public void onRequestCustomPrinterIcon(@NonNull PrinterId printerId,
420bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            @NonNull CustomPrinterIconCallback callback) {
421bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
422bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
423bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
424d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * Callback asking you to stop tracking the state of a printer. The passed
425d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * in printer id is the one for which you received a call to {@link
426d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * #onStartPrinterStateTracking(PrinterId)}.
427d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
428d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @param printerId The printer to stop tracking.
429d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
430d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @see #onStartPrinterStateTracking(PrinterId)
431d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     */
432d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    public abstract void onStopPrinterStateTracking(PrinterId printerId);
433798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
434269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
435773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * Gets the printers that should be tracked. These are printers that are
436773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * important to the user and for which you received a call to {@link
437773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * #onStartPrinterStateTracking(PrinterId)} asking you to observer their
438773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * state and reporting it to the system via {@link #addPrinters(List)}.
439773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * You will receive a call to {@link #onStopPrinterStateTracking(PrinterId)}
440773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * if you should stop tracking a printer.
441773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * <p>
442773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * <strong>Note: </strong> Calls to this method after the session is
443773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
444773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * </p>
445773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     *
446773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @return The printers.
447773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     *
448773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @see #onStartPrinterStateTracking(PrinterId)
449773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @see #onStopPrinterStateTracking(PrinterId)
450773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @see #isDestroyed()
451773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     */
452773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    public final List<PrinterId> getTrackedPrinters() {
453773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        PrintService.throwIfNotCalledOnMainThread();
454773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        if (mIsDestroyed) {
455773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            return Collections.emptyList();
456773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        }
457773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        return new ArrayList<PrinterId>(mTrackedPrinters);
458773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    }
459773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav
460773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    /**
461269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Notifies you that the session is destroyed. After this callback is invoked
462269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * any calls to the methods of this class will be ignored, {@link #isDestroyed()}
463269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * will return true and you will also no longer receive callbacks.
464269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
465269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
466269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
467269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public abstract void onDestroy();
468798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
469269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
470269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Gets whether the session is destroyed.
471269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
472269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @return Whether the session is destroyed.
473269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
474269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onDestroy()
475269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
476269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public final boolean isDestroyed() {
477269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
478269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        return mIsDestroyed;
479269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
480798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
481269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
482269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Gets whether printer discovery is started.
483269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
484269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @return Whether printer discovery is destroyed.
485269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
486269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStartPrinterDiscovery(List)
487269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStopPrinterDiscovery()
488269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
489269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public final boolean isPrinterDiscoveryStarted() {
490269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
491269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        return mIsDiscoveryStarted;
492269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
493798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
494269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void startPrinterDiscovery(List<PrinterId> priorityList) {
495269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mIsDestroyed) {
496269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDiscoveryStarted = true;
497269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            sendOutOfDiscoveryPeriodPrinterChanges();
498269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (priorityList == null) {
499269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                priorityList = Collections.emptyList();
500798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov            }
501269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            onStartPrinterDiscovery(priorityList);
502798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
503798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
504798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
505269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void stopPrinterDiscovery() {
506269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mIsDestroyed) {
507269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDiscoveryStarted = false;
508269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            onStopPrinterDiscovery();
509798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
510269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
511798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
512d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    void validatePrinters(List<PrinterId> printerIds) {
513d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        if (!mIsDestroyed && mObserver != null) {
514d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov            onValidatePrinters(printerIds);
515d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
516d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    }
517d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
518d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    void startPrinterStateTracking(PrinterId printerId) {
519773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        if (!mIsDestroyed && mObserver != null
520773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                && !mTrackedPrinters.contains(printerId)) {
521773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            mTrackedPrinters.add(printerId);
522d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov            onStartPrinterStateTracking(printerId);
523d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
524d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    }
525d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
526bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
527bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * Request the custom icon for a printer.
528bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
529bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param printerId The printer to icon belongs to.
530bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
531bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
532bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    void requestCustomPrinterIcon(PrinterId printerId) {
533bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        if (!mIsDestroyed && mObserver != null) {
534bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            CustomPrinterIconCallback callback = new CustomPrinterIconCallback(printerId,
535bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    mObserver);
536bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            onRequestCustomPrinterIcon(printerId, callback);
537bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
538bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
539bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
540d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    void stopPrinterStateTracking(PrinterId printerId) {
541773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        if (!mIsDestroyed && mObserver != null
542773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                && mTrackedPrinters.remove(printerId)) {
543d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov            onStopPrinterStateTracking(printerId);
544798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
545269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
546798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
547269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void destroy() {
548269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mIsDestroyed) {
549269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDestroyed = true;
550269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDiscoveryStarted = false;
551269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mPrinters.clear();
552269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mLastSentPrinters = null;
553269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mObserver = null;
554269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            onDestroy();
555798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
556269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
557798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov}
558