From 1d6e7cc536cb7f49b318f630ad8f2eb348786716 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 24 Aug 2016 09:27:46 -0700 Subject: [PATCH] Hold no locks when calling RemotePrintSpooler The calls might be blocking and need the main thread of to be unblocked to finish. Hence do not call while holding any monitors that might need to be acquired the main thread. The calls that have been moved out of the lock: - Icon related calls: These are just caches. Hence we flush the cache we just request the icon again - Prune call: This just removes not installed print service from some data structure. The order of two of these calls does not matter as the end result of both removals will be the same, regardless of order. Testing done: Reinstalled a print service multiple times. Before the first reinstallation locked up the userState, now not anymore Change-Id: I4f4cdaba65132dc2ef054877cbb097b499a723f6 Fixes: 31043684 --- .../com/android/server/print/RemotePrintSpooler.java | 3 +++ .../print/java/com/android/server/print/UserState.java | 18 +++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java index 07cc9c05f57a..07b26e83e934 100644 --- a/services/print/java/com/android/server/print/RemotePrintSpooler.java +++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java @@ -57,6 +57,9 @@ import java.util.concurrent.TimeoutException; * spooler if needed, to make the timed remote calls, to handle * remote exceptions, and to bind/unbind to the remote instance as * needed. + * + * The calls might be blocking and need the main thread of to be unblocked to finish. Hence do not + * call this while holding any monitors that might need to be acquired the main thread. */ final class RemotePrintSpooler { diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index 05301c1cb5f2..a91cdb38a15a 100644 --- a/services/print/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java @@ -434,12 +434,12 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, } public void createPrinterDiscoverySession(@NonNull IPrinterDiscoveryObserver observer) { + mSpooler.clearCustomPrinterIconCache(); + synchronized (mLock) { throwIfDestroyedLocked(); if (mPrinterDiscoverySession == null) { - mSpooler.clearCustomPrinterIconCache(); - // If we do not have a session, tell all service to create one. mPrinterDiscoverySession = new PrinterDiscoverySessionMediator(mContext) { @Override @@ -731,6 +731,8 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, @Override public void onCustomPrinterIconLoaded(PrinterId printerId, Icon icon) { + mSpooler.onCustomPrinterIconLoaded(printerId, icon); + synchronized (mLock) { throwIfDestroyedLocked(); @@ -738,7 +740,6 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, if (mPrinterDiscoverySession == null) { return; } - mSpooler.onCustomPrinterIconLoaded(printerId, icon); mPrinterDiscoverySession.onCustomPrinterIconLoadedLocked(printerId); } } @@ -979,18 +980,21 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, * Prune persistent state if a print service was uninstalled */ public void prunePrintServices() { + ArrayList installedComponents; + synchronized (mLock) { - ArrayList installedComponents = getInstalledComponents(); + installedComponents = getInstalledComponents(); // Remove unnecessary entries from persistent state "disabled services" boolean disabledServicesUninstalled = mDisabledServices.retainAll(installedComponents); if (disabledServicesUninstalled) { writeDisabledPrintServicesLocked(mDisabledServices); } - - // Remove unnecessary entries from persistent state "approved services" - mSpooler.pruneApprovedPrintServices(installedComponents); } + + // Remove unnecessary entries from persistent state "approved services" + mSpooler.pruneApprovedPrintServices(installedComponents); + } private void onConfigurationChangedLocked() { -- 2.11.0