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 1944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.content.Context; 202fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.content.pm.ParceledListSlice; 2144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Handler; 2244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Looper; 2344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Message; 2444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.RemoteException; 2544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.util.ArrayMap; 2644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.util.Log; 2744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 2844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.lang.ref.WeakReference; 2944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.util.ArrayList; 3044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.util.Collections; 31cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganovimport java.util.LinkedHashMap; 3244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport java.util.List; 3344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 3444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov/** 3544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov * @hide 3644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov */ 3744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovpublic final class PrinterDiscoverySession { 3844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 3944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final String LOG_TAG ="PrinterDiscoverySession"; 4044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 4144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final int MSG_PRINTERS_ADDED = 1; 4244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final int MSG_PRINTERS_REMOVED = 2; 4344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 44cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganov private final LinkedHashMap<PrinterId, PrinterInfo> mPrinters = 45cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganov new LinkedHashMap<PrinterId, PrinterInfo>(); 4644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 4744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final IPrintManager mPrintManager; 4844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 4944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final int mUserId; 5044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final Handler mHandler; 5244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private IPrinterDiscoveryObserver mObserver; 5444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private OnPrintersChangeListener mListener; 5644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private boolean mIsPrinterDiscoveryStarted; 5844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 5944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public static interface OnPrintersChangeListener { 6044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onPrintersChanged(); 6144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 6244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 6344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterDiscoverySession(IPrintManager printManager, Context context, int userId) { 6444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager = printManager; 6544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mUserId = userId; 6644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler = new SessionHandler(context.getMainLooper()); 6744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mObserver = new PrinterDiscoveryObserver(this); 6844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 6944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.createPrinterDiscoverySession(mObserver, mUserId); 7044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 7144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error creating printer discovery session", re); 7244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 7344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 7444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 75a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav public final void startPrinterDiscovery(List<PrinterId> priorityList) { 7644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 77a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.w(LOG_TAG, "Ignoring start printers discovery - session destroyed"); 78d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 7944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 8044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!mIsPrinterDiscoveryStarted) { 8144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mIsPrinterDiscoveryStarted = true; 8244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 8344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.startPrinterDiscovery(mObserver, priorityList, mUserId); 8444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 8544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error starting printer discovery", re); 8644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 8744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 8844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 8944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 9044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void stopPrinterDiscovery() { 9144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 9244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring stop printers discovery - session destroyed"); 93d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 9444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 9544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsPrinterDiscoveryStarted) { 9644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mIsPrinterDiscoveryStarted = false; 9744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 9844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.stopPrinterDiscovery(mObserver, mUserId); 9944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 10044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error stopping printer discovery", re); 10144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 105d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public final void startPrinterStateTracking(PrinterId printerId) { 10644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 107d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring start printer state tracking - session destroyed"); 108d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 10944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 11044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 111d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrintManager.startPrinterStateTracking(printerId, mUserId); 11244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 113d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.e(LOG_TAG, "Error starting printer state tracking", re); 114d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 115d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 116d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 117d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public final void stopPrinterStateTracking(PrinterId printerId) { 118d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (isDestroyed()) { 119d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring stop printer state tracking - session destroyed"); 120d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 121d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 122d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov try { 123d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrintManager.stopPrinterStateTracking(printerId, mUserId); 124d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } catch (RemoteException re) { 125a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav Log.e(LOG_TAG, "Error stopping printer state tracking", re); 126d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 127d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 128d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 129d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public final void validatePrinters(List<PrinterId> printerIds) { 130d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (isDestroyed()) { 131d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring validate printers - session destroyed"); 132d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 133d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 134d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov try { 135d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrintManager.validatePrinters(printerIds, mUserId); 136d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } catch (RemoteException re) { 137d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.e(LOG_TAG, "Error validating printers", re); 13844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 13944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 14144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void destroy() { 14244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 14344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring destroy - session destroyed"); 14444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov destroyNoCheck(); 14644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 14744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 14844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final List<PrinterInfo> getPrinters() { 14944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 15044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Ignoring get printers - session destroyed"); 15144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return Collections.emptyList(); 15244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 15344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return new ArrayList<PrinterInfo>(mPrinters.values()); 15444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 15544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 15644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final boolean isDestroyed() { 15744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfNotCalledOnMainThread(); 15844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return isDestroyedNoCheck(); 15944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 16044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 16144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final boolean isPrinterDiscoveryStarted() { 16244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfNotCalledOnMainThread(); 16344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return mIsPrinterDiscoveryStarted; 16444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 16544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 16644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void setOnPrintersChangeListener(OnPrintersChangeListener listener) { 16744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfNotCalledOnMainThread(); 16844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mListener = listener; 16944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 17044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 17144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 17244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov protected final void finalize() throws Throwable { 17344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!isDestroyedNoCheck()) { 17444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Destroying leaked printer discovery session"); 17544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov destroyNoCheck(); 17644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 17744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov super.finalize(); 17844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 17944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 18044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private boolean isDestroyedNoCheck() { 18144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return (mObserver == null); 18244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 18344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 18444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void destroyNoCheck() { 18544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov stopPrinterDiscovery(); 18644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 18744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrintManager.destroyPrinterDiscoverySession(mObserver, mUserId); 18844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 18944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error destroying printer discovery session", re); 19044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } finally { 19144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mObserver = null; 19244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinters.clear(); 19344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 19444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 19544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 196c335eb411503154cf475903eb6c5c67575769112Svetoslav private void handlePrintersAdded(List<PrinterInfo> addedPrinters) { 19744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 19844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 19944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 200c335eb411503154cf475903eb6c5c67575769112Svetoslav 201c335eb411503154cf475903eb6c5c67575769112Svetoslav // No old printers - do not bother keeping their position. 202c335eb411503154cf475903eb6c5c67575769112Svetoslav if (mPrinters.isEmpty()) { 203c335eb411503154cf475903eb6c5c67575769112Svetoslav final int printerCount = addedPrinters.size(); 204c335eb411503154cf475903eb6c5c67575769112Svetoslav for (int i = 0; i < printerCount; i++) { 205c335eb411503154cf475903eb6c5c67575769112Svetoslav PrinterInfo printer = addedPrinters.get(i); 206c335eb411503154cf475903eb6c5c67575769112Svetoslav mPrinters.put(printer.getId(), printer); 20744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 20844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov notifyOnPrintersChanged(); 209c335eb411503154cf475903eb6c5c67575769112Svetoslav return; 21044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 211c335eb411503154cf475903eb6c5c67575769112Svetoslav 212c335eb411503154cf475903eb6c5c67575769112Svetoslav // Add the printers to a map. 213c335eb411503154cf475903eb6c5c67575769112Svetoslav ArrayMap<PrinterId, PrinterInfo> addedPrintersMap = 214c335eb411503154cf475903eb6c5c67575769112Svetoslav new ArrayMap<PrinterId, PrinterInfo>(); 215c335eb411503154cf475903eb6c5c67575769112Svetoslav final int printerCount = addedPrinters.size(); 216c335eb411503154cf475903eb6c5c67575769112Svetoslav for (int i = 0; i < printerCount; i++) { 217c335eb411503154cf475903eb6c5c67575769112Svetoslav PrinterInfo printer = addedPrinters.get(i); 218c335eb411503154cf475903eb6c5c67575769112Svetoslav addedPrintersMap.put(printer.getId(), printer); 219c335eb411503154cf475903eb6c5c67575769112Svetoslav } 220c335eb411503154cf475903eb6c5c67575769112Svetoslav 221c335eb411503154cf475903eb6c5c67575769112Svetoslav // Update printers we already have. 222cfab2457f2c140a2356bb45ec25f51a0a5866556Svetoslav Ganov for (PrinterId oldPrinterId : mPrinters.keySet()) { 223c335eb411503154cf475903eb6c5c67575769112Svetoslav PrinterInfo updatedPrinter = addedPrintersMap.remove(oldPrinterId); 224c335eb411503154cf475903eb6c5c67575769112Svetoslav if (updatedPrinter != null) { 225c335eb411503154cf475903eb6c5c67575769112Svetoslav mPrinters.put(oldPrinterId, updatedPrinter); 226c335eb411503154cf475903eb6c5c67575769112Svetoslav } 227c335eb411503154cf475903eb6c5c67575769112Svetoslav } 228c335eb411503154cf475903eb6c5c67575769112Svetoslav 229c335eb411503154cf475903eb6c5c67575769112Svetoslav // Add the new printers, i.e. what is left. 230c335eb411503154cf475903eb6c5c67575769112Svetoslav mPrinters.putAll(addedPrintersMap); 231c335eb411503154cf475903eb6c5c67575769112Svetoslav 232c335eb411503154cf475903eb6c5c67575769112Svetoslav // Announce the change. 233c335eb411503154cf475903eb6c5c67575769112Svetoslav notifyOnPrintersChanged(); 23444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 23544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 23644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handlePrintersRemoved(List<PrinterId> printerIds) { 23744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (isDestroyed()) { 23844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 23944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 24044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov boolean printersChanged = false; 24144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int removedPrinterIdCount = printerIds.size(); 24244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < removedPrinterIdCount; i++) { 24344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterId removedPrinterId = printerIds.get(i); 24444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinters.remove(removedPrinterId) != null) { 24544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov printersChanged = true; 24644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 24744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 24844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (printersChanged) { 24944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov notifyOnPrintersChanged(); 25044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 25344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void notifyOnPrintersChanged() { 25444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mListener != null) { 25544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mListener.onPrintersChanged(); 25644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 25844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 25944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static void throwIfNotCalledOnMainThread() { 26044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!Looper.getMainLooper().isCurrentThread()) { 26144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throw new IllegalAccessError("must be called from the main thread"); 26244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 26344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 26444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 26544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final class SessionHandler extends Handler { 26644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 26744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public SessionHandler(Looper looper) { 26844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov super(looper, null, false); 26944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 27044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 27144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 27244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @SuppressWarnings("unchecked") 27344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void handleMessage(Message message) { 27444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov switch (message.what) { 27544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_PRINTERS_ADDED: { 27644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> printers = (List<PrinterInfo>) message.obj; 27744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handlePrintersAdded(printers); 27844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 27944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 28044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_PRINTERS_REMOVED: { 28144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> printerIds = (List<PrinterId>) message.obj; 28244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handlePrintersRemoved(printerIds); 28344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 28444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 28544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 28644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 28744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 28844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private static final class PrinterDiscoveryObserver extends IPrinterDiscoveryObserver.Stub { 28944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final WeakReference<PrinterDiscoverySession> mWeakSession; 29144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public PrinterDiscoveryObserver(PrinterDiscoverySession session) { 29344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mWeakSession = new WeakReference<PrinterDiscoverySession>(session); 29444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 29544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 29644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 2972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav @SuppressWarnings("rawtypes") 2982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void onPrintersAdded(ParceledListSlice printers) { 29944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterDiscoverySession session = mWeakSession.get(); 30044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (session != null) { 30144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov session.mHandler.obtainMessage(MSG_PRINTERS_ADDED, 3022fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printers.getList()).sendToTarget(); 30344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 30444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 30544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 30644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 3072fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav @SuppressWarnings("rawtypes") 3082fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void onPrintersRemoved(ParceledListSlice printerIds) { 30944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterDiscoverySession session = mWeakSession.get(); 31044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (session != null) { 31144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov session.mHandler.obtainMessage(MSG_PRINTERS_REMOVED, 3122fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printerIds.getList()).sendToTarget(); 31344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 31444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 31544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 31644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov} 317