Handle user changes off the main thread.
The remote print spooler can only be accessed off the main thread
by design as calls into it may block for a short amoun of time since
the frist call into the spooler may have to wait for the system to
bind to the spooler service. A recent change introduced a regression
where the user state changes are now dispatched on the main thread.
This change schedules the user change handling to a background handler
thread.
bug:17396682
Change-Id: I059be8f31ba41122cb2967d8afadd19e6b5a08e5
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 64242ba..6785cb8 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -627,26 +627,40 @@
return userState;
}
- private void handleUserStarted(int userId) {
- UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(userId);
- userState.updateIfNeededLocked();
- }
- // This is the first time we switch to this user after boot, so
- // now is the time to remove obsolete print jobs since they
- // are from the last boot and no application would query them.
- userState.removeObsoletePrintJobs();
+ private void handleUserStarted(final int userId) {
+ // This code will touch the remote print spooler which
+ // must be called off the main thread, so post the work.
+ BackgroundThread.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(userId);
+ userState.updateIfNeededLocked();
+ }
+ // This is the first time we switch to this user after boot, so
+ // now is the time to remove obsolete print jobs since they
+ // are from the last boot and no application would query them.
+ userState.removeObsoletePrintJobs();
+ }
+ });
}
- private void handleUserStopped(int userId) {
- synchronized (mLock) {
- UserState userState = mUserStates.get(userId);
- if (userState != null) {
- userState.destroyLocked();
- mUserStates.remove(userId);
+ private void handleUserStopped(final int userId) {
+ // This code will touch the remote print spooler which
+ // must be called off the main thread, so post the work.
+ BackgroundThread.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mLock) {
+ UserState userState = mUserStates.get(userId);
+ if (userState != null) {
+ userState.destroyLocked();
+ mUserStates.remove(userId);
+ }
+ }
}
- }
+ });
}
private int resolveCallingProfileParentLocked(int userId) {