144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov/* 244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project 344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * 444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * you may not use this file except in compliance with the License. 644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * You may obtain a copy of the License at 744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * 844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * 1044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software 1144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 1244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * See the License for the specific language governing permissions and 1444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * limitations under the License. 1544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov */ 1644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovpackage android.print; 1844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmannimport android.annotation.NonNull; 2076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmannimport android.annotation.Nullable; 2144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.content.Context; 222fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.content.pm.ParceledListSlice; 2344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Handler; 2444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Looper; 2544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Message; 2644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.RemoteException; 2744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.util.ArrayMap; 2844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.util.Log; 2944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 3044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.lang.ref.WeakReference; 3144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.util.ArrayList; 3244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.util.Collections; 33cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganovimport java.util.LinkedHashMap; 3444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.util.List; 3544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 3644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov/** 3744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * @hide 3844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov */ 3944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovpublic final class PrinterDiscoverySession { 4044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 4144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final String LOG_TAG ="PrinterDiscoverySession"; 4244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 4344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final int MSG_PRINTERS_ADDED = 1; 4444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final int MSG_PRINTERS_REMOVED = 2; 4544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 46cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganov private final LinkedHashMap<PrinterId, PrinterInfo> mPrinters = 47cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganov new LinkedHashMap<PrinterId, PrinterInfo>(); 4844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 4944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final IPrintManager mPrintManager; 5044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final int mUserId; 5244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final Handler mHandler; 5444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private IPrinterDiscoveryObserver mObserver; 5644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private OnPrintersChangeListener mListener; 5844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private boolean mIsPrinterDiscoveryStarted; 6044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 6144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public static interface OnPrintersChangeListener { 6244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onPrintersChanged(); 6344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 6444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 6544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterDiscoverySession(IPrintManager printManager, Context context, int userId) { 6644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager = printManager; 6744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mUserId = userId; 6844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler = new SessionHandler(context.getMainLooper()); 6944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mObserver = new PrinterDiscoveryObserver(this); 7044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 7144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.createPrinterDiscoverySession(mObserver, mUserId); 7244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 7344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error creating printer discovery session", re); 7444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 7544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 7644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 7776d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann public final void startPrinterDiscovery(@Nullable List<PrinterId> priorityList) { 7844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 79a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.w(LOG_TAG, "Ignoring start printers discovery - session destroyed"); 80d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 8144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 8244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!mIsPrinterDiscoveryStarted) { 8344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mIsPrinterDiscoveryStarted = true; 8444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 8544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.startPrinterDiscovery(mObserver, priorityList, mUserId); 8644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 8744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error starting printer discovery", re); 8844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 8944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 9044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 9144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 9244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void stopPrinterDiscovery() { 9344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 9444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring stop printers discovery - session destroyed"); 95d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 9644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 9744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsPrinterDiscoveryStarted) { 9844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mIsPrinterDiscoveryStarted = false; 9944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 10044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.stopPrinterDiscovery(mObserver, mUserId); 10144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 10244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error stopping printer discovery", re); 10344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 10776d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann public final void startPrinterStateTracking(@NonNull PrinterId printerId) { 10844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 109d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring start printer state tracking - session destroyed"); 110d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 11144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 11244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 113d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrintManager.startPrinterStateTracking(printerId, mUserId); 11444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 115d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.e(LOG_TAG, "Error starting printer state tracking", re); 116d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 117d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 118d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 11976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann public final void stopPrinterStateTracking(@NonNull PrinterId printerId) { 120d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (isDestroyed()) { 121d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring stop printer state tracking - session destroyed"); 122d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 123d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 124d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov try { 125d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrintManager.stopPrinterStateTracking(printerId, mUserId); 126d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } catch (RemoteException re) { 127a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error stopping printer state tracking", re); 128d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 129d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 130d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 131d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public final void validatePrinters(List<PrinterId> printerIds) { 132d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (isDestroyed()) { 133d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring validate printers - session destroyed"); 134d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 135d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 136d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov try { 137d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrintManager.validatePrinters(printerIds, mUserId); 138d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } catch (RemoteException re) { 139d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.e(LOG_TAG, "Error validating printers", re); 14044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 14344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void destroy() { 14444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 14544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring destroy - session destroyed"); 14644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov destroyNoCheck(); 14844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 15044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final List<PrinterInfo> getPrinters() { 15144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 15244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring get printers - session destroyed"); 15344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return Collections.emptyList(); 15444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 15544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return new ArrayList<PrinterInfo>(mPrinters.values()); 15644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 15744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 15844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final boolean isDestroyed() { 15944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfNotCalledOnMainThread(); 16044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return isDestroyedNoCheck(); 16144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 16244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 16344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final boolean isPrinterDiscoveryStarted() { 16444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfNotCalledOnMainThread(); 16544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return mIsPrinterDiscoveryStarted; 16644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 16744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 16844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void setOnPrintersChangeListener(OnPrintersChangeListener listener) { 16944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfNotCalledOnMainThread(); 17044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mListener = listener; 17144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 17244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 17344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 17444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov protected final void finalize() throws Throwable { 17544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!isDestroyedNoCheck()) { 17644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Destroying leaked printer discovery session"); 17744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov destroyNoCheck(); 17844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 17944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov super.finalize(); 18044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 18144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 18244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private boolean isDestroyedNoCheck() { 18344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return (mObserver == null); 18444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 18544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 18644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void destroyNoCheck() { 18744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov stopPrinterDiscovery(); 18844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 18944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.destroyPrinterDiscoverySession(mObserver, mUserId); 19044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 19144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error destroying printer discovery session", re); 19244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } finally { 19344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mObserver = null; 19444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinters.clear(); 19544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 19644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 19744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 198c335eb411503154cf475903eb6c5c67575769112Svetoslav private void handlePrintersAdded(List<PrinterInfo> addedPrinters) { 19944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 20044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 20144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 202c335eb411503154cf475903eb6c5c67575769112Svetoslav 203c335eb411503154cf475903eb6c5c67575769112Svetoslav // No old printers - do not bother keeping their position. 204c335eb411503154cf475903eb6c5c67575769112Svetoslav if (mPrinters.isEmpty()) { 205c335eb411503154cf475903eb6c5c67575769112Svetoslav final int printerCount = addedPrinters.size(); 206c335eb411503154cf475903eb6c5c67575769112Svetoslav for (int i = 0; i < printerCount; i++) { 207c335eb411503154cf475903eb6c5c67575769112Svetoslav PrinterInfo printer = addedPrinters.get(i); 208c335eb411503154cf475903eb6c5c67575769112Svetoslav mPrinters.put(printer.getId(), printer); 20944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 21044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov notifyOnPrintersChanged(); 211c335eb411503154cf475903eb6c5c67575769112Svetoslav return; 21244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 213c335eb411503154cf475903eb6c5c67575769112Svetoslav 214c335eb411503154cf475903eb6c5c67575769112Svetoslav // Add the printers to a map. 215c335eb411503154cf475903eb6c5c67575769112Svetoslav ArrayMap<PrinterId, PrinterInfo> addedPrintersMap = 216c335eb411503154cf475903eb6c5c67575769112Svetoslav new ArrayMap<PrinterId, PrinterInfo>(); 217c335eb411503154cf475903eb6c5c67575769112Svetoslav final int printerCount = addedPrinters.size(); 218c335eb411503154cf475903eb6c5c67575769112Svetoslav for (int i = 0; i < printerCount; i++) { 219c335eb411503154cf475903eb6c5c67575769112Svetoslav PrinterInfo printer = addedPrinters.get(i); 220c335eb411503154cf475903eb6c5c67575769112Svetoslav addedPrintersMap.put(printer.getId(), printer); 221c335eb411503154cf475903eb6c5c67575769112Svetoslav } 222c335eb411503154cf475903eb6c5c67575769112Svetoslav 223c335eb411503154cf475903eb6c5c67575769112Svetoslav // Update printers we already have. 224cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganov for (PrinterId oldPrinterId : mPrinters.keySet()) { 225c335eb411503154cf475903eb6c5c67575769112Svetoslav PrinterInfo updatedPrinter = addedPrintersMap.remove(oldPrinterId); 226c335eb411503154cf475903eb6c5c67575769112Svetoslav if (updatedPrinter != null) { 227c335eb411503154cf475903eb6c5c67575769112Svetoslav mPrinters.put(oldPrinterId, updatedPrinter); 228c335eb411503154cf475903eb6c5c67575769112Svetoslav } 229c335eb411503154cf475903eb6c5c67575769112Svetoslav } 230c335eb411503154cf475903eb6c5c67575769112Svetoslav 231c335eb411503154cf475903eb6c5c67575769112Svetoslav // Add the new printers, i.e. what is left. 232c335eb411503154cf475903eb6c5c67575769112Svetoslav mPrinters.putAll(addedPrintersMap); 233c335eb411503154cf475903eb6c5c67575769112Svetoslav 234c335eb411503154cf475903eb6c5c67575769112Svetoslav // Announce the change. 235c335eb411503154cf475903eb6c5c67575769112Svetoslav notifyOnPrintersChanged(); 23644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 23744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 23844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handlePrintersRemoved(List<PrinterId> printerIds) { 23944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 24044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 24144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 24244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov boolean printersChanged = false; 24344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int removedPrinterIdCount = printerIds.size(); 24444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < removedPrinterIdCount; i++) { 24544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterId removedPrinterId = printerIds.get(i); 24644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinters.remove(removedPrinterId) != null) { 24744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov printersChanged = true; 24844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 24944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (printersChanged) { 25144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov notifyOnPrintersChanged(); 25244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 25544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void notifyOnPrintersChanged() { 25644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mListener != null) { 25744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mListener.onPrintersChanged(); 25844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 26044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 26144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static void throwIfNotCalledOnMainThread() { 26244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!Looper.getMainLooper().isCurrentThread()) { 26344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throw new IllegalAccessError("must be called from the main thread"); 26444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 26544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 26644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 26744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final class SessionHandler extends Handler { 26844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 26944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public SessionHandler(Looper looper) { 27044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov super(looper, null, false); 27144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 27244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 27344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 27444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @SuppressWarnings("unchecked") 27544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void handleMessage(Message message) { 27644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov switch (message.what) { 27744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_PRINTERS_ADDED: { 27844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> printers = (List<PrinterInfo>) message.obj; 27944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handlePrintersAdded(printers); 28044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 28144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 28244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_PRINTERS_REMOVED: { 28344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> printerIds = (List<PrinterId>) message.obj; 28444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handlePrintersRemoved(printerIds); 28544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 28644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 28744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 28844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 28944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29076d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann public static final class PrinterDiscoveryObserver extends IPrinterDiscoveryObserver.Stub { 29144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final WeakReference<PrinterDiscoverySession> mWeakSession; 29344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public PrinterDiscoveryObserver(PrinterDiscoverySession session) { 29544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mWeakSession = new WeakReference<PrinterDiscoverySession>(session); 29644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 29744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 2992fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav @SuppressWarnings("rawtypes") 3002fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void onPrintersAdded(ParceledListSlice printers) { 30144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterDiscoverySession session = mWeakSession.get(); 30244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (session != null) { 30344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov session.mHandler.obtainMessage(MSG_PRINTERS_ADDED, 3042fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printers.getList()).sendToTarget(); 30544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 30644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 30744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 30844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 3092fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav @SuppressWarnings("rawtypes") 3102fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void onPrintersRemoved(ParceledListSlice printerIds) { 31144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterDiscoverySession session = mWeakSession.get(); 31244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (session != null) { 31344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov session.mHandler.obtainMessage(MSG_PRINTERS_REMOVED, 3142fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printerIds.getList()).sendToTarget(); 31544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 31644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 31744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 31844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov} 319