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;
21e54d79c4cd6f90ccc6288df7a09d91698d603d9ePhilip P. Moltmannimport android.os.CancellationSignal;
22798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.os.RemoteException;
23269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterCapabilitiesInfo;
24798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.print.PrinterId;
25798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.print.PrinterInfo;
26269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.util.ArrayMap;
27798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport android.util.Log;
28798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
29269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.ArrayList;
30269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.Collections;
31798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovimport java.util.List;
32798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
33798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov/**
34798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * This class encapsulates the interaction between a print service and the
35798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * system during printer discovery. During printer discovery you are responsible
3699cc86f9e096b204f1e9a3754bcb9514512ddaebSvetoslav Ganov * for adding discovered printers, removing previously added printers that
37798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * disappeared, and updating already added printers.
38798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * <p>
39269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * During the lifetime of this session you may be asked to start and stop
40269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * performing printer discovery multiple times. You will receive a call to {@link
41269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * PrinterDiscoverySession#onStartPrinterDiscovery(List)} to start printer
42269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * discovery and a call to {@link PrinterDiscoverySession#onStopPrinterDiscovery()}
43269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * to stop printer discovery. When the system is no longer interested in printers
44269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * discovered by this session you will receive a call to {@link #onDestroy()} at
45269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * which point the system will no longer call into the session and all the session
46269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * methods will do nothing.
47269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * </p>
48269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * <p>
49269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Discovered printers are added by invoking {@link
50269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * PrinterDiscoverySession#addPrinters(List)}. Added printers that disappeared are
51269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * removed by invoking {@link PrinterDiscoverySession#removePrinters(List)}. Added
52269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * printers whose properties or capabilities changed are updated through a call to
53773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav * {@link PrinterDiscoverySession#addPrinters(List)}. The printers added in this
54269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * session can be acquired via {@link #getPrinters()} where the returned printers
55269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * will be an up-to-date snapshot of the printers that you reported during the
56269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * session. Printers are <strong>not</strong> persisted across sessions.
57798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * </p>
58798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * <p>
59d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * The system will make a call to {@link #onValidatePrinters(List)} if you
60d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * need to update some printers. It is possible that you add a printer without
61269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * specifying its capabilities. This enables you to avoid querying all discovered
62269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * printers for their capabilities, rather querying the capabilities of a printer
63269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * only if necessary. For example, the system will request that you update a printer
64d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * if it gets selected by the user. When validating printers you do not need to
65d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * provide the printers' capabilities but may do so.
66d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * </p>
67d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * <p>
68d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * If the system is interested in being constantly updated for the state of a
69d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * printer you will receive a call to {@link #onStartPrinterStateTracking(PrinterId)}
70d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * after which you will have to do a best effort to keep the system updated for
71d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * changes in the printer state and capabilities. You also <strong>must</strong>
72d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * update the printer capabilities if you did not provide them when adding it, or
73d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * the printer will be ignored. When the system is no longer interested in getting
74d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * updates for a printer you will receive a call to {@link #onStopPrinterStateTracking(
75d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov * PrinterId)}.
76798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * </p>
77798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * <p>
78269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * <strong>Note: </strong> All callbacks in this class are executed on the main
79269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * application thread. You also have to invoke any method of this class on the main
80269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * application thread.
81798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov * </p>
82798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov */
83798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganovpublic abstract class PrinterDiscoverySession {
84798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    private static final String LOG_TAG = "PrinterDiscoverySession";
85798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
86798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    private static int sIdCounter = 0;
87798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
88269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private final int mId;
89798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
90269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
91269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            new ArrayMap<PrinterId, PrinterInfo>();
92798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
93773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    private final List<PrinterId> mTrackedPrinters =
94773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            new ArrayList<PrinterId>();
95773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav
96269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private ArrayMap<PrinterId, PrinterInfo> mLastSentPrinters;
97269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
98269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private IPrintServiceClient mObserver;
99798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
100269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private boolean mIsDestroyed;
101798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
102269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private boolean mIsDiscoveryStarted;
103798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
104798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
105798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * Constructor.
106798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
107269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public PrinterDiscoverySession() {
108798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        mId = sIdCounter++;
109798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
110798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
111269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void setObserver(IPrintServiceClient observer) {
112269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        mObserver = observer;
113269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // If some printers were added in the method that
114269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // created the session, send them over.
115269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mPrinters.isEmpty()) {
1162fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            try {
1172fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(getPrinters()));
1182fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            } catch (RemoteException re) {
1192fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Log.e(LOG_TAG, "Error sending added printers", re);
1202fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
121798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
122798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
123798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
124798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    int getId() {
125798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        return mId;
126798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
127798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
128798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
129269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Gets the printers reported in this session. For example, if you add two
130269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * printers and remove one of them, the returned list will contain only
131269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * the printer that was added but not removed.
132269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <p>
133269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong> Calls to this method after the session is
134d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
135269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * </p>
136269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
137269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @return The printers.
138269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
139269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #addPrinters(List)
140269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #removePrinters(List)
141269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
142269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
143c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public final @NonNull List<PrinterInfo> getPrinters() {
144269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
145269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDestroyed) {
146269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return Collections.emptyList();
147269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
148269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        return new ArrayList<PrinterInfo>(mPrinters.values());
149269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
150269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
151269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
152773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * Adds discovered printers. Adding an already added printer updates it.
153798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * Removed printers can be added again. You can call this method multiple
154269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * times during the life of this session. Duplicates will be ignored.
155798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
156269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong> Calls to this method after the session is
157d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
158798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
159798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
160798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @param printers The printers to add.
161798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
162798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #removePrinters(List)
163269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #getPrinters()
164269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
165798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
166c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public final void addPrinters(@NonNull List<PrinterInfo> printers) {
167269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
168269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
169269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // If the session is destroyed - nothing do to.
170269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDestroyed) {
171269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            Log.w(LOG_TAG, "Not adding printers - session destroyed.");
172269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return;
173798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
174269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
175269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDiscoveryStarted) {
176269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // If during discovery, add the new printers and send them.
177773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            List<PrinterInfo> addedPrinters = null;
178269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int addedPrinterCount = printers.size();
179269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < addedPrinterCount; i++) {
180269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterInfo addedPrinter = printers.get(i);
181773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                PrinterInfo oldPrinter = mPrinters.put(addedPrinter.getId(), addedPrinter);
182773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                if (oldPrinter == null || !oldPrinter.equals(addedPrinter)) {
183773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                    if (addedPrinters == null) {
184773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                        addedPrinters = new ArrayList<PrinterInfo>();
185773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                    }
186269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    addedPrinters.add(addedPrinter);
187269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
188269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
189269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
190269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Send the added printers, if such.
191773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            if (addedPrinters != null) {
1922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                try {
1932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
1942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                } catch (RemoteException re) {
1952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    Log.e(LOG_TAG, "Error sending added printers", re);
1962fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                }
197798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov            }
19818d9c3cc6c7d69f7c5b36dafc4b66f0722b98a89Svetoslav Ganov        } else {
199269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Remember the last sent printers if needed.
200269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (mLastSentPrinters == null) {
201269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                mLastSentPrinters = new ArrayMap<PrinterId, PrinterInfo>(mPrinters);
202269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
203269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
204269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Update the printers.
205269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int addedPrinterCount = printers.size();
206269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < addedPrinterCount; i++) {
207269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterInfo addedPrinter = printers.get(i);
208269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (mPrinters.get(addedPrinter.getId()) == null) {
209269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    mPrinters.put(addedPrinter.getId(), addedPrinter);
210269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
211269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
212269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
213269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
214269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
215798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
216798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * Removes added printers. Removing an already removed or never added
217269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * printer has no effect. Removed printers can be added again. You can
218269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * call this method multiple times during the lifetime of this session.
219798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
220269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong> Calls to this method after the session is
221d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
222798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
223798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
224798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @param printerIds The ids of the removed printers.
225798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
226798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #addPrinters(List)
227269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #getPrinters()
228269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
229798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
230c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public final void removePrinters(@NonNull List<PrinterId> printerIds) {
231269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
232269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
233269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // If the session is destroyed - nothing do to.
234269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDestroyed) {
235269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            Log.w(LOG_TAG, "Not removing printers - session destroyed.");
236269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return;
237798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
238269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
239269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mIsDiscoveryStarted) {
240269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // If during discovery, remove existing printers and send them.
241269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            List<PrinterId> removedPrinterIds = new ArrayList<PrinterId>();
242269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int removedPrinterIdCount = printerIds.size();
243269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < removedPrinterIdCount; i++) {
244269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterId removedPrinterId = printerIds.get(i);
245269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (mPrinters.remove(removedPrinterId) != null) {
246269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    removedPrinterIds.add(removedPrinterId);
247269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
248269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
249269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
250269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Send the removed printers, if such.
251269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (!removedPrinterIds.isEmpty()) {
2522fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                try {
2532fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(
2542fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                            removedPrinterIds));
2552fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                } catch (RemoteException re) {
2562fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                    Log.e(LOG_TAG, "Error sending removed printers", re);
2572fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                }
258798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov            }
25918d9c3cc6c7d69f7c5b36dafc4b66f0722b98a89Svetoslav Ganov        } else {
260269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Remember the last sent printers if needed.
261269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (mLastSentPrinters == null) {
262269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                mLastSentPrinters = new ArrayMap<PrinterId, PrinterInfo>(mPrinters);
263269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
264269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
265269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            // Update the printers.
266269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            final int removedPrinterIdCount = printerIds.size();
267269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            for (int i = 0; i < removedPrinterIdCount; i++) {
268269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                PrinterId removedPrinterId = printerIds.get(i);
269269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                mPrinters.remove(removedPrinterId);
270269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
271269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
272269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
273269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
274269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    private void sendOutOfDiscoveryPeriodPrinterChanges() {
275269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Noting changed since the last discovery period - nothing to do.
276269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (mLastSentPrinters == null || mLastSentPrinters.isEmpty()) {
277269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mLastSentPrinters = null;
278269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return;
279269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
280269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
281773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        // Determine the added printers.
282269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        List<PrinterInfo> addedPrinters = null;
283269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        for (PrinterInfo printer : mPrinters.values()) {
284269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            PrinterInfo sentPrinter = mLastSentPrinters.get(printer.getId());
285773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            if (sentPrinter == null || !sentPrinter.equals(printer)) {
286269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (addedPrinters == null) {
287269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    addedPrinters = new ArrayList<PrinterInfo>();
288269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
289269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                addedPrinters.add(printer);
290269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
291798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
292269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
293269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Send the added printers, if such.
294269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (addedPrinters != null) {
2952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            try {
2962fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
2972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            } catch (RemoteException re) {
2982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Log.e(LOG_TAG, "Error sending added printers", re);
2992fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
300269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
301269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
302269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Determine the removed printers.
303773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        List<PrinterId> removedPrinterIds = null;
304269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        for (PrinterInfo sentPrinter : mLastSentPrinters.values()) {
305269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (!mPrinters.containsKey(sentPrinter.getId())) {
306269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                if (removedPrinterIds == null) {
307269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    removedPrinterIds = new ArrayList<PrinterId>();
308269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
309269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                removedPrinterIds.add(sentPrinter.getId());
310269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
311269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
312269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
313269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        // Send the removed printers, if such.
314269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (removedPrinterIds != null) {
3152fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            try {
3162fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(removedPrinterIds));
3172fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            } catch (RemoteException re) {
3182fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav                Log.e(LOG_TAG, "Error sending removed printers", re);
3192fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav            }
320269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
321269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
322269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        mLastSentPrinters = null;
323798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
324798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
325798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
326269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Callback asking you to start printer discovery. Discovered printers should be
327269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * added via calling {@link #addPrinters(List)}. Added printers that disappeared
328269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * should be removed via calling {@link #removePrinters(List)}. Added printers
329269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * whose properties or capabilities changed should be updated via calling {@link
330773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * #addPrinters(List)}. You will receive a call to {@link #onStopPrinterDiscovery()}
331773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * when you should stop printer discovery.
332798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
333269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * During the lifetime of this session all printers that are known to your print
334269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * service have to be added. The system does not retain any printers across sessions.
335269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * However, if you were asked to start and then stop performing printer discovery
336269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * in this session, then a subsequent discovering should not re-discover already
337773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * discovered printers. You can get the printers reported during this session by
338773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * calling {@link #getPrinters()}.
339798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
340798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
341269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * <strong>Note: </strong>You are also given a list of printers whose availability
342269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * has to be checked first. For example, these printers could be the user's favorite
343d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * ones, therefore they have to be verified first. You do <strong>not need</strong>
344d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * to provide the capabilities of the printers, rather verify whether they exist
345d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * similarly to {@link #onValidatePrinters(List)}.
346798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
347798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
348269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @param priorityList The list of printers to validate first. Never null.
349269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
350269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStopPrinterDiscovery()
351798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #addPrinters(List)
352798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * @see #removePrinters(List)
353269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isPrinterDiscoveryStarted()
354798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
355c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public abstract void onStartPrinterDiscovery(@NonNull List<PrinterId> priorityList);
356798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
357798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
358269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Callback notifying you that you should stop printer discovery.
359269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
360269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStartPrinterDiscovery(List)
361269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isPrinterDiscoveryStarted()
362798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
363269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public abstract void onStopPrinterDiscovery();
364798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
365798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    /**
366d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * Callback asking you to validate that the given printers are valid, that
367d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * is they exist. You are responsible for checking whether these printers
368d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * exist and for the ones that do exist notify the system via calling
369773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * {@link #addPrinters(List)}.
370d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <p>
371d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <strong>Note: </strong> You are <strong>not required</strong> to provide
372d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * the printer capabilities when updating the printers that do exist.
373d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <p>
374d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
375d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @param printerIds The printers to validate.
376d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
377c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann     * @see android.print.PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
378d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *      PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
379d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     */
380c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public abstract void onValidatePrinters(@NonNull List<PrinterId> printerIds);
381d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
382d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    /**
383d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * Callback asking you to start tracking the state of a printer. Tracking
384d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * the state means that you should do a best effort to observe the state
385d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * of this printer and notify the system if that state changes via calling
386773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * {@link #addPrinters(List)}.
387798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
388798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <strong>Note: </strong> A printer can be initially added without its
389798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * capabilities to avoid polling printers that the user will not select.
390798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * However, after this method is called you are expected to update the
391798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * printer <strong>including</strong> its capabilities. Otherwise, the
392798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * printer will be ignored.
393798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * <p>
394d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * <p>
395d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * A scenario when you may be requested to track a printer's state is if
396d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * the user selects that printer and the system has to present print
397d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * options UI based on the printer's capabilities. In this case the user
398d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * should be promptly informed if, for example, the printer becomes
399d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * unavailable.
400798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     * </p>
401798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
402d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @param printerId The printer to start tracking.
403798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *
404d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @see #onStopPrinterStateTracking(PrinterId)
405c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann     * @see android.print.PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
406798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     *      PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
407798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov     */
408c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public abstract void onStartPrinterStateTracking(@NonNull PrinterId printerId);
409d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
410d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    /**
411b99876416cb8e85c748914b7eb4096f7dc80ed2cPhilip P. Moltmann     * Called by the system to request the custom icon for a printer. Once the icon is available the
412b99876416cb8e85c748914b7eb4096f7dc80ed2cPhilip P. Moltmann     * print services uses {@link CustomPrinterIconCallback#onCustomPrinterIconLoaded} to send the
413b99876416cb8e85c748914b7eb4096f7dc80ed2cPhilip P. Moltmann     * icon to the system.
414bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
415bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param printerId The printer to icon belongs to.
416b99876416cb8e85c748914b7eb4096f7dc80ed2cPhilip P. Moltmann     * @param cancellationSignal Signal used to cancel the request.
417b99876416cb8e85c748914b7eb4096f7dc80ed2cPhilip P. Moltmann     * @param callback Callback for returning the icon to the system.
418bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
419b99876416cb8e85c748914b7eb4096f7dc80ed2cPhilip P. Moltmann     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon(boolean)
420bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
421bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    public void onRequestCustomPrinterIcon(@NonNull PrinterId printerId,
422e54d79c4cd6f90ccc6288df7a09d91698d603d9ePhilip P. Moltmann            @NonNull CancellationSignal cancellationSignal,
423bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            @NonNull CustomPrinterIconCallback callback) {
424bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
425bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
426bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
427d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * Callback asking you to stop tracking the state of a printer. The passed
428d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * in printer id is the one for which you received a call to {@link
429d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * #onStartPrinterStateTracking(PrinterId)}.
430d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
431d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @param printerId The printer to stop tracking.
432d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     *
433d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     * @see #onStartPrinterStateTracking(PrinterId)
434d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov     */
435c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public abstract void onStopPrinterStateTracking(@NonNull PrinterId printerId);
436798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
437269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
438773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * Gets the printers that should be tracked. These are printers that are
439773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * important to the user and for which you received a call to {@link
440773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * #onStartPrinterStateTracking(PrinterId)} asking you to observer their
441773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * state and reporting it to the system via {@link #addPrinters(List)}.
442773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * You will receive a call to {@link #onStopPrinterStateTracking(PrinterId)}
443773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * if you should stop tracking a printer.
444773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * <p>
445773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * <strong>Note: </strong> Calls to this method after the session is
446773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
447773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * </p>
448773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     *
449773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @return The printers.
450773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     *
451773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @see #onStartPrinterStateTracking(PrinterId)
452773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @see #onStopPrinterStateTracking(PrinterId)
453773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     * @see #isDestroyed()
454773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav     */
455c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    public final @NonNull List<PrinterId> getTrackedPrinters() {
456773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        PrintService.throwIfNotCalledOnMainThread();
457773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        if (mIsDestroyed) {
458773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            return Collections.emptyList();
459773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        }
460773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        return new ArrayList<PrinterId>(mTrackedPrinters);
461773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    }
462773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav
463773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav    /**
464269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Notifies you that the session is destroyed. After this callback is invoked
465269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * any calls to the methods of this class will be ignored, {@link #isDestroyed()}
466269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * will return true and you will also no longer receive callbacks.
467269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
468269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #isDestroyed()
469269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
470269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public abstract void onDestroy();
471798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
472269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
473269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Gets whether the session is destroyed.
474269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
475269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @return Whether the session is destroyed.
476269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
477269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onDestroy()
478269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
479269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public final boolean isDestroyed() {
480269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
481269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        return mIsDestroyed;
482269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
483798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
484269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    /**
485269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * Gets whether printer discovery is started.
486269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
487269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @return Whether printer discovery is destroyed.
488269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     *
489269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStartPrinterDiscovery(List)
490269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     * @see #onStopPrinterDiscovery()
491269403b032f965ff3847eb982c2f697229dc5a92Svetoslav     */
492269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public final boolean isPrinterDiscoveryStarted() {
493269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        PrintService.throwIfNotCalledOnMainThread();
494269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        return mIsDiscoveryStarted;
495269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
496798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
497c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    void startPrinterDiscovery(@NonNull List<PrinterId> priorityList) {
498269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mIsDestroyed) {
499269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDiscoveryStarted = true;
500269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            sendOutOfDiscoveryPeriodPrinterChanges();
501269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (priorityList == null) {
502269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                priorityList = Collections.emptyList();
503798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov            }
504269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            onStartPrinterDiscovery(priorityList);
505798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
506798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov    }
507798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
508269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void stopPrinterDiscovery() {
509269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mIsDestroyed) {
510269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDiscoveryStarted = false;
511269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            onStopPrinterDiscovery();
512798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
513269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
514798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
515c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    void validatePrinters(@NonNull List<PrinterId> printerIds) {
516d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        if (!mIsDestroyed && mObserver != null) {
517d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov            onValidatePrinters(printerIds);
518d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
519d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    }
520d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
521c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    void startPrinterStateTracking(@NonNull PrinterId printerId) {
522773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        if (!mIsDestroyed && mObserver != null
523773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                && !mTrackedPrinters.contains(printerId)) {
524773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav            mTrackedPrinters.add(printerId);
525d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov            onStartPrinterStateTracking(printerId);
526d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov        }
527d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov    }
528d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
529bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    /**
530bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * Request the custom icon for a printer.
531bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     *
532bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @param printerId The printer to icon belongs to.
533bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
534bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann     */
535c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    void requestCustomPrinterIcon(@NonNull PrinterId printerId) {
536bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        if (!mIsDestroyed && mObserver != null) {
537bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            CustomPrinterIconCallback callback = new CustomPrinterIconCallback(printerId,
538bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    mObserver);
539e54d79c4cd6f90ccc6288df7a09d91698d603d9ePhilip P. Moltmann            onRequestCustomPrinterIcon(printerId, new CancellationSignal(), callback);
540bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann        }
541bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    }
542bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
543c43639c3067dda5df189fb3cbf14f256c17e677dPhilip P. Moltmann    void stopPrinterStateTracking(@NonNull PrinterId printerId) {
544773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav        if (!mIsDestroyed && mObserver != null
545773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav                && mTrackedPrinters.remove(printerId)) {
546d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov            onStopPrinterStateTracking(printerId);
547798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
548269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
549798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov
550269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void destroy() {
551269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (!mIsDestroyed) {
552269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDestroyed = true;
553269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mIsDiscoveryStarted = false;
554269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mPrinters.clear();
555269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mLastSentPrinters = null;
556269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            mObserver = null;
557269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            onDestroy();
558798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov        }
559269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
560798bed6cc7d273e72b0253288605db9cd2b57740Svetoslav Ganov}
561