diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2013-09-15 18:46:01 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-09-15 18:46:02 +0000 |
commit | 4244d66a122258adc86a8d757d3fe5f9588a59f8 (patch) | |
tree | 35266fb9918a7d5eac67e32088041cdb660d18a8 /services/java/com/android/server | |
parent | 3386b07ef1efbe091ab14719e9f8b61fa419d839 (diff) | |
parent | de4fa2dfe2e681c79e27d84604b9c48c68184aef (diff) | |
download | frameworks_base-4244d66a122258adc86a8d757d3fe5f9588a59f8.zip frameworks_base-4244d66a122258adc86a8d757d3fe5f9588a59f8.tar.gz frameworks_base-4244d66a122258adc86a8d757d3fe5f9588a59f8.tar.bz2 |
Merge changes Id0a67846,I20b57d66 into klp-dev
* changes:
Print system may get stuck bound to a print service
Spooler should not crash if print service config activities are not exported.
Diffstat (limited to 'services/java/com/android/server')
3 files changed, 135 insertions, 71 deletions
diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java index 926f822..c33bfb7 100644 --- a/services/java/com/android/server/print/PrintManagerService.java +++ b/services/java/com/android/server/print/PrintManagerService.java @@ -35,6 +35,7 @@ import android.print.IPrinterDiscoveryObserver; import android.print.PrintAttributes; import android.print.PrintJobInfo; import android.print.PrinterId; +import android.printservice.PrintServiceInfo; import android.provider.Settings; import android.util.SparseArray; @@ -192,6 +193,22 @@ public final class PrintManagerService extends IPrintManager.Stub { } } + + @Override + public List<PrintServiceInfo> getEnabledPrintServices(int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + return userState.getEnabledPrintServices(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer, int userId) { diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/java/com/android/server/print/RemotePrintService.java index f15c760..8869cbe 100644 --- a/services/java/com/android/server/print/RemotePrintService.java +++ b/services/java/com/android/server/print/RemotePrintService.java @@ -83,6 +83,8 @@ final class RemotePrintService implements DeathRecipient { private boolean mHasPrinterDiscoverySession; + private boolean mServiceDead; + private List<PrinterId> mDiscoveryPriorityList; private List<PrinterId> mTrackedPrinterList; @@ -103,6 +105,7 @@ final class RemotePrintService implements DeathRecipient { mSpooler = spooler; mHandler = new MyHandler(context.getMainLooper()); mPrintServiceClient = new RemotePrintServiceClient(this); + mServiceDead = true; } public ComponentName getComponentName() { @@ -144,10 +147,6 @@ final class RemotePrintService implements DeathRecipient { mDestroyed = true; } - public void onAllPrintJobsHandled() { - mHandler.sendEmptyMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED); - } - @Override public void binderDied() { mHandler.sendEmptyMessage(MyHandler.MSG_BINDER_DIED); @@ -156,36 +155,35 @@ final class RemotePrintService implements DeathRecipient { private void handleBinderDied() { mPrintService.asBinder().unlinkToDeath(this, 0); mPrintService = null; + mServiceDead = true; mCallbacks.onServiceDied(this); } - public void dump(PrintWriter pw, String prefix) { - String tab = " "; - pw.append(prefix).append("service:").println(); - pw.append(prefix).append(tab).append("componentName=") - .append(mComponentName.flattenToString()).println(); - pw.append(prefix).append(tab).append("destroyed=") - .append(String.valueOf(mDestroyed)).println(); - pw.append(prefix).append(tab).append("bound=") - .append(String.valueOf(isBound())).println(); - pw.append(prefix).append(tab).append("hasDicoverySession=") - .append(String.valueOf(mHasPrinterDiscoverySession)).println(); - pw.append(prefix).append(tab).append("isDiscoveringPrinters=") - .append(String.valueOf(mDiscoveryPriorityList != null)).println(); - pw.append(prefix).append(tab).append("trackedPrinters=") - .append((mTrackedPrinterList != null) ? mTrackedPrinterList.toString() : "null"); + public void onAllPrintJobsHandled() { + mHandler.sendEmptyMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED); } private void handleOnAllPrintJobsHandled() { throwIfDestroyed(); - mHasActivePrintJobs = false; - - if (isBound()) { + if (!isBound()) { + // The service is dead and neither has active jobs nor discovery + // session, so ensure we are unbound since the service has no work. + if (mServiceDead && !mHasPrinterDiscoverySession) { + ensureUnbound(); + return; + } + ensureBound(); + mPendingCommands.add(new Runnable() { + @Override + public void run() { + handleOnAllPrintJobsHandled(); + } + }); + } else { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserId + "] onAllPrintJobsHandled()"); } - // If the service has a printer discovery session // created we should not disconnect from it just yet. if (!mHasPrinterDiscoverySession) { @@ -201,9 +199,15 @@ final class RemotePrintService implements DeathRecipient { private void handleRequestCancelPrintJob(final PrintJobInfo printJob) { throwIfDestroyed(); - // If we are not bound, then we have no print jobs to handle - // which means that there are no print jobs to be cancelled. - if (isBound()) { + if (!isBound()) { + ensureBound(); + mPendingCommands.add(new Runnable() { + @Override + public void run() { + handleRequestCancelPrintJob(printJob); + } + }); + } else { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserId + "] requestCancelPrintJob()"); } @@ -222,14 +226,12 @@ final class RemotePrintService implements DeathRecipient { private void handleOnPrintJobQueued(final PrintJobInfo printJob) { throwIfDestroyed(); - mHasActivePrintJobs = true; - if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @Override - public void run() { + public void run() { handleOnPrintJobQueued(printJob); } }); @@ -251,6 +253,7 @@ final class RemotePrintService implements DeathRecipient { private void handleCreatePrinterDiscoverySession() { throwIfDestroyed(); + mHasPrinterDiscoverySession = true; if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @@ -268,8 +271,6 @@ final class RemotePrintService implements DeathRecipient { } catch (RemoteException re) { Slog.e(LOG_TAG, "Error creating printer dicovery session.", re); } - - mHasPrinterDiscoverySession = true; } } @@ -279,7 +280,14 @@ final class RemotePrintService implements DeathRecipient { private void handleDestroyPrinterDiscoverySession() { throwIfDestroyed(); + mHasPrinterDiscoverySession = false; if (!isBound()) { + // The service is dead and neither has active jobs nor discovery + // session, so ensure we are unbound since the service has no work. + if (mServiceDead && !mHasActivePrintJobs) { + ensureUnbound(); + return; + } ensureBound(); mPendingCommands.add(new Runnable() { @Override @@ -291,15 +299,11 @@ final class RemotePrintService implements DeathRecipient { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserId + "] destroyPrinterDiscoverySession()"); } - - mHasPrinterDiscoverySession = false; - try { mPrintService.destroyPrinterDiscoverySession(); } catch (RemoteException re) { Slog.e(LOG_TAG, "Error destroying printer dicovery session.", re); } - // If the service has no print jobs and no active discovery // session anymore we should disconnect from it. if (!mHasActivePrintJobs) { @@ -315,6 +319,11 @@ final class RemotePrintService implements DeathRecipient { private void handleStartPrinterDiscovery(final List<PrinterId> priorityList) { throwIfDestroyed(); + // Take a note that we are doing discovery. + mDiscoveryPriorityList = new ArrayList<PrinterId>(); + if (priorityList != null) { + mDiscoveryPriorityList.addAll(priorityList); + } if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @@ -332,11 +341,6 @@ final class RemotePrintService implements DeathRecipient { } catch (RemoteException re) { Slog.e(LOG_TAG, "Error starting printer dicovery.", re); } - // Take a note that we are doing discovery. - mDiscoveryPriorityList = new ArrayList<PrinterId>(); - if (priorityList != null) { - mDiscoveryPriorityList.addAll(priorityList); - } } } @@ -346,6 +350,8 @@ final class RemotePrintService implements DeathRecipient { private void handleStopPrinterDiscovery() { throwIfDestroyed(); + // We are not doing discovery anymore. + mDiscoveryPriorityList = null; if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @@ -358,8 +364,6 @@ final class RemotePrintService implements DeathRecipient { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterDiscovery()"); } - // We are not doing discovery anymore. - mDiscoveryPriorityList = null; try { mPrintService.stopPrinterDiscovery(); } catch (RemoteException re) { @@ -402,6 +406,11 @@ final class RemotePrintService implements DeathRecipient { private void handleStartPrinterStateTracking(final PrinterId printerId) { throwIfDestroyed(); + // Take a note we are tracking the printer. + if (mTrackedPrinterList == null) { + mTrackedPrinterList = new ArrayList<PrinterId>(); + } + mTrackedPrinterList.add(printerId); if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @@ -419,11 +428,6 @@ final class RemotePrintService implements DeathRecipient { } catch (RemoteException re) { Slog.e(LOG_TAG, "Error requesting start printer tracking.", re); } - // Take a note we are tracking the printer. - if (mTrackedPrinterList == null) { - mTrackedPrinterList = new ArrayList<PrinterId>(); - } - mTrackedPrinterList.add(printerId); } } @@ -434,6 +438,13 @@ final class RemotePrintService implements DeathRecipient { private void handleStopPrinterStateTracking(final PrinterId printerId) { throwIfDestroyed(); + // We are no longer tracking the printer. + if (mTrackedPrinterList == null || !mTrackedPrinterList.remove(printerId)) { + return; + } + if (mTrackedPrinterList.isEmpty()) { + mTrackedPrinterList = null; + } if (!isBound()) { ensureBound(); mPendingCommands.add(new Runnable() { @@ -446,13 +457,6 @@ final class RemotePrintService implements DeathRecipient { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterTracking()"); } - // We are no longer tracking the printer. - if (mTrackedPrinterList == null || !mTrackedPrinterList.remove(printerId)) { - return; - } - if (mTrackedPrinterList.isEmpty()) { - mTrackedPrinterList = null; - } try { mPrintService.stopPrinterStateTracking(printerId); } catch (RemoteException re) { @@ -461,6 +465,25 @@ final class RemotePrintService implements DeathRecipient { } } + public void dump(PrintWriter pw, String prefix) { + String tab = " "; + pw.append(prefix).append("service:").println(); + pw.append(prefix).append(tab).append("componentName=") + .append(mComponentName.flattenToString()).println(); + pw.append(prefix).append(tab).append("destroyed=") + .append(String.valueOf(mDestroyed)).println(); + pw.append(prefix).append(tab).append("bound=") + .append(String.valueOf(isBound())).println(); + pw.append(prefix).append(tab).append("hasDicoverySession=") + .append(String.valueOf(mHasPrinterDiscoverySession)).println(); + pw.append(prefix).append(tab).append("hasActivePrintJobs=") + .append(String.valueOf(mHasActivePrintJobs)).println(); + pw.append(prefix).append(tab).append("isDiscoveringPrinters=") + .append(String.valueOf(mDiscoveryPriorityList != null)).println(); + pw.append(prefix).append(tab).append("trackedPrinters=") + .append((mTrackedPrinterList != null) ? mTrackedPrinterList.toString() : "null"); + } + private boolean isBound() { return mPrintService != null; } @@ -512,6 +535,7 @@ final class RemotePrintService implements DeathRecipient { @Override public void onServiceConnected(ComponentName name, IBinder service) { if (mDestroyed || !mBinding) { + mContext.unbindService(mServiceConnection); return; } mBinding = false; @@ -529,31 +553,33 @@ final class RemotePrintService implements DeathRecipient { handleBinderDied(); return; } - // If there is a session, then the service died after creating - // a session. Hence, recreate the session. - if (mHasPrinterDiscoverySession) { + // If the service died and there is a discovery session, recreate it. + if (mServiceDead && mHasPrinterDiscoverySession) { handleCreatePrinterDiscoverySession(); } - // If there is a priority list, then the service died during - // discovery and is restarted. Hence, start discovery. - if (mDiscoveryPriorityList != null) { + // If the service died and there is discovery started, restart it. + if (mServiceDead && mDiscoveryPriorityList != null) { handleStartPrinterDiscovery(mDiscoveryPriorityList); } - // If there is a tracked printer list, then the service died - // during discovery and is restarted. Hence, start tracking. - if (mTrackedPrinterList != null) { + // If the service died and printers were tracked, start tracking. + if (mServiceDead && mTrackedPrinterList != null) { final int trackedPrinterCount = mTrackedPrinterList.size(); for (int i = 0; i < trackedPrinterCount; i++) { handleStartPrinterStateTracking(mTrackedPrinterList.get(i)); } } // Finally, do all the pending work. - final int pendingCommandCount = mPendingCommands.size(); - for (int i = 0; i < pendingCommandCount; i++) { - Runnable pendingCommand = mPendingCommands.get(i); + while (!mPendingCommands.isEmpty()) { + Runnable pendingCommand = mPendingCommands.remove(0); pendingCommand.run(); } - mPendingCommands.clear(); + // We did a best effort to get to the last state if we crashed. + // If we do not have print jobs and no discovery is in progress, + // then no need to be bound. + if (!mHasPrinterDiscoverySession && !mHasActivePrintJobs) { + ensureUnbound(); + } + mServiceDead = false; } @Override diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java index 86a5aed..7a56e6b 100644 --- a/services/java/com/android/server/print/UserState.java +++ b/services/java/com/android/server/print/UserState.java @@ -134,6 +134,26 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks { } } + public List<PrintServiceInfo> getEnabledPrintServices() { + synchronized (mLock) { + List<PrintServiceInfo> enabledServices = null; + final int installedServiceCount = mInstalledServices.size(); + for (int i = 0; i < installedServiceCount; i++) { + PrintServiceInfo installedService = mInstalledServices.get(i); + ComponentName componentName = new ComponentName( + installedService.getResolveInfo().serviceInfo.packageName, + installedService.getResolveInfo().serviceInfo.name); + if (mActiveServices.containsKey(componentName)) { + if (enabledServices == null) { + enabledServices = new ArrayList<PrintServiceInfo>(); + } + enabledServices.add(installedService); + } + } + return enabledServices; + } + } + public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer) { synchronized (mLock) { throwIfDestroyedLocked(); @@ -292,6 +312,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks { } // Fail all print jobs. failActivePrintJobsForService(service.getComponentName()); + service.onAllPrintJobsHandled(); // No session - nothing to do. if (mPrinterDiscoverySession == null) { return; @@ -984,11 +1005,11 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks { removedPrinterIds.add(printerId); } } - final int removedPrinterCount = removedPrinterIds.size(); - for (int i = 0; i < removedPrinterCount; i++) { - mPrinters.remove(removedPrinterIds.get(i)); - } if (removedPrinterIds != null) { + final int removedPrinterCount = removedPrinterIds.size(); + for (int i = 0; i < removedPrinterCount; i++) { + mPrinters.remove(removedPrinterIds.get(i)); + } mHandler.obtainMessage( SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED, removedPrinterIds).sendToTarget(); |