1a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/* 2a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Copyright (C) 2013 The Android Open Source Project 3a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * 4a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 5a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * you may not use this file except in compliance with the License. 6a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * You may obtain a copy of the License at 7a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * 8a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 9a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * 10a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software 11a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 12a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * See the License for the specific language governing permissions and 14a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * limitations under the License. 15a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */ 16a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 17a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovpackage com.android.server.print; 18a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 197bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.app.PendingIntent; 20a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.ComponentName; 21a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Context; 22a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.Intent; 237bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.content.IntentSender; 24d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganovimport android.content.pm.ApplicationInfo; 25a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.pm.PackageManager; 262fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.content.pm.ParceledListSlice; 27a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.content.pm.ResolveInfo; 28d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganovimport android.content.pm.ServiceInfo; 297bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.net.Uri; 30c6066799ad130140159230d14451b429eb828755Svetoslavimport android.os.AsyncTask; 31c6066799ad130140159230d14451b429eb828755Svetoslavimport android.os.Binder; 327bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.os.Bundle; 3344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Handler; 3444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.IBinder; 352fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.os.IBinder.DeathRecipient; 3644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Looper; 3744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.Message; 3844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.RemoteCallbackList; 3944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.os.RemoteException; 404a82b455f9832430207e3ecfddfad4b67b071407Svetoslav Ganovimport android.os.UserHandle; 412fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.IPrintDocumentAdapter; 42704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport android.print.IPrintJobStateChangeListener; 4344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.print.IPrinterDiscoveryObserver; 442fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintAttributes; 452fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId; 46a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.PrintJobInfo; 47c6066799ad130140159230d14451b429eb828755Svetoslavimport android.print.PrintManager; 48269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterId; 4944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.print.PrinterInfo; 50a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.printservice.PrintServiceInfo; 517bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.provider.DocumentsContract; 52a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.provider.Settings; 53a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.text.TextUtils; 54a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.text.TextUtils.SimpleStringSplitter; 5544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.util.ArrayMap; 56b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport android.util.ArraySet; 5744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.util.Log; 58a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.Slog; 59dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganovimport android.util.SparseArray; 60a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 61c6066799ad130140159230d14451b429eb828755Svetoslavimport com.android.internal.R; 622fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport com.android.internal.os.BackgroundThread; 6344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport com.android.internal.os.SomeArgs; 64c6066799ad130140159230d14451b429eb828755Svetoslavimport com.android.server.print.RemotePrintService.PrintServiceCallbacks; 65a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks; 66a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 67b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor; 68b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter; 69a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.ArrayList; 70dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganovimport java.util.Collections; 71a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.HashSet; 72d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganovimport java.util.Iterator; 73a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.List; 74dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslavimport java.util.Map; 75a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport java.util.Set; 76a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 77a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov/** 78a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov * Represents the print state for a user. 79a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov */ 80c6066799ad130140159230d14451b429eb828755Svetoslavfinal class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks { 81a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 82a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final String LOG_TAG = "UserState"; 83a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 84c6066799ad130140159230d14451b429eb828755Svetoslav private static final boolean DEBUG = false; 8544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 86a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private static final char COMPONENT_NAME_SEPARATOR = ':'; 87a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 88a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final SimpleStringSplitter mStringColonSplitter = 89a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); 90a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 91a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Intent mQueryIntent = 92a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov new Intent(android.printservice.PrintService.SERVICE_INTERFACE); 93a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 94b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov private final ArrayMap<ComponentName, RemotePrintService> mActiveServices = 95b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov new ArrayMap<ComponentName, RemotePrintService>(); 96a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 97a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final List<PrintServiceInfo> mInstalledServices = 98a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov new ArrayList<PrintServiceInfo>(); 99a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 100a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Set<ComponentName> mEnabledServices = 101b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov new ArraySet<ComponentName>(); 102a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 103dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private final PrintJobForAppCache mPrintJobForAppCache = 104dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov new PrintJobForAppCache(); 1052fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 106a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Object mLock; 107a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 108a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final Context mContext; 109a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 110a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final int mUserId; 111a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 112a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private final RemotePrintSpooler mSpooler; 113a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 114704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private final Handler mHandler; 115704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 11644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private PrinterDiscoverySessionMediator mPrinterDiscoverySession; 11744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 118704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private List<PrintJobStateChangeListenerRecord> mPrintJobStateChangeListenerRecords; 119704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 120a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean mDestroyed; 121a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 122a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public UserState(Context context, int userId, Object lock) { 123a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mContext = context; 124a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mUserId = userId; 125a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mLock = lock; 126a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mSpooler = new RemotePrintSpooler(context, userId, this); 127704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mHandler = new UserStateHandler(context.getMainLooper()); 1286bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov synchronized (mLock) { 129564560e46d8a075fe508514f3dbd94f29963e6ebSvetoslav enableSystemPrintServicesLocked(); 130564560e46d8a075fe508514f3dbd94f29963e6ebSvetoslav onConfigurationChangedLocked(); 1316bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } 132a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 133a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 134a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 135a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onPrintJobQueued(PrintJobInfo printJob) { 136a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final RemotePrintService service; 137a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 138a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 1398c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov ComponentName printServiceName = printJob.getPrinterId().getServiceName(); 140a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov service = mActiveServices.get(printServiceName); 141a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 142a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (service != null) { 143a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov service.onPrintJobQueued(printJob); 144db85ad56adb74f0310b604228dac8bbc03ac2769Svetoslav Ganov } else { 145db85ad56adb74f0310b604228dac8bbc03ac2769Svetoslav Ganov // The service for the job is no longer enabled, so just 146db85ad56adb74f0310b604228dac8bbc03ac2769Svetoslav Ganov // fail the job with the appropriate message. 147db85ad56adb74f0310b604228dac8bbc03ac2769Svetoslav Ganov mSpooler.setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED, 148db85ad56adb74f0310b604228dac8bbc03ac2769Svetoslav Ganov mContext.getString(R.string.reason_service_unavailable)); 149a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 150a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 151a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 152a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov @Override 153a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void onAllPrintJobsForServiceHandled(ComponentName printService) { 154a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final RemotePrintService service; 155a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 156a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 157a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov service = mActiveServices.get(printService); 158a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 159a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (service != null) { 160a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov service.onAllPrintJobsHandled(); 161a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 162a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 163a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 1642fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void removeObsoletePrintJobs() { 1652fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mSpooler.removeObsoletePrintJobs(); 1662fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 1672fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 1687bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav @SuppressWarnings("deprecation") 1697bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav public Bundle print(String printJobName, IPrintDocumentAdapter adapter, 1707bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav PrintAttributes attributes, String packageName, int appId) { 1712fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav // Create print job place holder. 1722fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav final PrintJobInfo printJob = new PrintJobInfo(); 173dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJob.setId(new PrintJobId()); 1742fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printJob.setAppId(appId); 1752fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printJob.setLabel(printJobName); 1762fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printJob.setAttributes(attributes); 1772fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printJob.setState(PrintJobInfo.STATE_CREATED); 178704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov printJob.setCopies(1); 1797bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav printJob.setCreationTime(System.currentTimeMillis()); 1802fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 181dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Track this job so we can forget it when the creator dies. 1827bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav if (!mPrintJobForAppCache.onPrintJobCreated(adapter.asBinder(), appId, 183dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJob)) { 184dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Not adding a print job means the client is dead - done. 185dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return null; 186dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 187dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 1882fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav // Spin the spooler to add the job and show the config UI. 1892fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav new AsyncTask<Void, Void, Void>() { 1902fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav @Override 1912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav protected Void doInBackground(Void... params) { 1927bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav mSpooler.createPrintJob(printJob); 1932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return null; 1942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 1952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 1962fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 1977bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav final long identity = Binder.clearCallingIdentity(); 1987bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav try { 1997bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Intent intent = new Intent(PrintManager.ACTION_PRINT_DIALOG); 2007bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav intent.setData(Uri.fromParts("printjob", printJob.getId().flattenToString(), null)); 2017bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav intent.putExtra(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER, adapter.asBinder()); 2027bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav intent.putExtra(PrintManager.EXTRA_PRINT_JOB, printJob); 2037bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, packageName); 2047bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 2054a82b455f9832430207e3ecfddfad4b67b071407Svetoslav Ganov IntentSender intentSender = PendingIntent.getActivityAsUser( 2067bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT 207b0a78390ed834724e9c6adf0feff9931d7f9ec10Svetoslav | PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, 208b0a78390ed834724e9c6adf0feff9931d7f9ec10Svetoslav null, new UserHandle(mUserId)) .getIntentSender(); 2097bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 2107bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Bundle result = new Bundle(); 2117bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav result.putParcelable(PrintManager.EXTRA_PRINT_JOB, printJob); 2127bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav result.putParcelable(PrintManager.EXTRA_PRINT_DIALOG_INTENT, intentSender); 2137bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 2147bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav return result; 2157bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } finally { 2167bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav Binder.restoreCallingIdentity(identity); 2177bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 2182fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2192fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 2202fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public List<PrintJobInfo> getPrintJobInfos(int appId) { 221dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> cachedPrintJobs = mPrintJobForAppCache.getPrintJobs(appId); 222dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Note that the print spooler is not storing print jobs that 223dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // are in a terminal state as it is non-trivial to properly update 224dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // the spooler state for when to forget print jobs in terminal state. 225dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Therefore, we fuse the cached print jobs for running apps (some 226dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // jobs are in a terminal state) with the ones that the print 227dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // spooler knows about (some jobs are being processed). 228dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov ArrayMap<PrintJobId, PrintJobInfo> result = 229dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov new ArrayMap<PrintJobId, PrintJobInfo>(); 230dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 231dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Add the cached print jobs for running apps. 232dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int cachedPrintJobCount = cachedPrintJobs.size(); 233dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < cachedPrintJobCount; i++) { 234dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo cachedPrintJob = cachedPrintJobs.get(i); 235dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov result.put(cachedPrintJob.getId(), cachedPrintJob); 236b4fda134761c9521a7e127db3806a07a18763b77Svetoslav // Strip out the tag and the advanced print options. 237b4fda134761c9521a7e127db3806a07a18763b77Svetoslav // They are visible only to print services. 238b450d0d4d7fca16674fea02f15e21dc737352c40Svetoslav cachedPrintJob.setTag(null); 239b4fda134761c9521a7e127db3806a07a18763b77Svetoslav cachedPrintJob.setAdvancedOptions(null); 240dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 241dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 242dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov // Add everything else the spooler knows about. 243dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(null, 244dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo.STATE_ANY, appId); 245d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav if (printJobs != null) { 246d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav final int printJobCount = printJobs.size(); 247d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav for (int i = 0; i < printJobCount; i++) { 248d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav PrintJobInfo printJob = printJobs.get(i); 249d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav result.put(printJob.getId(), printJob); 250b4fda134761c9521a7e127db3806a07a18763b77Svetoslav // Strip out the tag and the advanced print options. 251b4fda134761c9521a7e127db3806a07a18763b77Svetoslav // They are visible only to print services. 252b450d0d4d7fca16674fea02f15e21dc737352c40Svetoslav printJob.setTag(null); 253b4fda134761c9521a7e127db3806a07a18763b77Svetoslav printJob.setAdvancedOptions(null); 254d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } 255dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 256dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 257dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return new ArrayList<PrintJobInfo>(result.values()); 2582fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2592fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 2602fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) { 261dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo printJob = mPrintJobForAppCache.getPrintJob(printJobId, appId); 262b4fda134761c9521a7e127db3806a07a18763b77Svetoslav if (printJob == null) { 263b4fda134761c9521a7e127db3806a07a18763b77Svetoslav printJob = mSpooler.getPrintJobInfo(printJobId, appId); 264b4fda134761c9521a7e127db3806a07a18763b77Svetoslav } 265dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJob != null) { 266b4fda134761c9521a7e127db3806a07a18763b77Svetoslav // Strip out the tag and the advanced print options. 267b4fda134761c9521a7e127db3806a07a18763b77Svetoslav // They are visible only to print services. 268b4fda134761c9521a7e127db3806a07a18763b77Svetoslav printJob.setTag(null); 269b4fda134761c9521a7e127db3806a07a18763b77Svetoslav printJob.setAdvancedOptions(null); 270dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 271b4fda134761c9521a7e127db3806a07a18763b77Svetoslav return printJob; 2722fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2732fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 2742fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void cancelPrintJob(PrintJobId printJobId, int appId) { 2752fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintJobInfo printJobInfo = mSpooler.getPrintJobInfo(printJobId, appId); 2762fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (printJobInfo == null) { 2772fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 2782fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 279a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 280a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov // Take a note that we are trying to cancel the job. 281a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov mSpooler.setPrintJobCancelling(printJobId, true); 282a18661d5922e5ae24ccce8e815aeba437a2fba82Svetoslav Ganov 2832fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) { 2842fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName(); 2852fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav RemotePrintService printService = null; 2862fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 2872fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printService = mActiveServices.get(printServiceName); 2882fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2892fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (printService == null) { 2902fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 2912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2922fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav printService.onRequestCancelPrintJob(printJobInfo); 2932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } else { 2942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav // If the print job is failed we do not need cooperation 2952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav // from the print service. 2962fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_CANCELED, null); 2972fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2982fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 2992fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 3002fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void restartPrintJob(PrintJobId printJobId, int appId) { 3012fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, appId); 3022fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) { 3032fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return; 3042fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 3052fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null); 3062fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 3072fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 308860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov public List<PrintServiceInfo> getEnabledPrintServices() { 309860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov synchronized (mLock) { 310860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov List<PrintServiceInfo> enabledServices = null; 311860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov final int installedServiceCount = mInstalledServices.size(); 312860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov for (int i = 0; i < installedServiceCount; i++) { 313860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov PrintServiceInfo installedService = mInstalledServices.get(i); 314860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov ComponentName componentName = new ComponentName( 315860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov installedService.getResolveInfo().serviceInfo.packageName, 316860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov installedService.getResolveInfo().serviceInfo.name); 317860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov if (mActiveServices.containsKey(componentName)) { 318860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov if (enabledServices == null) { 319860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov enabledServices = new ArrayList<PrintServiceInfo>(); 320860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 321860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov enabledServices.add(installedService); 322860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 323860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 324860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov return enabledServices; 325860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 326860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov } 327860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov 328d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav public List<PrintServiceInfo> getInstalledPrintServices() { 329d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav synchronized (mLock) { 330d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav return mInstalledServices; 331d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } 332d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav } 333d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav 33444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer) { 335a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized (mLock) { 336a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 337a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mActiveServices.isEmpty()) { 338a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return; 339a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 34044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 34144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // If we do not have a session, tell all service to create one. 34244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession = new PrinterDiscoverySessionMediator(mContext) { 34344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 34444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onDestroyed() { 34544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession = null; 34644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 34744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov }; 34844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Add the observer to the brand new session. 34944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.addObserverLocked(observer); 35044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } else { 35144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // If services have created session, just add the observer. 35244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.addObserverLocked(observer); 35344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 354a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 35544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 35644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 35744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer) { 35844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov synchronized (mLock) { 35944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Already destroyed - nothing to do. 36044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 36144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 36244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 36344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Remove this observer. 36444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.removeObserverLocked(observer); 365269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 366269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 367269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 36844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void startPrinterDiscovery(IPrinterDiscoveryObserver observer, 36944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> printerIds) { 370269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 371269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throwIfDestroyedLocked(); 37244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No services - nothing to do. 373269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mActiveServices.isEmpty()) { 374269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 375269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 37644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No session - nothing to do. 37744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 37844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 37944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 38044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Kick of discovery. 38144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.startPrinterDiscoveryLocked(observer, 38244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov printerIds); 383269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 384269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 385269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 38644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer) { 387269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 388269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throwIfDestroyedLocked(); 38944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No services - nothing to do. 390269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mActiveServices.isEmpty()) { 391269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 392269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 39344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No session - nothing to do. 39444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 39544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 39644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 39744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Kick of discovery. 39844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.stopPrinterDiscoveryLocked(observer); 399269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 400269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 401269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 402d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public void validatePrinters(List<PrinterId> printerIds) { 403269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 404269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throwIfDestroyedLocked(); 40544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No services - nothing to do. 406269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mActiveServices.isEmpty()) { 407269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 408269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 40944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No session - nothing to do. 41044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 41144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 41244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 41344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Request an updated. 414d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrinterDiscoverySession.validatePrintersLocked(printerIds); 415d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 416d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 417d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 418d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public void startPrinterStateTracking(PrinterId printerId) { 419d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov synchronized (mLock) { 420d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov throwIfDestroyedLocked(); 421d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // No services - nothing to do. 422d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mActiveServices.isEmpty()) { 423d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 424d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 425d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // No session - nothing to do. 426d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 427d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 428d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 429d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Request start tracking the printer. 430d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrinterDiscoverySession.startPrinterStateTrackingLocked(printerId); 431d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 432d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 433d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 434d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public void stopPrinterStateTracking(PrinterId printerId) { 435d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov synchronized (mLock) { 436d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov throwIfDestroyedLocked(); 437d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // No services - nothing to do. 438d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mActiveServices.isEmpty()) { 439d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 440d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 441d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // No session - nothing to do. 442d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 443d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 444d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 445d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Request stop tracking the printer. 446d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mPrinterDiscoverySession.stopPrinterStateTrackingLocked(printerId); 447269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 44844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 44944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 450704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener, 451704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov int appId) throws RemoteException { 452704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov synchronized (mLock) { 453704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov throwIfDestroyedLocked(); 454704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListenerRecords == null) { 455704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords = 456704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov new ArrayList<PrintJobStateChangeListenerRecord>(); 457704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 458704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords.add( 459704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov new PrintJobStateChangeListenerRecord(listener, appId) { 460704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 461704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void onBinderDied() { 462704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords.remove(this); 463704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 464704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov }); 465704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 466704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 467704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 468704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener) { 469704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov synchronized (mLock) { 470704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov throwIfDestroyedLocked(); 471704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListenerRecords == null) { 472704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return; 473704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 474704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final int recordCount = mPrintJobStateChangeListenerRecords.size(); 475704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov for (int i = 0; i < recordCount; i++) { 476704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobStateChangeListenerRecord record = 477704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords.get(i); 478704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (record.listener.asBinder().equals(listener.asBinder())) { 479704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords.remove(i); 480704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov break; 481704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 482704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 483704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListenerRecords.isEmpty()) { 484704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords = null; 485704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 486704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 487704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 488704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 489704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 490dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob) { 491dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mPrintJobForAppCache.onPrintJobStateChanged(printJob); 492704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mHandler.obtainMessage(UserStateHandler.MSG_DISPATCH_PRINT_JOB_STATE_CHANGED, 493dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJob.getAppId(), 0, printJob.getId()).sendToTarget(); 494704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 495704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 496c6066799ad130140159230d14451b429eb828755Svetoslav @Override 49744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onPrintersAdded(List<PrinterInfo> printers) { 49844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov synchronized (mLock) { 49944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov throwIfDestroyedLocked(); 50044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No services - nothing to do. 50144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mActiveServices.isEmpty()) { 50244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 50344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 50444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No session - nothing to do. 50544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 50644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 50744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 50844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.onPrintersAddedLocked(printers); 509269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 510269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 511269403b032f965ff3847eb982c2f697229dc5a92Svetoslav 512c6066799ad130140159230d14451b429eb828755Svetoslav @Override 51344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onPrintersRemoved(List<PrinterId> printerIds) { 514269403b032f965ff3847eb982c2f697229dc5a92Svetoslav synchronized (mLock) { 515269403b032f965ff3847eb982c2f697229dc5a92Svetoslav throwIfDestroyedLocked(); 51644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No services - nothing to do. 517269403b032f965ff3847eb982c2f697229dc5a92Svetoslav if (mActiveServices.isEmpty()) { 518269403b032f965ff3847eb982c2f697229dc5a92Svetoslav return; 519269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 52044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No session - nothing to do. 52144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession == null) { 52244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 52344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 52444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.onPrintersRemovedLocked(printerIds); 525269403b032f965ff3847eb982c2f697229dc5a92Svetoslav } 52644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 52744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 528c6066799ad130140159230d14451b429eb828755Svetoslav @Override 529c6066799ad130140159230d14451b429eb828755Svetoslav public void onServiceDied(RemotePrintService service) { 530c6066799ad130140159230d14451b429eb828755Svetoslav synchronized (mLock) { 531c6066799ad130140159230d14451b429eb828755Svetoslav throwIfDestroyedLocked(); 532c6066799ad130140159230d14451b429eb828755Svetoslav // No services - nothing to do. 533c6066799ad130140159230d14451b429eb828755Svetoslav if (mActiveServices.isEmpty()) { 534c6066799ad130140159230d14451b429eb828755Svetoslav return; 535c6066799ad130140159230d14451b429eb828755Svetoslav } 536c6066799ad130140159230d14451b429eb828755Svetoslav // Fail all print jobs. 537c6066799ad130140159230d14451b429eb828755Svetoslav failActivePrintJobsForService(service.getComponentName()); 538de4fa2dfe2e681c79e27d84604b9c48c68184aefSvetoslav Ganov service.onAllPrintJobsHandled(); 539c6066799ad130140159230d14451b429eb828755Svetoslav // No session - nothing to do. 540c6066799ad130140159230d14451b429eb828755Svetoslav if (mPrinterDiscoverySession == null) { 541c6066799ad130140159230d14451b429eb828755Svetoslav return; 542c6066799ad130140159230d14451b429eb828755Svetoslav } 543c6066799ad130140159230d14451b429eb828755Svetoslav mPrinterDiscoverySession.onServiceDiedLocked(service); 544c6066799ad130140159230d14451b429eb828755Svetoslav } 545c6066799ad130140159230d14451b429eb828755Svetoslav } 546c6066799ad130140159230d14451b429eb828755Svetoslav 547a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void updateIfNeededLocked() { 548a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 549a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (readConfigurationLocked()) { 550a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov onConfigurationChangedLocked(); 551a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 552a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 553a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 554a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public Set<ComponentName> getEnabledServices() { 555a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov synchronized(mLock) { 556a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 557a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return mEnabledServices; 558a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 559a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 560a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 561a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void destroyLocked() { 562a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throwIfDestroyedLocked(); 563a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mSpooler.destroy(); 564a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov for (RemotePrintService service : mActiveServices.values()) { 565a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov service.destroy(); 566a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 567a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mActiveServices.clear(); 568a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mInstalledServices.clear(); 569a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mEnabledServices.clear(); 57044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinterDiscoverySession != null) { 57144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession.destroyLocked(); 57244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mPrinterDiscoverySession = null; 57344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 574a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mDestroyed = true; 575a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 576a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 577b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov public void dump(FileDescriptor fd, PrintWriter pw, String prefix) { 578b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("user state ").append(String.valueOf(mUserId)).append(":"); 579b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.println(); 580b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 581b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov String tab = " "; 582b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 583b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("installed services:").println(); 584b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov final int installedServiceCount = mInstalledServices.size(); 585b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (int i = 0; i < installedServiceCount; i++) { 586b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov PrintServiceInfo installedService = mInstalledServices.get(i); 587b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov String installedServicePrefix = prefix + tab + tab; 588b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(installedServicePrefix).append("service:").println(); 589b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov ResolveInfo resolveInfo = installedService.getResolveInfo(); 590b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov ComponentName componentName = new ComponentName( 591b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov resolveInfo.serviceInfo.packageName, 592b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov resolveInfo.serviceInfo.name); 593b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(installedServicePrefix).append(tab).append("componentName=") 594b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(componentName.flattenToString()).println(); 595b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(installedServicePrefix).append(tab).append("settingsActivity=") 596b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(installedService.getSettingsActivityName()).println(); 597b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(installedServicePrefix).append(tab).append("addPrintersActivity=") 598b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(installedService.getAddPrintersActivityName()).println(); 599dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav pw.append(installedServicePrefix).append(tab).append("avancedOptionsActivity=") 600dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav .append(installedService.getAdvancedOptionsActivityName()).println(); 601b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 602b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 603b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("enabled services:").println(); 604b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (ComponentName enabledService : mEnabledServices) { 605b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov String enabledServicePrefix = prefix + tab + tab; 606b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(enabledServicePrefix).append("service:").println(); 607b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(enabledServicePrefix).append(tab).append("componentName=") 608b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(enabledService.flattenToString()); 609b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.println(); 610b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 611b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 612b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("active services:").println(); 613b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov final int activeServiceCount = mActiveServices.size(); 614b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (int i = 0; i < activeServiceCount; i++) { 615b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov RemotePrintService activeService = mActiveServices.valueAt(i); 616b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov activeService.dump(pw, prefix + tab + tab); 617b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.println(); 618b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 619b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 620dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append(tab).append("cached print jobs:").println(); 621dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mPrintJobForAppCache.dump(pw, prefix + tab + tab); 622dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 623b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("discovery mediator:").println(); 624b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov if (mPrinterDiscoverySession != null) { 625b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov mPrinterDiscoverySession.dump(pw, prefix + tab + tab); 626b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 627b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 628b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("print spooler:").println(); 629b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov mSpooler.dump(fd, pw, prefix + tab + tab); 630b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.println(); 631b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 632b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 633a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean readConfigurationLocked() { 634a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov boolean somethingChanged = false; 635a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov somethingChanged |= readInstalledPrintServicesLocked(); 636a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov somethingChanged |= readEnabledPrintServicesLocked(); 637a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return somethingChanged; 638a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 639a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 640a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean readInstalledPrintServicesLocked() { 641a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Set<PrintServiceInfo> tempPrintServices = new HashSet<PrintServiceInfo>(); 642a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 643a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov List<ResolveInfo> installedServices = mContext.getPackageManager() 644a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov .queryIntentServicesAsUser(mQueryIntent, PackageManager.GET_SERVICES 645a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov | PackageManager.GET_META_DATA, mUserId); 646a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 647a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int installedCount = installedServices.size(); 648a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov for (int i = 0, count = installedCount; i < count; i++) { 649a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ResolveInfo installedService = installedServices.get(i); 650a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (!android.Manifest.permission.BIND_PRINT_SERVICE.equals( 651a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov installedService.serviceInfo.permission)) { 652a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ComponentName serviceName = new ComponentName( 653a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov installedService.serviceInfo.packageName, 654a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov installedService.serviceInfo.name); 655a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Slog.w(LOG_TAG, "Skipping print service " 656a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov + serviceName.flattenToShortString() 657a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov + " since it does not require permission " 658a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov + android.Manifest.permission.BIND_PRINT_SERVICE); 659a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov continue; 660a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 661a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov tempPrintServices.add(PrintServiceInfo.create(installedService, mContext)); 662a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 663a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 6648ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav boolean someServiceChanged = false; 6658ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav 6668ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav if (tempPrintServices.size() != mInstalledServices.size()) { 6678ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav someServiceChanged = true; 6688ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav } else { 6698ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav for (PrintServiceInfo newService: tempPrintServices) { 6708ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav final int oldServiceIndex = mInstalledServices.indexOf(newService); 6718ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav if (oldServiceIndex < 0) { 6728ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav someServiceChanged = true; 6738ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav break; 6748ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav } 6758ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav // PrintServiceInfo#equals compares only the id not all members, 6768ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav // so we are also comparing the members coming from meta-data. 6778ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav PrintServiceInfo oldService = mInstalledServices.get(oldServiceIndex); 6788ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav if (!TextUtils.equals(oldService.getAddPrintersActivityName(), 6798ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav newService.getAddPrintersActivityName()) 6808ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav || !TextUtils.equals(oldService.getAdvancedOptionsActivityName(), 6818ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav newService.getAdvancedOptionsActivityName()) 6828ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav || !TextUtils.equals(oldService.getSettingsActivityName(), 6838ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav newService.getSettingsActivityName())) { 6848ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav someServiceChanged = true; 6858ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav break; 6868ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav } 6878ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav } 6888ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav } 6898ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav 6908ef0c14858de7a178aac2a5a38fe1651d3592d7fSvetoslav if (someServiceChanged) { 691a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mInstalledServices.clear(); 692a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov mInstalledServices.addAll(tempPrintServices); 693a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return true; 694a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 695a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 696a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return false; 697a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 698a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 699a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private boolean readEnabledPrintServicesLocked() { 700a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov Set<ComponentName> tempEnabledServiceNameSet = new HashSet<ComponentName>(); 7016bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov readPrintServicesFromSettingLocked(Settings.Secure.ENABLED_PRINT_SERVICES, 7026bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov tempEnabledServiceNameSet); 7036bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov if (!tempEnabledServiceNameSet.equals(mEnabledServices)) { 7046bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov mEnabledServices.clear(); 7056bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov mEnabledServices.addAll(tempEnabledServiceNameSet); 7066bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov return true; 7076bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } 7086bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov return false; 7096bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } 710a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 7116bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov private void readPrintServicesFromSettingLocked(String setting, 7126bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Set<ComponentName> outServiceNames) { 713a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(), 7146bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov setting, mUserId); 715a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (!TextUtils.isEmpty(settingValue)) { 716a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; 717a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov splitter.setString(settingValue); 718a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov while (splitter.hasNext()) { 719a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov String string = splitter.next(); 720a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (TextUtils.isEmpty(string)) { 721a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov continue; 722a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 723a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ComponentName componentName = ComponentName.unflattenFromString(string); 724a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (componentName != null) { 7256bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov outServiceNames.add(componentName); 726a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 727a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 728a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 729a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 730a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 731564560e46d8a075fe508514f3dbd94f29963e6ebSvetoslav private void enableSystemPrintServicesLocked() { 7326bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov // Load enabled and installed services. 7336bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov readEnabledPrintServicesLocked(); 7346bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov readInstalledPrintServicesLocked(); 735d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 7366bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov // Load the system services once enabled on first boot. 7376bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Set<ComponentName> enabledOnFirstBoot = new HashSet<ComponentName>(); 7386bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov readPrintServicesFromSettingLocked( 7396bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES, 7406bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov enabledOnFirstBoot); 741d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 7426bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov StringBuilder builder = new StringBuilder(); 743d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 7446bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov final int serviceCount = mInstalledServices.size(); 7456bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov for (int i = 0; i < serviceCount; i++) { 7466bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov ServiceInfo serviceInfo = mInstalledServices.get(i).getResolveInfo().serviceInfo; 7476bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov // Enable system print services if we never did that and are not enabled. 7486bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7496bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov ComponentName serviceName = new ComponentName( 7506bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov serviceInfo.packageName, serviceInfo.name); 7516bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov if (!mEnabledServices.contains(serviceName) 7526bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov && !enabledOnFirstBoot.contains(serviceName)) { 753d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (builder.length() > 0) { 754d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov builder.append(":"); 755d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 756d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov builder.append(serviceName.flattenToString()); 757d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 758d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 7596bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } 7606bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov 7616bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov // Nothing to be enabled - done. 7626bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov if (builder.length() <= 0) { 7636bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov return; 7646bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } 7656bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov 7666bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov String servicesToEnable = builder.toString(); 767d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 7686bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov // Update the enabled services setting. 7696bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov String enabledServices = Settings.Secure.getStringForUser( 7706bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov mContext.getContentResolver(), Settings.Secure.ENABLED_PRINT_SERVICES, mUserId); 7716bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov if (TextUtils.isEmpty(enabledServices)) { 7726bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov enabledServices = servicesToEnable; 7736bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } else { 7746bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov enabledServices = enabledServices + ":" + servicesToEnable; 7756bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } 7766bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Settings.Secure.putStringForUser(mContext.getContentResolver(), 7776bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Settings.Secure.ENABLED_PRINT_SERVICES, enabledServices, mUserId); 7786bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov 7796bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov // Update the enabled on first boot services setting. 7806bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov String enabledOnFirstBootServices = Settings.Secure.getStringForUser( 7816bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov mContext.getContentResolver(), 7826bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES, mUserId); 7836bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov if (TextUtils.isEmpty(enabledOnFirstBootServices)) { 7846bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov enabledOnFirstBootServices = servicesToEnable; 7856bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov } else { 7866bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov enabledOnFirstBootServices = enabledOnFirstBootServices + ":" + enabledServices; 787d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 7886bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Settings.Secure.putStringForUser(mContext.getContentResolver(), 7896bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES, 7906bd20bc46c762860cac852888df5adf718f2be24Svetoslav Ganov enabledOnFirstBootServices, mUserId); 791d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 792d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 793a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void onConfigurationChangedLocked() { 794dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav Set<ComponentName> installedComponents = new ArraySet<ComponentName>(); 795dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav 796a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov final int installedCount = mInstalledServices.size(); 797a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov for (int i = 0; i < installedCount; i++) { 798a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ResolveInfo resolveInfo = mInstalledServices.get(i).getResolveInfo(); 799a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov ComponentName serviceName = new ComponentName(resolveInfo.serviceInfo.packageName, 800a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov resolveInfo.serviceInfo.name); 801dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav 802dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav installedComponents.add(serviceName); 803dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav 804a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mEnabledServices.contains(serviceName)) { 805a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (!mActiveServices.containsKey(serviceName)) { 80644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = new RemotePrintService( 80744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mContext, serviceName, mUserId, mSpooler, this); 808c6066799ad130140159230d14451b429eb828755Svetoslav addServiceLocked(service); 809a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 810a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } else { 811a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov RemotePrintService service = mActiveServices.remove(serviceName); 812a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (service != null) { 813c6066799ad130140159230d14451b429eb828755Svetoslav removeServiceLocked(service); 814a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 815a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 816a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 817dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav 818dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav Iterator<Map.Entry<ComponentName, RemotePrintService>> iterator = 819dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav mActiveServices.entrySet().iterator(); 820dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav while (iterator.hasNext()) { 821dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav Map.Entry<ComponentName, RemotePrintService> entry = iterator.next(); 822dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav ComponentName serviceName = entry.getKey(); 823dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav RemotePrintService service = entry.getValue(); 824dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav if (!installedComponents.contains(serviceName)) { 825dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav removeServiceLocked(service); 826dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav iterator.remove(); 827dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav } 828dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav } 829a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 830a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 831c6066799ad130140159230d14451b429eb828755Svetoslav private void addServiceLocked(RemotePrintService service) { 832c6066799ad130140159230d14451b429eb828755Svetoslav mActiveServices.put(service.getComponentName(), service); 833c6066799ad130140159230d14451b429eb828755Svetoslav if (mPrinterDiscoverySession != null) { 834c6066799ad130140159230d14451b429eb828755Svetoslav mPrinterDiscoverySession.onServiceAddedLocked(service); 835c6066799ad130140159230d14451b429eb828755Svetoslav } 836c6066799ad130140159230d14451b429eb828755Svetoslav } 837c6066799ad130140159230d14451b429eb828755Svetoslav 838c6066799ad130140159230d14451b429eb828755Svetoslav private void removeServiceLocked(RemotePrintService service) { 839c6066799ad130140159230d14451b429eb828755Svetoslav // Fail all print jobs. 840c6066799ad130140159230d14451b429eb828755Svetoslav failActivePrintJobsForService(service.getComponentName()); 841c6066799ad130140159230d14451b429eb828755Svetoslav // If discovery is in progress, tear down the service. 842c6066799ad130140159230d14451b429eb828755Svetoslav if (mPrinterDiscoverySession != null) { 843c6066799ad130140159230d14451b429eb828755Svetoslav mPrinterDiscoverySession.onServiceRemovedLocked(service); 844c6066799ad130140159230d14451b429eb828755Svetoslav } else { 845c6066799ad130140159230d14451b429eb828755Svetoslav // Otherwise, just destroy it. 846c6066799ad130140159230d14451b429eb828755Svetoslav service.destroy(); 847c6066799ad130140159230d14451b429eb828755Svetoslav } 848c6066799ad130140159230d14451b429eb828755Svetoslav } 849c6066799ad130140159230d14451b429eb828755Svetoslav 850c6066799ad130140159230d14451b429eb828755Svetoslav private void failActivePrintJobsForService(final ComponentName serviceName) { 851c6066799ad130140159230d14451b429eb828755Svetoslav // Makes sure all active print jobs are failed since the service 852c6066799ad130140159230d14451b429eb828755Svetoslav // just died. Do this off the main thread since we do to allow 853c6066799ad130140159230d14451b429eb828755Svetoslav // calls into the spooler on the main thread. 854c6066799ad130140159230d14451b429eb828755Svetoslav if (Looper.getMainLooper().isCurrentThread()) { 8552fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav BackgroundThread.getHandler().post(new Runnable() { 856c6066799ad130140159230d14451b429eb828755Svetoslav @Override 8572fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void run() { 8589b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov failScheduledPrintJobsForServiceInternal(serviceName); 859c6066799ad130140159230d14451b429eb828755Svetoslav } 8602fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav }); 861c6066799ad130140159230d14451b429eb828755Svetoslav } else { 8629b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov failScheduledPrintJobsForServiceInternal(serviceName); 863c6066799ad130140159230d14451b429eb828755Svetoslav } 864c6066799ad130140159230d14451b429eb828755Svetoslav } 865c6066799ad130140159230d14451b429eb828755Svetoslav 8669b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov private void failScheduledPrintJobsForServiceInternal(ComponentName serviceName) { 867c6066799ad130140159230d14451b429eb828755Svetoslav List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(serviceName, 8689b6d3a153f44010a75907c6a9742c89a57d4e5eeSvetoslav Ganov PrintJobInfo.STATE_ANY_SCHEDULED, PrintManager.APP_ID_ANY); 869c6066799ad130140159230d14451b429eb828755Svetoslav if (printJobs == null) { 870c6066799ad130140159230d14451b429eb828755Svetoslav return; 871c6066799ad130140159230d14451b429eb828755Svetoslav } 872c6066799ad130140159230d14451b429eb828755Svetoslav final long identity = Binder.clearCallingIdentity(); 873c6066799ad130140159230d14451b429eb828755Svetoslav try { 874c6066799ad130140159230d14451b429eb828755Svetoslav final int printJobCount = printJobs.size(); 875c6066799ad130140159230d14451b429eb828755Svetoslav for (int i = 0; i < printJobCount; i++) { 876c6066799ad130140159230d14451b429eb828755Svetoslav PrintJobInfo printJob = printJobs.get(i); 877c6066799ad130140159230d14451b429eb828755Svetoslav mSpooler.setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED, 878db85ad56adb74f0310b604228dac8bbc03ac2769Svetoslav Ganov mContext.getString(R.string.reason_service_unavailable)); 879c6066799ad130140159230d14451b429eb828755Svetoslav } 880c6066799ad130140159230d14451b429eb828755Svetoslav } finally { 881c6066799ad130140159230d14451b429eb828755Svetoslav Binder.restoreCallingIdentity(identity); 882c6066799ad130140159230d14451b429eb828755Svetoslav } 883c6066799ad130140159230d14451b429eb828755Svetoslav } 884c6066799ad130140159230d14451b429eb828755Svetoslav 885a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov private void throwIfDestroyedLocked() { 886a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov if (mDestroyed) { 887a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov throw new IllegalStateException("Cannot interact with a destroyed instance."); 888a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 889a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 890a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 891704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private void handleDispatchPrintJobStateChanged(PrintJobId printJobId, int appId) { 892704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final List<PrintJobStateChangeListenerRecord> records; 893704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov synchronized (mLock) { 894704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (mPrintJobStateChangeListenerRecords == null) { 895704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov return; 896704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 897704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov records = new ArrayList<PrintJobStateChangeListenerRecord>( 898704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov mPrintJobStateChangeListenerRecords); 899704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 900704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final int recordCount = records.size(); 901704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov for (int i = 0; i < recordCount; i++) { 902704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobStateChangeListenerRecord record = records.get(i); 903704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (record.appId == PrintManager.APP_ID_ANY 904704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov || record.appId == appId) 905704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov try { 906704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov record.listener.onPrintJobStateChanged(printJobId); 907704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } catch (RemoteException re) { 908704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov Log.e(LOG_TAG, "Error notifying for print job state change", re); 909704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 910704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 911704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 912704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 913704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private final class UserStateHandler extends Handler { 914704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public static final int MSG_DISPATCH_PRINT_JOB_STATE_CHANGED = 1; 915704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 916704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public UserStateHandler(Looper looper) { 917704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov super(looper, null, false); 918704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 919704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 920704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 921704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void handleMessage(Message message) { 922704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov if (message.what == MSG_DISPATCH_PRINT_JOB_STATE_CHANGED) { 923704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov PrintJobId printJobId = (PrintJobId) message.obj; 924704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final int appId = message.arg1; 925704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov handleDispatchPrintJobStateChanged(printJobId, appId); 926704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 927704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 928704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 929704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 930704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov private abstract class PrintJobStateChangeListenerRecord implements DeathRecipient { 931704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final IPrintJobStateChangeListener listener; 932704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov final int appId; 933704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 934704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public PrintJobStateChangeListenerRecord(IPrintJobStateChangeListener listener, 935704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov int appId) throws RemoteException { 936704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov this.listener = listener; 937704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov this.appId = appId; 938704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov listener.asBinder().linkToDeath(this, 0); 939704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 940704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 941704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov @Override 942704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public void binderDied() { 943704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov listener.asBinder().unlinkToDeath(this, 0); 944704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov onBinderDied(); 945704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 946704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 947704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov public abstract void onBinderDied(); 948704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 949704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 95044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private class PrinterDiscoverySessionMediator { 95144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final ArrayMap<PrinterId, PrinterInfo> mPrinters = 95244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov new ArrayMap<PrinterId, PrinterInfo>(); 95344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 95444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final RemoteCallbackList<IPrinterDiscoveryObserver> mDiscoveryObservers = 95544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov new RemoteCallbackList<IPrinterDiscoveryObserver>() { 95644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 95744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onCallbackDied(IPrinterDiscoveryObserver observer) { 95844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov synchronized (mLock) { 95944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov stopPrinterDiscoveryLocked(observer); 96044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov removeObserverLocked(observer); 96144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 96244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 96344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov }; 96444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 96544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final List<IBinder> mStartedPrinterDiscoveryTokens = new ArrayList<IBinder>(); 96644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 967d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private final List<PrinterId> mStateTrackedPrinters = new ArrayList<PrinterId>(); 968d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 96944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final Handler mHandler; 97044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 97144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private boolean mIsDestroyed; 97244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 97344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public PrinterDiscoverySessionMediator(Context context) { 97444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler = new SessionHandler(context.getMainLooper()); 97544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Kick off the session creation. 97644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = new ArrayList<RemotePrintService>( 97744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mActiveServices.values()); 97844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 97944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION, services) 98044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .sendToTarget(); 98144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 98244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 98344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void addObserverLocked(IPrinterDiscoveryObserver observer) { 98444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Add the observer. 98544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mDiscoveryObservers.register(observer); 98644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 98744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Bring the added observer up to speed with the printers. 98844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!mPrinters.isEmpty()) { 98944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> printers = new ArrayList<PrinterInfo>(mPrinters.values()); 99044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SomeArgs args = SomeArgs.obtain(); 99144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.arg1 = observer; 99244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.arg2 = printers; 99344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler.MSG_PRINTERS_ADDED, 99444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args).sendToTarget(); 99544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 99644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 99744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 99844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void removeObserverLocked(IPrinterDiscoveryObserver observer) { 99944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Remove the observer. 100044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mDiscoveryObservers.unregister(observer); 100144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // No one else observing - then kill it. 100244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mDiscoveryObservers.getRegisteredCallbackCount() == 0) { 100344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov destroyLocked(); 100444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 100544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 100644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 100744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void startPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer, 100844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> priorityList) { 100944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 101044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not starting dicovery - session destroyed"); 101144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 101244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 101344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1014c6066799ad130140159230d14451b429eb828755Svetoslav final boolean discoveryStarted = !mStartedPrinterDiscoveryTokens.isEmpty(); 1015c6066799ad130140159230d14451b429eb828755Svetoslav 1016c6066799ad130140159230d14451b429eb828755Svetoslav // Remember we got a start request to match with an end. 1017c6066799ad130140159230d14451b429eb828755Svetoslav mStartedPrinterDiscoveryTokens.add(observer.asBinder()); 1018c6066799ad130140159230d14451b429eb828755Svetoslav 101944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // If printer discovery is ongoing and the start request has a list 1020d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // of printer to be checked, then we just request validating them. 1021c6066799ad130140159230d14451b429eb828755Svetoslav if (discoveryStarted && priorityList != null && !priorityList.isEmpty()) { 1022d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov validatePrinters(priorityList); 102344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 102444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 102544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 102644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // The service are already performing discovery - nothing to do. 102744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mStartedPrinterDiscoveryTokens.size() > 1) { 102844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 102944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 10309186d0cb2bd325d9b52da15dbd513937c1e42caaSvetoslav Ganov 103144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = new ArrayList<RemotePrintService>( 103244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mActiveServices.values()); 103344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SomeArgs args = SomeArgs.obtain(); 103444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.arg1 = services; 103544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.arg2 = priorityList; 103644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 103744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .MSG_DISPATCH_START_PRINTER_DISCOVERY, args) 103844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .sendToTarget(); 103944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 104044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 104144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public final void stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer) { 104244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 104344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not stopping dicovery - session destroyed"); 104444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 104544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 104644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // This one did not make an active discovery request - nothing to do. 104744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!mStartedPrinterDiscoveryTokens.remove(observer.asBinder())) { 104844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 104944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 105044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // There are other interested observers - do not stop discovery. 105144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (!mStartedPrinterDiscoveryTokens.isEmpty()) { 105244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 105344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 105444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = new ArrayList<RemotePrintService>( 105544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mActiveServices.values()); 105644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 105744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .MSG_DISPATCH_STOP_PRINTER_DISCOVERY, services) 105844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .sendToTarget(); 105944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 106044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1061d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public void validatePrintersLocked(List<PrinterId> printerIds) { 106244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 1063d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Not validating pritners - session destroyed"); 106444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 106544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 1066d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1067d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov List<PrinterId> remainingList = new ArrayList<PrinterId>(printerIds); 1068d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov while (!remainingList.isEmpty()) { 1069d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Iterator<PrinterId> iterator = remainingList.iterator(); 1070d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Gather the printers per service and request a validation. 1071d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov List<PrinterId> updateList = new ArrayList<PrinterId>(); 1072d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov ComponentName serviceName = null; 1073d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov while (iterator.hasNext()) { 1074d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov PrinterId printerId = iterator.next(); 1075d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (updateList.isEmpty()) { 1076d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov updateList.add(printerId); 1077d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov serviceName = printerId.getServiceName(); 1078d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov iterator.remove(); 1079d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } else if (printerId.getServiceName().equals(serviceName)) { 1080d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov updateList.add(printerId); 1081d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov iterator.remove(); 1082d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1083d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1084d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Schedule a notification of the service. 1085d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov RemotePrintService service = mActiveServices.get(serviceName); 1086d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (service != null) { 1087d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov SomeArgs args = SomeArgs.obtain(); 1088d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.arg1 = service; 1089d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.arg2 = updateList; 1090d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 1091d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov .MSG_VALIDATE_PRINTERS, args) 1092d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov .sendToTarget(); 1093d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1094d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1095d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1096d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1097d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public final void startPrinterStateTrackingLocked(PrinterId printerId) { 1098d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mIsDestroyed) { 1099d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Not starting printer state tracking - session destroyed"); 1100d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1101d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1102d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // If printer discovery is not started - nothing to do. 1103d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mStartedPrinterDiscoveryTokens.isEmpty()) { 1104d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1105d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1106d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov final boolean containedPrinterId = mStateTrackedPrinters.contains(printerId); 1107d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Keep track of the number of requests to track this one. 1108d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mStateTrackedPrinters.add(printerId); 1109d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // If we were tracking this printer - nothing to do. 1110d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (containedPrinterId) { 1111d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1112d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1113d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // No service - nothing to do. 111444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = mActiveServices.get(printerId.getServiceName()); 1115d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (service == null) { 1116d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 111744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 1118d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Ask the service to start tracking. 1119d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov SomeArgs args = SomeArgs.obtain(); 1120d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.arg1 = service; 1121d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.arg2 = printerId; 1122d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 1123d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov .MSG_START_PRINTER_STATE_TRACKING, args) 1124d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov .sendToTarget(); 1125d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1126d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1127d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov public final void stopPrinterStateTrackingLocked(PrinterId printerId) { 1128d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mIsDestroyed) { 1129d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov Log.w(LOG_TAG, "Not stopping printer state tracking - session destroyed"); 1130d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1131d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1132d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // If printer discovery is not started - nothing to do. 1133d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (mStartedPrinterDiscoveryTokens.isEmpty()) { 1134d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1135d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1136d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // If we did not track this printer - nothing to do. 1137d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (!mStateTrackedPrinters.remove(printerId)) { 1138d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1139d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1140d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // No service - nothing to do. 1141d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov RemotePrintService service = mActiveServices.get(printerId.getServiceName()); 1142d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov if (service == null) { 1143d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov return; 1144d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1145d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Ask the service to start tracking. 1146d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov SomeArgs args = SomeArgs.obtain(); 1147d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.arg1 = service; 1148d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.arg2 = printerId; 1149d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 1150d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov .MSG_STOP_PRINTER_STATE_TRACKING, args) 1151d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov .sendToTarget(); 115244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 115344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 115444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onDestroyed() { 115544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov /* do nothing */ 115644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 115744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 115844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void destroyLocked() { 115944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 116044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not destroying - session destroyed"); 116144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 116244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 1163564560e46d8a075fe508514f3dbd94f29963e6ebSvetoslav mIsDestroyed = true; 1164d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov // Make sure printer tracking is stopped. 1165d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov final int printerCount = mStateTrackedPrinters.size(); 1166d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov for (int i = 0; i < printerCount; i++) { 1167d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov PrinterId printerId = mStateTrackedPrinters.get(i); 1168d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov stopPrinterStateTracking(printerId); 1169d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 117044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Make sure discovery is stopped. 117144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int observerCount = mStartedPrinterDiscoveryTokens.size(); 117244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < observerCount; i++) { 117344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov IBinder token = mStartedPrinterDiscoveryTokens.get(i); 117444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver.Stub.asInterface(token)); 117544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 117644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Tell the services we are done. 117744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = new ArrayList<RemotePrintService>( 117844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mActiveServices.values()); 117944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler 118044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION, services) 118144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov .sendToTarget(); 118244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 118344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 118444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onPrintersAddedLocked(List<PrinterInfo> printers) { 118544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (DEBUG) { 118644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.i(LOG_TAG, "onPrintersAddedLocked()"); 118744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 118844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 118944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not adding printers - session destroyed"); 119044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 119144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 119244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> addedPrinters = null; 119344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int addedPrinterCount = printers.size(); 119444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < addedPrinterCount; i++) { 119544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterInfo printer = printers.get(i); 1196773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav PrinterInfo oldPrinter = mPrinters.put(printer.getId(), printer); 1197773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav if (oldPrinter == null || !oldPrinter.equals(printer)) { 119844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (addedPrinters == null) { 119944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov addedPrinters = new ArrayList<PrinterInfo>(); 120044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 120144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov addedPrinters.add(printer); 120244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 120344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 120444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (addedPrinters != null) { 120544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_ADDED, 120644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov addedPrinters).sendToTarget(); 120744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 120844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 120944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 121044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onPrintersRemovedLocked(List<PrinterId> printerIds) { 121144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (DEBUG) { 121244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.i(LOG_TAG, "onPrintersRemovedLocked()"); 121344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 121444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 121544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not removing printers - session destroyed"); 121644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 121744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 121844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> removedPrinterIds = null; 121944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int removedPrinterCount = printerIds.size(); 122044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < removedPrinterCount; i++) { 122144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterId removedPrinterId = printerIds.get(i); 122244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mPrinters.remove(removedPrinterId) != null) { 122344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (removedPrinterIds == null) { 122444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov removedPrinterIds = new ArrayList<PrinterId>(); 122544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 122644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov removedPrinterIds.add(removedPrinterId); 122744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 122844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 122944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (removedPrinterIds != null) { 123044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED, 123144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov removedPrinterIds).sendToTarget(); 123244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 123344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 123444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1235c6066799ad130140159230d14451b429eb828755Svetoslav public void onServiceRemovedLocked(RemotePrintService service) { 123644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 123744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not updating removed service - session destroyed"); 123844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 123944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 1240c6066799ad130140159230d14451b429eb828755Svetoslav // Remove the reported and tracked printers for that service. 1241c6066799ad130140159230d14451b429eb828755Svetoslav ComponentName serviceName = service.getComponentName(); 1242c6066799ad130140159230d14451b429eb828755Svetoslav removePrintersForServiceLocked(serviceName); 1243c6066799ad130140159230d14451b429eb828755Svetoslav service.destroy(); 1244c6066799ad130140159230d14451b429eb828755Svetoslav } 1245c6066799ad130140159230d14451b429eb828755Svetoslav 1246c6066799ad130140159230d14451b429eb828755Svetoslav public void onServiceDiedLocked(RemotePrintService service) { 1247c6066799ad130140159230d14451b429eb828755Svetoslav // Remove the reported by that service. 1248c6066799ad130140159230d14451b429eb828755Svetoslav removePrintersForServiceLocked(service.getComponentName()); 124944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 125044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 125144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void onServiceAddedLocked(RemotePrintService service) { 125244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov if (mIsDestroyed) { 125344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.w(LOG_TAG, "Not updating added service - session destroyed"); 125444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov return; 125544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 125644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov // Tell the service to create a session. 125744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage( 125844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SessionHandler.MSG_CREATE_PRINTER_DISCOVERY_SESSION, 125944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service).sendToTarget(); 1260b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav // Start printer discovery if necessary. 1261b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav if (!mStartedPrinterDiscoveryTokens.isEmpty()) { 126244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mHandler.obtainMessage( 126344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SessionHandler.MSG_START_PRINTER_DISCOVERY, 126444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service).sendToTarget(); 126544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 1266b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav // Start tracking printers if necessary 1267b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav final int trackedPrinterCount = mStateTrackedPrinters.size(); 1268b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav for (int i = 0; i < trackedPrinterCount; i++) { 1269b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav PrinterId printerId = mStateTrackedPrinters.get(i); 1270b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav if (printerId.getServiceName().equals(service.getComponentName())) { 1271b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav SomeArgs args = SomeArgs.obtain(); 1272b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav args.arg1 = service; 1273b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav args.arg2 = printerId; 1274b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav mHandler.obtainMessage(SessionHandler 1275b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav .MSG_START_PRINTER_STATE_TRACKING, args) 1276b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav .sendToTarget(); 1277b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav } 1278b5f180608db6de123b54ae94de569ff1ebca705cSvetoslav } 127944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 128044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1281b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov public void dump(PrintWriter pw, String prefix) { 1282b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("destroyed=") 1283b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(String.valueOf(mDestroyed)).println(); 1284b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1285b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append("printDiscoveryInProgress=") 1286b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov .append(String.valueOf(!mStartedPrinterDiscoveryTokens.isEmpty())).println(); 1287b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1288b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov String tab = " "; 1289b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1290b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("printer discovery observers:").println(); 1291b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov final int observerCount = mDiscoveryObservers.beginBroadcast(); 1292b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (int i = 0; i < observerCount; i++) { 1293b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i); 1294b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(prefix).append(observer.toString()); 1295b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.println(); 1296b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 1297b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov mDiscoveryObservers.finishBroadcast(); 1298b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1299b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("start discovery requests:").println(); 1300b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov final int tokenCount = this.mStartedPrinterDiscoveryTokens.size(); 1301b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (int i = 0; i < tokenCount; i++) { 1302b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov IBinder token = mStartedPrinterDiscoveryTokens.get(i); 1303b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append(tab).append(token.toString()).println(); 1304b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 1305b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1306b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("tracked printer requests:").println(); 1307b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov final int trackedPrinters = mStateTrackedPrinters.size(); 1308b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (int i = 0; i < trackedPrinters; i++) { 1309b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov PrinterId printer = mStateTrackedPrinters.get(i); 1310b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append(tab).append(printer.toString()).println(); 1311b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 1312b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1313b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append("printers:").println(); 1314b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov final int pritnerCount = mPrinters.size(); 1315b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov for (int i = 0; i < pritnerCount; i++) { 1316b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov PrinterInfo printer = mPrinters.valueAt(i); 1317b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov pw.append(prefix).append(tab).append(tab).append( 1318b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov printer.toString()).println(); 1319b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 1320b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 1321b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 1322c6066799ad130140159230d14451b429eb828755Svetoslav private void removePrintersForServiceLocked(ComponentName serviceName) { 1323c6066799ad130140159230d14451b429eb828755Svetoslav // No printers - nothing to do. 1324c6066799ad130140159230d14451b429eb828755Svetoslav if (mPrinters.isEmpty()) { 1325c6066799ad130140159230d14451b429eb828755Svetoslav return; 1326c6066799ad130140159230d14451b429eb828755Svetoslav } 1327c6066799ad130140159230d14451b429eb828755Svetoslav // Remove the printers for that service. 1328c6066799ad130140159230d14451b429eb828755Svetoslav List<PrinterId> removedPrinterIds = null; 1329c6066799ad130140159230d14451b429eb828755Svetoslav final int printerCount = mPrinters.size(); 1330c6066799ad130140159230d14451b429eb828755Svetoslav for (int i = 0; i < printerCount; i++) { 1331c6066799ad130140159230d14451b429eb828755Svetoslav PrinterId printerId = mPrinters.keyAt(i); 1332c6066799ad130140159230d14451b429eb828755Svetoslav if (printerId.getServiceName().equals(serviceName)) { 1333c6066799ad130140159230d14451b429eb828755Svetoslav if (removedPrinterIds == null) { 1334c6066799ad130140159230d14451b429eb828755Svetoslav removedPrinterIds = new ArrayList<PrinterId>(); 1335c6066799ad130140159230d14451b429eb828755Svetoslav } 1336c6066799ad130140159230d14451b429eb828755Svetoslav removedPrinterIds.add(printerId); 1337c6066799ad130140159230d14451b429eb828755Svetoslav } 1338c6066799ad130140159230d14451b429eb828755Svetoslav } 1339c6066799ad130140159230d14451b429eb828755Svetoslav if (removedPrinterIds != null) { 1340de4fa2dfe2e681c79e27d84604b9c48c68184aefSvetoslav Ganov final int removedPrinterCount = removedPrinterIds.size(); 1341de4fa2dfe2e681c79e27d84604b9c48c68184aefSvetoslav Ganov for (int i = 0; i < removedPrinterCount; i++) { 1342de4fa2dfe2e681c79e27d84604b9c48c68184aefSvetoslav Ganov mPrinters.remove(removedPrinterIds.get(i)); 1343de4fa2dfe2e681c79e27d84604b9c48c68184aefSvetoslav Ganov } 1344c6066799ad130140159230d14451b429eb828755Svetoslav mHandler.obtainMessage( 1345c6066799ad130140159230d14451b429eb828755Svetoslav SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED, 1346c6066799ad130140159230d14451b429eb828755Svetoslav removedPrinterIds).sendToTarget(); 1347c6066799ad130140159230d14451b429eb828755Svetoslav } 1348c6066799ad130140159230d14451b429eb828755Svetoslav } 1349c6066799ad130140159230d14451b429eb828755Svetoslav 135044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handleDispatchPrintersAdded(List<PrinterInfo> addedPrinters) { 135144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int observerCount = mDiscoveryObservers.beginBroadcast(); 135244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < observerCount; i++) { 135344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i); 13549186d0cb2bd325d9b52da15dbd513937c1e42caaSvetoslav Ganov handlePrintersAdded(observer, addedPrinters); 135544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 135644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mDiscoveryObservers.finishBroadcast(); 135744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 135844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 135944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handleDispatchPrintersRemoved(List<PrinterId> removedPrinterIds) { 136044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int observerCount = mDiscoveryObservers.beginBroadcast(); 136144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < observerCount; i++) { 136244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i); 13639186d0cb2bd325d9b52da15dbd513937c1e42caaSvetoslav Ganov handlePrintersRemoved(observer, removedPrinterIds); 136444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 136544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov mDiscoveryObservers.finishBroadcast(); 136644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 136744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 136844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handleDispatchCreatePrinterDiscoverySession( 136944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services) { 137044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int serviceCount = services.size(); 137144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < serviceCount; i++) { 137244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = services.get(i); 137344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service.createPrinterDiscoverySession(); 137444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 137544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 137644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 137744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handleDispatchDestroyPrinterDiscoverySession( 137844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services) { 137944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int serviceCount = services.size(); 138044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < serviceCount; i++) { 138144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = services.get(i); 138244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service.destroyPrinterDiscoverySession(); 138344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 138444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov onDestroyed(); 138544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 138644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 138744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handleDispatchStartPrinterDiscovery( 138844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services, List<PrinterId> printerIds) { 138944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int serviceCount = services.size(); 139044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < serviceCount; i++) { 139144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = services.get(i); 139244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service.startPrinterDiscovery(printerIds); 139344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 139444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 139544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 139644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handleDispatchStopPrinterDiscovery(List<RemotePrintService> services) { 139744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov final int serviceCount = services.size(); 139844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov for (int i = 0; i < serviceCount; i++) { 139944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = services.get(i); 140044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service.stopPrinterDiscovery(); 140144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 140244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 140344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1404d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private void handleValidatePrinters(RemotePrintService service, 1405d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov List<PrinterId> printerIds) { 1406d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov service.validatePrinters(printerIds); 1407d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1408d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1409d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private void handleStartPrinterStateTracking(RemotePrintService service, 1410d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov PrinterId printerId) { 1411d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov service.startPrinterStateTracking(printerId); 1412d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 1413d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1414d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov private void handleStopPrinterStateTracking(RemotePrintService service, 141544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterId printerId) { 1416d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov service.stopPrinterStateTracking(printerId); 141744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 141844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 141944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handlePrintersAdded(IPrinterDiscoveryObserver observer, 142044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> printers) { 142144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 14222fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav observer.onPrintersAdded(new ParceledListSlice<PrinterInfo>(printers)); 142344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 142444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov Log.e(LOG_TAG, "Error sending added printers", re); 142544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 142644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 142744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 142844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private void handlePrintersRemoved(IPrinterDiscoveryObserver observer, 142944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> printerIds) { 143044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov try { 14312fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav observer.onPrintersRemoved(new ParceledListSlice<PrinterId>(printerIds)); 143244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } catch (RemoteException re) { 14332fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav Log.e(LOG_TAG, "Error sending removed printers", re); 143444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 143544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 143644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 143744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov private final class SessionHandler extends Handler { 143844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public static final int MSG_PRINTERS_ADDED = 1; 143944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public static final int MSG_PRINTERS_REMOVED = 2; 144044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public static final int MSG_DISPATCH_PRINTERS_ADDED = 3; 144144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public static final int MSG_DISPATCH_PRINTERS_REMOVED = 4; 1442773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav 1443773f54de3de9bce7b6f915aa47ed686b161d77aaSvetoslav public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 5; 1444c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 6; 1445c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_START_PRINTER_DISCOVERY = 7; 1446c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_STOP_PRINTER_DISCOVERY = 8; 1447c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION = 9; 1448c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION = 10; 1449c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_DISPATCH_START_PRINTER_DISCOVERY = 11; 1450c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_DISPATCH_STOP_PRINTER_DISCOVERY = 12; 1451c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_VALIDATE_PRINTERS = 13; 1452c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_START_PRINTER_STATE_TRACKING = 14; 1453c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_STOP_PRINTER_STATE_TRACKING = 15; 1454c6066799ad130140159230d14451b429eb828755Svetoslav public static final int MSG_DESTROY_SERVICE = 16; 145544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 145644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SessionHandler(Looper looper) { 145744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov super(looper, null, false); 145844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 145944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 146044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @Override 146144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov @SuppressWarnings("unchecked") 146244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov public void handleMessage(Message message) { 146344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov switch (message.what) { 146444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_PRINTERS_ADDED: { 146544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 146644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg1; 146744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> addedPrinters = (List<PrinterInfo>) args.arg2; 146844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.recycle(); 146944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handlePrintersAdded(observer, addedPrinters); 147044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 147144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 147244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_PRINTERS_REMOVED: { 147344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 147444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg1; 147544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> removedPrinterIds = (List<PrinterId>) args.arg2; 147644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.recycle(); 147744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handlePrintersRemoved(observer, removedPrinterIds); 147844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 147944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 148044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_DISPATCH_PRINTERS_ADDED: { 148144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterInfo> addedPrinters = (List<PrinterInfo>) message.obj; 148244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handleDispatchPrintersAdded(addedPrinters); 148344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 148444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 148544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_DISPATCH_PRINTERS_REMOVED: { 148644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> removedPrinterIds = (List<PrinterId>) message.obj; 148744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handleDispatchPrintersRemoved(removedPrinterIds); 148844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 148944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 149044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_CREATE_PRINTER_DISCOVERY_SESSION: { 149144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = (RemotePrintService) message.obj; 149244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service.createPrinterDiscoverySession(); 149344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 149444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1495c6066799ad130140159230d14451b429eb828755Svetoslav case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: { 1496c6066799ad130140159230d14451b429eb828755Svetoslav RemotePrintService service = (RemotePrintService) message.obj; 1497c6066799ad130140159230d14451b429eb828755Svetoslav service.destroyPrinterDiscoverySession(); 1498c6066799ad130140159230d14451b429eb828755Svetoslav } break; 1499c6066799ad130140159230d14451b429eb828755Svetoslav 150044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_START_PRINTER_DISCOVERY: { 150144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = (RemotePrintService) message.obj; 150244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov service.startPrinterDiscovery(null); 150344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 150444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1505c6066799ad130140159230d14451b429eb828755Svetoslav case MSG_STOP_PRINTER_DISCOVERY: { 1506c6066799ad130140159230d14451b429eb828755Svetoslav RemotePrintService service = (RemotePrintService) message.obj; 1507c6066799ad130140159230d14451b429eb828755Svetoslav service.stopPrinterDiscovery(); 1508c6066799ad130140159230d14451b429eb828755Svetoslav } break; 1509c6066799ad130140159230d14451b429eb828755Svetoslav 151044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION: { 151144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = (List<RemotePrintService>) message.obj; 151244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handleDispatchCreatePrinterDiscoverySession(services); 151344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 151444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 151544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION: { 151644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = (List<RemotePrintService>) message.obj; 151744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handleDispatchDestroyPrinterDiscoverySession(services); 151844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 151944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 152044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_DISPATCH_START_PRINTER_DISCOVERY: { 152144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 152244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = (List<RemotePrintService>) args.arg1; 152344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<PrinterId> printerIds = (List<PrinterId>) args.arg2; 152444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.recycle(); 152544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handleDispatchStartPrinterDiscovery(services, printerIds); 152644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 152744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 152844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov case MSG_DISPATCH_STOP_PRINTER_DISCOVERY: { 152944720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov List<RemotePrintService> services = (List<RemotePrintService>) message.obj; 153044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov handleDispatchStopPrinterDiscovery(services); 153144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 153244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 1533d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov case MSG_VALIDATE_PRINTERS: { 1534d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 1535d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov RemotePrintService service = (RemotePrintService) args.arg1; 1536d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov List<PrinterId> printerIds = (List<PrinterId>) args.arg2; 1537d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.recycle(); 1538d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov handleValidatePrinters(service, printerIds); 1539d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } break; 1540d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1541d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov case MSG_START_PRINTER_STATE_TRACKING: { 154244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 154344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov RemotePrintService service = (RemotePrintService) args.arg1; 154444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov PrinterId printerId = (PrinterId) args.arg2; 154544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov args.recycle(); 1546d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov handleStartPrinterStateTracking(service, printerId); 154744720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } break; 1548d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 1549d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov case MSG_STOP_PRINTER_STATE_TRACKING: { 1550d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov SomeArgs args = (SomeArgs) message.obj; 1551d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov RemotePrintService service = (RemotePrintService) args.arg1; 1552d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov PrinterId printerId = (PrinterId) args.arg2; 1553d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov args.recycle(); 1554d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov handleStopPrinterStateTracking(service, printerId); 1555c6066799ad130140159230d14451b429eb828755Svetoslav } break; 1556c6066799ad130140159230d14451b429eb828755Svetoslav 1557c6066799ad130140159230d14451b429eb828755Svetoslav case MSG_DESTROY_SERVICE: { 1558c6066799ad130140159230d14451b429eb828755Svetoslav RemotePrintService service = (RemotePrintService) message.obj; 1559c6066799ad130140159230d14451b429eb828755Svetoslav service.destroy(); 1560c6066799ad130140159230d14451b429eb828755Svetoslav } break; 156144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 156244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 156344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 156444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 15652fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 1566dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private final class PrintJobForAppCache { 1567dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov private final SparseArray<List<PrintJobInfo>> mPrintJobsForRunningApp = 1568dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov new SparseArray<List<PrintJobInfo>>(); 15692fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav 1570dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public boolean onPrintJobCreated(final IBinder creator, final int appId, 1571dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo printJob) { 15722fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav try { 15732fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav creator.linkToDeath(new DeathRecipient() { 15742fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav @Override 15752fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav public void binderDied() { 15762fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav creator.unlinkToDeath(this, 0); 15772fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 1578dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mPrintJobsForRunningApp.remove(appId); 15792fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 15802fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 15812fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav }, 0); 15822fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } catch (RemoteException re) { 15832fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav /* The process is already dead - we just failed. */ 15842fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return false; 15852fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 15862fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav synchronized (mLock) { 1587dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> printJobsForApp = mPrintJobsForRunningApp.get(appId); 1588dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJobsForApp == null) { 1589dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobsForApp = new ArrayList<PrintJobInfo>(); 1590dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov mPrintJobsForRunningApp.put(appId, printJobsForApp); 15912fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 1592dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobsForApp.add(printJob); 15932fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 15942fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav return true; 15952fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 1596dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 1597dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void onPrintJobStateChanged(PrintJobInfo printJob) { 1598dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov synchronized (mLock) { 1599dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> printJobsForApp = mPrintJobsForRunningApp.get( 1600dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJob.getAppId()); 1601dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJobsForApp == null) { 1602dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return; 1603dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1604dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int printJobCount = printJobsForApp.size(); 1605dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < printJobCount; i++) { 1606dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo oldPrintJob = printJobsForApp.get(i); 1607dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (oldPrintJob.getId().equals(printJob.getId())) { 1608dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobsForApp.set(i, printJob); 1609dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1610dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1611dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1612dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1613dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 1614dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public PrintJobInfo getPrintJob(PrintJobId printJobId, int appId) { 1615dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov synchronized (mLock) { 1616dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> printJobsForApp = mPrintJobsForRunningApp.get(appId); 1617dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJobsForApp == null) { 1618dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return null; 1619dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1620dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int printJobCount = printJobsForApp.size(); 1621dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < printJobCount; i++) { 1622dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo printJob = printJobsForApp.get(i); 1623dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJob.getId().equals(printJobId)) { 1624dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return printJob; 1625dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1626dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1627dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1628dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return null; 1629dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1630dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 1631dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public List<PrintJobInfo> getPrintJobs(int appId) { 1632dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov synchronized (mLock) { 1633dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> printJobs = null; 1634dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (appId == PrintManager.APP_ID_ANY) { 1635dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int bucketCount = mPrintJobsForRunningApp.size(); 1636dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < bucketCount; i++) { 1637dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> bucket = mPrintJobsForRunningApp.valueAt(i); 1638dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJobs == null) { 1639dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobs = new ArrayList<PrintJobInfo>(); 1640dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1641dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobs.addAll(bucket); 1642dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1643dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } else { 1644dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> bucket = mPrintJobsForRunningApp.get(appId); 1645dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (bucket != null) { 1646dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJobs == null) { 1647dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobs = new ArrayList<PrintJobInfo>(); 1648dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1649dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov printJobs.addAll(bucket); 1650dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1651dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1652dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov if (printJobs != null) { 1653dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return printJobs; 1654dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1655dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov return Collections.emptyList(); 1656dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1657dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1658dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov 1659dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov public void dump(PrintWriter pw, String prefix) { 1660dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov synchronized (mLock) { 1661dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov String tab = " "; 1662dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int bucketCount = mPrintJobsForRunningApp.size(); 1663dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int i = 0; i < bucketCount; i++) { 1664dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int appId = mPrintJobsForRunningApp.keyAt(i); 1665dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append("appId=" + appId).append(':').println(); 1666dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov List<PrintJobInfo> bucket = mPrintJobsForRunningApp.valueAt(i); 1667dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov final int printJobCount = bucket.size(); 1668dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov for (int j = 0; j < printJobCount; j++) { 1669dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov PrintJobInfo printJob = bucket.get(j); 1670dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov pw.append(prefix).append(tab).append(printJob.toString()).println(); 1671dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1672dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1673dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 1674dd68da2741fa63070d5ad206020dcccb9f429a5aSvetoslav Ganov } 16752fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 16762fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav} 1677