summaryrefslogtreecommitdiff
path: root/services/java/com/android/server/print/RemotePrintService.java
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2013-09-10 21:08:32 -0700
committerSvetoslav <svetoslavganov@google.com>2013-09-12 10:52:26 -0700
commitc6066799ad130140159230d14451b429eb828755 (patch)
tree43145c16aae37124e167c1edde05c4376e0b69e2 /services/java/com/android/server/print/RemotePrintService.java
parent16dae5997bb0ff7f03d5a0ccfdc4be94aa35ba51 (diff)
Handle print serivce crashes.
1. Now after a print service crashes we are bringing it to the same state of its lifecycle. For example, if a service does a discovery and crashes we recreate the discovery session call the start discovery method and so on. 2. Turned off debugging logs since we have fully fledged state dump. bug:10697779 Change-Id: Id790537461428e96b197eef12258996bda2bd1ce
Diffstat (limited to 'services/java/com/android/server/print/RemotePrintService.java')
-rw-r--r--services/java/com/android/server/print/RemotePrintService.java149
1 files changed, 98 insertions, 51 deletions
diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/java/com/android/server/print/RemotePrintService.java
index ddff0ae55449..0d539b0a335f 100644
--- a/services/java/com/android/server/print/RemotePrintService.java
+++ b/services/java/com/android/server/print/RemotePrintService.java
@@ -21,11 +21,9 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
-import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
-import android.os.AsyncTask;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -39,8 +37,6 @@ import android.printservice.IPrintService;
import android.printservice.IPrintServiceClient;
import android.util.Slog;
-import com.android.internal.R;
-
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -55,7 +51,7 @@ final class RemotePrintService implements DeathRecipient {
private static final String LOG_TAG = "RemotePrintService";
- private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = false;
private final Context mContext;
@@ -65,7 +61,7 @@ final class RemotePrintService implements DeathRecipient {
private final RemotePrintSpooler mSpooler;
- private final UserState mUserState;
+ private final PrintServiceCallbacks mCallbacks;
private final int mUserId;
@@ -83,14 +79,24 @@ final class RemotePrintService implements DeathRecipient {
private boolean mDestroyed;
- private boolean mAllPrintJobsHandled;
+ private boolean mHasActivePrintJobs;
private boolean mHasPrinterDiscoverySession;
+ private List<PrinterId> mDiscoveryPriorityList;
+
+ private List<PrinterId> mTrackedPrinterList;
+
+ public static interface PrintServiceCallbacks {
+ public void onPrintersAdded(List<PrinterInfo> printers);
+ public void onPrintersRemoved(List<PrinterId> printerIds);
+ public void onServiceDied(RemotePrintService service);
+ }
+
public RemotePrintService(Context context, ComponentName componentName, int userId,
- RemotePrintSpooler spooler, UserState userState) {
+ RemotePrintSpooler spooler, PrintServiceCallbacks callbacks) {
mContext = context;
- mUserState = userState;
+ mCallbacks = callbacks;
mComponentName = componentName;
mIntent = new Intent().setComponent(mComponentName);
mUserId = userId;
@@ -99,15 +105,42 @@ final class RemotePrintService implements DeathRecipient {
mPrintServiceClient = new RemotePrintServiceClient(this);
}
+ public ComponentName getComponentName() {
+ return mComponentName;
+ }
+
public void destroy() {
mHandler.sendEmptyMessage(MyHandler.MSG_DESTROY);
}
private void handleDestroy() {
throwIfDestroyed();
+
+ // Stop tracking printers.
+ if (mTrackedPrinterList != null) {
+ final int trackedPrinterCount = mTrackedPrinterList.size();
+ for (int i = 0; i < trackedPrinterCount; i++) {
+ PrinterId printerId = mTrackedPrinterList.get(i);
+ if (printerId.getServiceName().equals(mComponentName)) {
+ handleStopPrinterStateTracking(printerId);
+ }
+ }
+ }
+
+ // Stop printer discovery.
+ if (mDiscoveryPriorityList != null) {
+ handleStopPrinterDiscovery();
+ }
+
+ // Destroy the discovery session.
+ if (mHasPrinterDiscoverySession) {
+ handleDestroyPrinterDiscoverySession();
+ }
+
+ // Unbind.
ensureUnbound();
- mAllPrintJobsHandled = false;
- mHasPrinterDiscoverySession = false;
+
+ // Done
mDestroyed = true;
}
@@ -121,21 +154,9 @@ final class RemotePrintService implements DeathRecipient {
}
private void handleBinderDied() {
- mAllPrintJobsHandled = false;
- mHasPrinterDiscoverySession = false;
- mPendingCommands.clear();
- ensureUnbound();
-
- // Makes sure all active print jobs are failed since the service
- // just died. Do this off the main thread since we do to allow
- // calls into the spooler on the main thread.
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- failAllActivePrintJobs();
- return null;
- }
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+ mPrintService.asBinder().unlinkToDeath(this, 0);
+ mPrintService = null;
+ mCallbacks.onServiceDied(this);
}
public void dump(PrintWriter pw, String prefix) {
@@ -148,32 +169,17 @@ final class RemotePrintService implements DeathRecipient {
pw.append(prefix).append(tab).append("bound=")
.append(String.valueOf(isBound())).println();
pw.append(prefix).append(tab).append("hasDicoverySession=")
- .append(String.valueOf(mHasPrinterDiscoverySession));
- }
-
- private void failAllActivePrintJobs() {
- List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(mComponentName,
- PrintJobInfo.STATE_ANY_ACTIVE, PrintManager.APP_ID_ANY);
- if (printJobs == null) {
- return;
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- final int printJobCount = printJobs.size();
- for (int i = 0; i < printJobCount; i++) {
- PrintJobInfo printJob = printJobs.get(i);
- mSpooler.setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
- mContext.getString(R.string.reason_unknown));
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ .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");
}
private void handleOnAllPrintJobsHandled() {
throwIfDestroyed();
- mAllPrintJobsHandled = true;
+ mHasActivePrintJobs = false;
if (isBound()) {
if (DEBUG) {
@@ -217,7 +223,7 @@ final class RemotePrintService implements DeathRecipient {
private void handleOnPrintJobQueued(final PrintJobInfo printJob) {
throwIfDestroyed();
- mAllPrintJobsHandled = false;
+ mHasActivePrintJobs = true;
if (!isBound()) {
ensureBound();
@@ -296,7 +302,7 @@ final class RemotePrintService implements DeathRecipient {
// If the service has no print jobs and no active discovery
// session anymore we should disconnect from it.
- if (mAllPrintJobsHandled) {
+ if (!mHasActivePrintJobs) {
ensureUnbound();
}
}
@@ -326,6 +332,11 @@ 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);
+ }
}
}
@@ -347,6 +358,8 @@ 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) {
@@ -406,6 +419,11 @@ 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);
}
}
@@ -428,6 +446,11 @@ final class RemotePrintService implements DeathRecipient {
if (DEBUG) {
Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterTracking()");
}
+ // We are no longer tracking the printer.
+ mTrackedPrinterList.remove(printerId);
+ if (mTrackedPrinterList.isEmpty()) {
+ mTrackedPrinterList = null;
+ }
try {
mPrintService.stopPrinterStateTracking(printerId);
} catch (RemoteException re) {
@@ -461,6 +484,10 @@ final class RemotePrintService implements DeathRecipient {
}
mBinding = false;
mPendingCommands.clear();
+ mHasActivePrintJobs = false;
+ mHasPrinterDiscoverySession = false;
+ mDiscoveryPriorityList = null;
+ mTrackedPrinterList = null;
if (isBound()) {
try {
mPrintService.setClient(null);
@@ -500,11 +527,31 @@ 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) {
+ handleCreatePrinterDiscoverySession();
+ }
+ // If there is a priority list, then the service died during
+ // discovery and is restarted. Hence, start discovery.
+ if (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) {
+ 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);
pendingCommand.run();
}
+ mPendingCommands.clear();
}
@Override
@@ -677,7 +724,7 @@ final class RemotePrintService implements DeathRecipient {
throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
final long identity = Binder.clearCallingIdentity();
try {
- service.mUserState.onPrintersAdded(printers);
+ service.mCallbacks.onPrintersAdded(printers);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -691,7 +738,7 @@ final class RemotePrintService implements DeathRecipient {
throwIfPrinterIdsTampered(service.mComponentName, printerIds);
final long identity = Binder.clearCallingIdentity();
try {
- service.mUserState.onPrintersRemoved(printerIds);
+ service.mCallbacks.onPrintersRemoved(printerIds);
} finally {
Binder.restoreCallingIdentity(identity);
}