summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2013-09-26 19:22:19 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-09-26 19:22:20 +0000
commit5cab967bf2bab49777bfa86dff8b0f892192ede6 (patch)
tree87e70842ccb310021f207c821df7fdbc25e541c1
parent3adc49c6780633b8bccc3b5b8dca10788c2288bc (diff)
parent704697b6197262678e930daa831a1916ddee4dcf (diff)
downloadframeworks_base-5cab967bf2bab49777bfa86dff8b0f892192ede6.zip
frameworks_base-5cab967bf2bab49777bfa86dff8b0f892192ede6.tar.gz
frameworks_base-5cab967bf2bab49777bfa86dff8b0f892192ede6.tar.bz2
Merge "Adding hidden APIs for observing the print jobs state." into klp-dev
-rw-r--r--Android.mk1
-rw-r--r--api/current.txt8
-rw-r--r--core/java/android/print/IPrintJobStateChangeListener.aidl28
-rw-r--r--core/java/android/print/IPrintManager.aidl6
-rw-r--r--core/java/android/print/IPrintSpoolerClient.aidl3
-rw-r--r--core/java/android/print/PrintJob.java100
-rw-r--r--core/java/android/print/PrintJobInfo.java41
-rw-r--r--core/java/android/print/PrintManager.java117
-rw-r--r--core/java/android/print/PrinterInfo.java2
-rw-r--r--core/java/android/printservice/PrintJob.java2
-rw-r--r--core/res/res/drawable-hdpi/ic_print_error.png (renamed from packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png)bin852 -> 852 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_print_error.png (renamed from packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png)bin658 -> 658 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_print_error.png (renamed from packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png)bin1026 -> 1026 bytes
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--packages/PrintSpooler/res/layout/spinner_dropdown_item.xml2
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/NotificationController.java47
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java100
-rw-r--r--services/java/com/android/server/print/PrintManagerService.java35
-rw-r--r--services/java/com/android/server/print/RemotePrintSpooler.java18
-rw-r--r--services/java/com/android/server/print/UserState.java111
20 files changed, 559 insertions, 63 deletions
diff --git a/Android.mk b/Android.mk
index 14d1a02..13b717a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -166,6 +166,7 @@ LOCAL_SRC_FILES += \
core/java/android/print/IPrinterDiscoveryObserver.aidl \
core/java/android/print/IPrintDocumentAdapter.aidl \
core/java/android/print/IPrintClient.aidl \
+ core/java/android/print/IPrintJobStateChangeListener.aidl \
core/java/android/print/IPrintManager.aidl \
core/java/android/print/IPrintSpooler.aidl \
core/java/android/print/IPrintSpoolerCallbacks.aidl \
diff --git a/api/current.txt b/api/current.txt
index c2dfa92..21ca3c0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19372,6 +19372,13 @@ package android.print {
method public void cancel();
method public android.print.PrintJobId getId();
method public android.print.PrintJobInfo getInfo();
+ method public boolean isBlocked();
+ method public boolean isCancelled();
+ method public boolean isCompleted();
+ method public boolean isFailed();
+ method public boolean isQueued();
+ method public boolean isStarted();
+ method public void restart();
}
public final class PrintJobId implements android.os.Parcelable {
@@ -19384,6 +19391,7 @@ package android.print {
method public int describeContents();
method public android.print.PrintAttributes getAttributes();
method public int getCopies();
+ method public long getCreationTime();
method public android.print.PrintJobId getId();
method public java.lang.String getLabel();
method public android.print.PageRange[] getPages();
diff --git a/core/java/android/print/IPrintJobStateChangeListener.aidl b/core/java/android/print/IPrintJobStateChangeListener.aidl
new file mode 100644
index 0000000..c1d39f0
--- /dev/null
+++ b/core/java/android/print/IPrintJobStateChangeListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print;
+
+import android.print.PrintJobId;
+
+/**
+ * Interface for observing print job state changes.
+ *
+ * @hide
+ */
+oneway interface IPrintJobStateChangeListener {
+ void onPrintJobStateChanged(in PrintJobId printJobId);
+}
diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl
index 4e839c6..4044b31 100644
--- a/core/java/android/print/IPrintManager.aidl
+++ b/core/java/android/print/IPrintManager.aidl
@@ -20,6 +20,7 @@ import android.print.IPrinterDiscoveryObserver;
import android.print.IPrintDocumentAdapter;
import android.print.IPrintClient;
import android.print.PrintJobId;
+import android.print.IPrintJobStateChangeListener;
import android.print.PrinterId;
import android.print.PrintJobInfo;
import android.print.PrintAttributes;
@@ -39,6 +40,11 @@ interface IPrintManager {
void cancelPrintJob(in PrintJobId printJobId, int appId, int userId);
void restartPrintJob(in PrintJobId printJobId, int appId, int userId);
+ void addPrintJobStateChangeListener(in IPrintJobStateChangeListener listener,
+ int appId, int userId);
+ void removePrintJobStateChangeListener(in IPrintJobStateChangeListener listener,
+ int userId);
+
List<PrintServiceInfo> getEnabledPrintServices(int userId);
void createPrinterDiscoverySession(in IPrinterDiscoveryObserver observer, int userId);
diff --git a/core/java/android/print/IPrintSpoolerClient.aidl b/core/java/android/print/IPrintSpoolerClient.aidl
index 8b511d6..0cf00cc 100644
--- a/core/java/android/print/IPrintSpoolerClient.aidl
+++ b/core/java/android/print/IPrintSpoolerClient.aidl
@@ -18,7 +18,7 @@ package android.print;
import android.content.ComponentName;
import android.print.PrintJobInfo;
-
+import android.print.PrintJobId;
/**
* Interface for receiving interesting state updates from the print spooler.
@@ -29,4 +29,5 @@ oneway interface IPrintSpoolerClient {
void onPrintJobQueued(in PrintJobInfo printJob);
void onAllPrintJobsForServiceHandled(in ComponentName printService);
void onAllPrintJobsHandled();
+ void onPrintJobStateChanged(in PrintJobId printJobId, int appId);
}
diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java
index 00ade07..535ae43 100644
--- a/core/java/android/print/PrintJob.java
+++ b/core/java/android/print/PrintJob.java
@@ -62,14 +62,110 @@ public final class PrintJob {
}
/**
- * Cancels this print job.
+ * Cancels this print job. You can request cancellation of a
+ * queued, started, blocked, or failed print job.
+ *
+ * @see #isQueued()
+ * @see #isStarted()
+ * @see #isBlocked()
+ * @see #isFailed()
*/
public void cancel() {
- if (!isInImmutableState()) {
+ final int state = getInfo().getState();
+ if (state == PrintJobInfo.STATE_QUEUED
+ || state == PrintJobInfo.STATE_STARTED
+ || state == PrintJobInfo.STATE_BLOCKED
+ || state == PrintJobInfo.STATE_FAILED) {
mPrintManager.cancelPrintJob(mCachedInfo.getId());
}
}
+ /**
+ * Restarts this print job. You can request restart of a failed
+ * print job.
+ *
+ * @see #isFailed()
+ */
+ public void restart() {
+ if (isFailed()) {
+ mPrintManager.restartPrintJob(mCachedInfo.getId());
+ }
+ }
+
+ /**
+ * Gets whether this print job is queued. Such a print job is
+ * ready to be printed. You can request a cancellation via
+ * {@link #cancel()}.
+ *
+ * @return Whether the print job is queued.
+ *
+ * @see #cancel()
+ */
+ public boolean isQueued() {
+ return getInfo().getState() == PrintJobInfo.STATE_QUEUED;
+ }
+
+ /**
+ * Gets whether this print job is started. Such a print job is
+ * being printed. You can request a cancellation via
+ * {@link #cancel()}.
+ *
+ * @return Whether the print job is started.
+ *
+ * @see #cancel()
+ */
+ public boolean isStarted() {
+ return getInfo().getState() == PrintJobInfo.STATE_STARTED;
+ }
+
+ /**
+ * Gets whether this print job is blocked. Such a print job is halted
+ * due to an abnormal condition. You can request a cancellation via
+ * {@link #cancel()}.
+ *
+ * @return Whether the print job is blocked.
+ *
+ * @see #cancel()
+ */
+ public boolean isBlocked() {
+ return getInfo().getState() == PrintJobInfo.STATE_BLOCKED;
+ }
+
+ /**
+ * Gets whether this print job is completed. Such a print job
+ * is successfully printed. You can neither cancel nor restart
+ * such a print job.
+ *
+ * @return Whether the print job is completed.
+ */
+ public boolean isCompleted() {
+ return getInfo().getState() == PrintJobInfo.STATE_COMPLETED;
+ }
+
+ /**
+ * Gets whether this print job is failed. Such a print job is
+ * not successfully printed due to an error. You can request
+ * a restart via {@link #restart()}.
+ *
+ * @return Whether the print job is failed.
+ *
+ * @see #restart()
+ */
+ public boolean isFailed() {
+ return getInfo().getState() == PrintJobInfo.STATE_FAILED;
+ }
+
+ /**
+ * Gets whether this print job is cancelled. Such a print job was
+ * cancelled as a result of a user request. This is a final state.
+ * You cannot restart such a print job.
+ *
+ * @return Whether the print job is cancelled.
+ */
+ public boolean isCancelled() {
+ return getInfo().getState() == PrintJobInfo.STATE_CANCELED;
+ }
+
private boolean isInImmutableState() {
final int state = mCachedInfo.getState();
return state == PrintJobInfo.STATE_COMPLETED
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index 502a9f2..e5d06a2 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -138,6 +138,9 @@ public final class PrintJobInfo implements Parcelable {
/** Optional tag assigned by a print service.*/
private String mTag;
+ /** The wall time when the print job was created. */
+ private long mCreationTime;
+
/** How many copies to print. */
private int mCopies;
@@ -168,6 +171,7 @@ public final class PrintJobInfo implements Parcelable {
mAppId = other.mAppId;
mUserId = other.mUserId;
mTag = other.mTag;
+ mCreationTime = other.mCreationTime;
mCopies = other.mCopies;
mStateReason = other.mStateReason;
mPageRanges = other.mPageRanges;
@@ -184,6 +188,7 @@ public final class PrintJobInfo implements Parcelable {
mAppId = parcel.readInt();
mUserId = parcel.readInt();
mTag = parcel.readString();
+ mCreationTime = parcel.readLong();
mCopies = parcel.readInt();
mStateReason = parcel.readString();
if (parcel.readInt() == 1) {
@@ -368,6 +373,29 @@ public final class PrintJobInfo implements Parcelable {
}
/**
+ * Gets the wall time in millisecond when this print job was created.
+ *
+ * @return The creation time in milliseconds.
+ */
+ public long getCreationTime() {
+ return mCreationTime;
+ }
+
+ /**
+ * Sets the wall time in milliseconds when this print job was created.
+ *
+ * @param creationTime The creation time in milliseconds.
+ *
+ * @hide
+ */
+ public void setCreationTime(long creationTime) {
+ if (creationTime < 0) {
+ throw new IllegalArgumentException("creationTime must be non-negative.");
+ }
+ mCreationTime = creationTime;
+ }
+
+ /**
* Gets the number of copies.
*
* @return The number of copies or zero if not set.
@@ -491,6 +519,7 @@ public final class PrintJobInfo implements Parcelable {
parcel.writeInt(mAppId);
parcel.writeInt(mUserId);
parcel.writeString(mTag);
+ parcel.writeLong(mCreationTime);
parcel.writeInt(mCopies);
parcel.writeString(mStateReason);
if (mPageRanges != null) {
@@ -522,6 +551,7 @@ public final class PrintJobInfo implements Parcelable {
builder.append(", status: ").append(stateToString(mState));
builder.append(", printer: " + mPrinterId);
builder.append(", tag: ").append(mTag);
+ builder.append(", creationTime: " + mCreationTime);
builder.append(", copies: ").append(mCopies);
builder.append(", attributes: " + (mAttributes != null
? mAttributes.toString() : null));
@@ -537,7 +567,7 @@ public final class PrintJobInfo implements Parcelable {
public static String stateToString(int state) {
switch (state) {
case STATE_CREATED: {
- return "STATUS_CREATED";
+ return "STATE_CREATED";
}
case STATE_QUEUED: {
return "STATE_QUEUED";
@@ -546,21 +576,20 @@ public final class PrintJobInfo implements Parcelable {
return "STATE_STARTED";
}
case STATE_FAILED: {
- return "STATUS_FAILED";
+ return "STATE_FAILED";
}
case STATE_COMPLETED: {
- return "STATUS_COMPLETED";
+ return "STATE_COMPLETED";
}
case STATE_CANCELED: {
- return "STATUS_CANCELED";
+ return "STATE_CANCELED";
}
default: {
- return "STATUS_UNKNOWN";
+ return "STATE_UNKNOWN";
}
}
}
-
public static final Parcelable.Creator<PrintJobInfo> CREATOR =
new Creator<PrintJobInfo>() {
@Override
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 5429155..a015388 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -30,6 +30,7 @@ import android.print.PrintDocumentAdapter.LayoutResultCallback;
import android.print.PrintDocumentAdapter.WriteResultCallback;
import android.printservice.PrintServiceInfo;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.os.SomeArgs;
@@ -40,6 +41,7 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* System level service for accessing the printing capabilities of the platform.
@@ -70,6 +72,19 @@ public final class PrintManager {
private final Handler mHandler;
+ private Map<PrintJobStateChangeListener, PrintJobStateChangeListenerWrapper> mPrintJobStateChangeListeners;
+
+ /** @hide */
+ public interface PrintJobStateChangeListener {
+
+ /**
+ * Callback notifying that a print job state changed.
+ *
+ * @param printJobId The print job id.
+ */
+ public void onPrintJobsStateChanged(PrintJobId printJobId);
+ }
+
/**
* Creates a new instance.
*
@@ -106,7 +121,6 @@ public final class PrintManager {
* @param userId The user id for which to get all print jobs.
* @return An instance if the caller has the permission to access
* all print jobs, null otherwise.
- *
* @hide
*/
public PrintManager getGlobalPrintManagerForUser(int userId) {
@@ -123,6 +137,75 @@ public final class PrintManager {
}
/**
+ * Adds a listener for observing the state of print jobs.
+ *
+ * @param listener The listener to add.
+ *
+ * @hide
+ */
+ public void addPrintJobStateChangeListener(PrintJobStateChangeListener listener) {
+ if (mPrintJobStateChangeListeners == null) {
+ mPrintJobStateChangeListeners = new ArrayMap<PrintJobStateChangeListener,
+ PrintJobStateChangeListenerWrapper>();
+ }
+ PrintJobStateChangeListenerWrapper wrappedListener =
+ new PrintJobStateChangeListenerWrapper(listener);
+ try {
+ mService.addPrintJobStateChangeListener(wrappedListener, mAppId, mUserId);
+ mPrintJobStateChangeListeners.put(listener, wrappedListener);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error adding print job state change listener", re);
+ }
+ }
+
+ /**
+ * Removes a listener for observing the state of print jobs.
+ *
+ * @param listener The listener to remove.
+ *
+ * @hide
+ */
+ public void removePrintJobStateChangeListener(PrintJobStateChangeListener listener) {
+ if (mPrintJobStateChangeListeners == null) {
+ return;
+ }
+ PrintJobStateChangeListenerWrapper wrappedListener =
+ mPrintJobStateChangeListeners.remove(listener);
+ if (wrappedListener == null) {
+ return;
+ }
+ if (mPrintJobStateChangeListeners.isEmpty()) {
+ mPrintJobStateChangeListeners = null;
+ }
+ try {
+ mService.removePrintJobStateChangeListener(wrappedListener, mUserId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error removing print job state change listener", re);
+ }
+ }
+
+ /**
+ * Gets a print job given its id.
+ *
+ * @return The print job list.
+ *
+ * @see PrintJob
+ *
+ * @hide
+ */
+ public PrintJob getPrintJob(PrintJobId printJobId) {
+ try {
+ PrintJobInfo printJob = mService.getPrintJobInfo(printJobId, mAppId, mUserId);
+ if (printJob != null) {
+ return new PrintJob(printJob, this);
+ }
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error getting print job", re);
+ }
+ return null;
+ }
+
+ /**
* Gets the print jobs for this application.
*
* @return The print job list.
@@ -155,6 +238,14 @@ public final class PrintManager {
}
}
+ void restartPrintJob(PrintJobId printJobId) {
+ try {
+ mService.restartPrintJob(printJobId, mAppId, mUserId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error restarting a print job: " + printJobId, re);
+ }
+ }
+
/**
* Creates a print job for printing a {@link PrintDocumentAdapter} with default print
* attributes.
@@ -163,7 +254,6 @@ public final class PrintManager {
* @param documentAdapter An adapter that emits the document to print.
* @param attributes The default print job attributes.
* @return The created print job on success or null on failure.
- *
* @see PrintJob
*/
public PrintJob print(String printJobName, PrintDocumentAdapter documentAdapter,
@@ -220,11 +310,11 @@ public final class PrintManager {
}
@Override
- public void startPrintJobConfigActivity(IntentSender intent) {
+ public void startPrintJobConfigActivity(IntentSender intent) {
PrintManager manager = mWeakPrintManager.get();
if (manager != null) {
SomeArgs args = SomeArgs.obtain();
- args.arg1 = manager.mContext;
+ args.arg1 = manager.mContext;
args.arg2 = intent;
manager.mHandler.obtainMessage(0, args).sendToTarget();
}
@@ -271,7 +361,7 @@ public final class PrintManager {
@Override
public void write(PageRange[] pages, ParcelFileDescriptor fd,
- IWriteResultCallback callback, int sequence) {
+ IWriteResultCallback callback, int sequence) {
synchronized (mLock) {
if (mLayoutOrWriteCancellation != null) {
mLayoutOrWriteCancellation.cancel();
@@ -492,4 +582,21 @@ public final class PrintManager {
}
}
}
+
+ private static final class PrintJobStateChangeListenerWrapper extends
+ IPrintJobStateChangeListener.Stub {
+ private final WeakReference<PrintJobStateChangeListener> mWeakListener;
+
+ public PrintJobStateChangeListenerWrapper(PrintJobStateChangeListener listener) {
+ mWeakListener = new WeakReference<PrintJobStateChangeListener>(listener);
+ }
+
+ @Override
+ public void onPrintJobStateChanged(PrintJobId printJobId) {
+ PrintJobStateChangeListener listener = mWeakListener.get();
+ if (listener != null) {
+ listener.onPrintJobsStateChanged(printJobId);
+ }
+ }
+ }
}
diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java
index a51e28b..ad79a38 100644
--- a/core/java/android/print/PrinterInfo.java
+++ b/core/java/android/print/PrinterInfo.java
@@ -302,7 +302,7 @@ public final class PrinterInfo implements Parcelable {
private boolean isValidStatus(int status) {
return (status == STATUS_IDLE
- || status == STATUS_IDLE
+ || status == STATUS_BUSY
|| status == STATUS_UNAVAILABLE);
}
}
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
index 2fcae6b..721e31e 100644
--- a/core/java/android/printservice/PrintJob.java
+++ b/core/java/android/printservice/PrintJob.java
@@ -175,7 +175,7 @@ public final class PrintJob {
*/
public boolean isCancelled() {
PrintService.throwIfNotCalledOnMainThread();
- return getInfo().getState() == PrintJobInfo.STATE_FAILED;
+ return getInfo().getState() == PrintJobInfo.STATE_CANCELED;
}
/**
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png b/core/res/res/drawable-hdpi/ic_print_error.png
index 7846a78..7846a78 100644
--- a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png
+++ b/core/res/res/drawable-hdpi/ic_print_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png b/core/res/res/drawable-mdpi/ic_print_error.png
index 44109eb..44109eb 100644
--- a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png
+++ b/core/res/res/drawable-mdpi/ic_print_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png b/core/res/res/drawable-xhdpi/ic_print_error.png
index c3faa42..c3faa42 100644
--- a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png
+++ b/core/res/res/drawable-xhdpi/ic_print_error.png
Binary files differ
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 57a4bb7..2e991d7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1037,6 +1037,7 @@
<java-symbol type="drawable" name="ic_media_stop" />
<java-symbol type="drawable" name="ic_text_dot" />
<java-symbol type="drawable" name="ic_print" />
+ <java-symbol type="drawable" name="ic_print_error" />
<java-symbol type="drawable" name="indicator_code_lock_drag_direction_green_up" />
<java-symbol type="drawable" name="indicator_code_lock_drag_direction_red_up" />
<java-symbol type="drawable" name="indicator_code_lock_point_area_default_holo" />
diff --git a/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml b/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
index 65d1ee7..c3c5021 100644
--- a/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
+++ b/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
@@ -45,7 +45,7 @@
android:ellipsize="end"
android:textIsSelectable="false"
android:visibility="gone"
- android:textColor="@color/item_text_color"
+ android:textColor="@color/print_option_title"
android:duplicateParentState="true">
</TextView>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
index 25bb071..dae7770 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
@@ -32,7 +32,7 @@ import android.print.IPrintManager;
import android.print.PrintJobId;
import android.print.PrintJobInfo;
import android.print.PrintManager;
-import android.text.TextUtils;
+import android.provider.Settings;
import android.util.Log;
/**
@@ -47,9 +47,9 @@ public class NotificationController {
private static final String INTENT_ACTION_CANCEL_PRINTJOB = "INTENT_ACTION_CANCEL_PRINTJOB";
private static final String INTENT_ACTION_RESTART_PRINTJOB = "INTENT_ACTION_RESTART_PRINTJOB";
- private static final String INTENT_EXTRA_PRINTJOB_ID = "INTENT_EXTRA_PRINTJOB_ID";
- private static final String INTENT_EXTRA_PRINTJOB_LABEL = "INTENT_EXTRA_PRINTJOB_LABEL";
- private static final String INTENT_EXTRA_PRINTER_NAME = "INTENT_EXTRA_PRINTER_NAME";
+ private static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
+ private static final String EXTRA_PRINTJOB_LABEL = "EXTRA_PRINTJOB_LABEL";
+ private static final String EXTRA_PRINTER_NAME = "EXTRA_PRINTER_NAME";
private final Context mContext;
private final NotificationManager mNotificationManager;
@@ -89,6 +89,7 @@ public class NotificationController {
private void createPrintingNotification(PrintJobInfo printJob) {
Notification.Builder builder = new Notification.Builder(mContext)
+ .setContentIntent(createContentIntent(printJob.getId()))
.setSmallIcon(com.android.internal.R.drawable.ic_print)
.setContentTitle(mContext.getString(R.string.printing_notification_title_template,
printJob.getLabel()))
@@ -102,18 +103,16 @@ public class NotificationController {
}
private void createFailedNotification(PrintJobInfo printJob) {
- String reason = !TextUtils.isEmpty(printJob.getStateReason())
- ? printJob.getStateReason() : mContext.getString(R.string.reason_unknown);
-
Notification.Builder builder = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.stat_notify_error)
+ .setContentIntent(createContentIntent(printJob.getId()))
+ .setSmallIcon(com.android.internal.R.drawable.ic_print_error)
.setContentTitle(mContext.getString(R.string.failed_notification_title_template,
printJob.getLabel()))
.addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
createCancelIntent(printJob))
.addAction(android.R.drawable.ic_secure, mContext.getString(R.string.restart),
createRestartIntent(printJob.getId()))
- .setContentText(reason)
+ .setContentText(printJob.getPrinterName())
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setShowWhen(true);
@@ -121,16 +120,14 @@ public class NotificationController {
}
private void createBlockedNotification(PrintJobInfo printJob) {
- String reason = !TextUtils.isEmpty(printJob.getStateReason())
- ? printJob.getStateReason() : mContext.getString(R.string.reason_unknown);
-
Notification.Builder builder = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.stat_notify_error)
+ .setContentIntent(createContentIntent(printJob.getId()))
+ .setSmallIcon(com.android.internal.R.drawable.ic_print_error)
.setContentTitle(mContext.getString(R.string.blocked_notification_title_template,
printJob.getLabel()))
.addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
createCancelIntent(printJob))
- .setContentText(reason)
+ .setContentText(printJob.getPrinterName())
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setShowWhen(true);
@@ -141,19 +138,25 @@ public class NotificationController {
mNotificationManager.cancel(printJobId.flattenToString(), 0);
}
+ private PendingIntent createContentIntent(PrintJobId printJobId) {
+ Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS);
+ intent.putExtra(EXTRA_PRINT_JOB_ID, printJobId.flattenToString());
+ return PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+ }
+
private PendingIntent createCancelIntent(PrintJobInfo printJob) {
Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + printJob.getId().flattenToString());
- intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJob.getId());
- intent.putExtra(INTENT_EXTRA_PRINTJOB_LABEL, printJob.getLabel());
- intent.putExtra(INTENT_EXTRA_PRINTER_NAME, printJob.getPrinterName());
+ intent.putExtra(EXTRA_PRINT_JOB_ID, printJob.getId());
+ intent.putExtra(EXTRA_PRINTJOB_LABEL, printJob.getLabel());
+ intent.putExtra(EXTRA_PRINTER_NAME, printJob.getPrinterName());
return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
}
private PendingIntent createRestartIntent(PrintJobId printJobId) {
Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + printJobId.flattenToString());
- intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJobId);
+ intent.putExtra(EXTRA_PRINT_JOB_ID, printJobId);
return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
}
@@ -164,12 +167,12 @@ public class NotificationController {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null && action.startsWith(INTENT_ACTION_CANCEL_PRINTJOB)) {
- PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID);
- String printJobLabel = intent.getExtras().getString(INTENT_EXTRA_PRINTJOB_LABEL);
- String printerName = intent.getExtras().getString(INTENT_EXTRA_PRINTER_NAME);
+ PrintJobId printJobId = intent.getExtras().getParcelable(EXTRA_PRINT_JOB_ID);
+ String printJobLabel = intent.getExtras().getString(EXTRA_PRINTJOB_LABEL);
+ String printerName = intent.getExtras().getString(EXTRA_PRINTER_NAME);
handleCancelPrintJob(context, printJobId, printJobLabel, printerName);
} else if (action != null && action.startsWith(INTENT_ACTION_RESTART_PRINTJOB)) {
- PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID);
+ PrintJobId printJobId = intent.getExtras().getParcelable(EXTRA_PRINT_JOB_ID);
handleRestartPrintJob(context, printJobId);
}
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
index ce1f6ec..62b35fe 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
@@ -155,23 +155,33 @@ public final class PrintSpoolerService extends Service {
@SuppressWarnings("deprecation")
@Override
public void createPrintJob(PrintJobInfo printJob, IPrintClient client,
- IPrintDocumentAdapter printAdapter) throws RemoteException {
- PrintSpoolerService.this.createPrintJob(printJob);
-
- Intent intent = new Intent(printJob.getId().flattenToString());
- intent.setClass(PrintSpoolerService.this, PrintJobConfigActivity.class);
- intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
- printAdapter.asBinder());
- intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB, printJob);
-
- IntentSender sender = PendingIntent.getActivity(
- PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
- | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
-
- Message message = mHandlerCaller.obtainMessageOO(
- HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
- client, sender);
- mHandlerCaller.executeOrSendMessage(message);
+ IPrintDocumentAdapter printAdapter) throws RemoteException {
+ PrintSpoolerService.this.createPrintJob(printJob);
+
+ Intent intent = new Intent(printJob.getId().flattenToString());
+ intent.setClass(PrintSpoolerService.this, PrintJobConfigActivity.class);
+ intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
+ printAdapter.asBinder());
+ intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB, printJob);
+
+ IntentSender sender = PendingIntent.getActivity(
+ PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
+ | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
+
+ Message message = mHandlerCaller.obtainMessageIIO(
+ HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
+ printJob.getAppId(), 0, printJob.getId());
+ mHandlerCaller.executeOrSendMessage(message);
+
+ message = mHandlerCaller.obtainMessageOO(
+ HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
+ client, sender);
+ mHandlerCaller.executeOrSendMessage(message);
+
+ printJob.setCreationTime(System.currentTimeMillis());
+ synchronized (mLock) {
+ mPersistanceManager.writeStateLocked();
+ }
}
@Override
@@ -240,12 +250,13 @@ public final class PrintSpoolerService extends Service {
}
private final class HandlerCallerCallback implements HandlerCaller.Callback {
- public static final int MSG_SET_CLIENT = 9;
- public static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 10;
- public static final int MSG_ON_PRINT_JOB_QUEUED = 11;
- public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 12;
- public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 13;
- public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 14;
+ public static final int MSG_SET_CLIENT = 1;
+ public static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 2;
+ public static final int MSG_ON_PRINT_JOB_QUEUED = 3;
+ public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 4;
+ public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 5;
+ public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 6;
+ public static final int MSG_ON_PRINT_JOB_STATE_CHANGED = 7;
@Override
public void executeMessage(Message message) {
@@ -310,6 +321,18 @@ public final class PrintSpoolerService extends Service {
case MSG_CHECK_ALL_PRINTJOBS_HANDLED: {
checkAllPrintJobsHandled();
} break;
+
+ case MSG_ON_PRINT_JOB_STATE_CHANGED: {
+ if (mClient != null) {
+ PrintJobId printJobId = (PrintJobId) message.obj;
+ final int appId = message.arg1;
+ try {
+ mClient.onPrintJobStateChanged(printJobId, appId);
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG, "Error notify for print job state change.", re);
+ }
+ }
+ } break;
}
}
}
@@ -511,6 +534,11 @@ public final class PrintSpoolerService extends Service {
synchronized (mLock) {
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
if (printJob != null) {
+ final int oldState = printJob.getState();
+ if (oldState == state) {
+ return false;
+ }
+
success = true;
printJob.setState(state);
@@ -553,6 +581,11 @@ public final class PrintSpoolerService extends Service {
if (!hasActivePrintJobsLocked()) {
notifyOnAllPrintJobsHandled();
}
+
+ Message message = mHandlerCaller.obtainMessageIIO(
+ HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
+ printJob.getAppId(), 0, printJob.getId());
+ mHandlerCaller.executeOrSendMessage(message);
}
}
@@ -706,7 +739,10 @@ public final class PrintSpoolerService extends Service {
private static final String ATTR_APP_ID = "appId";
private static final String ATTR_USER_ID = "userId";
private static final String ATTR_TAG = "tag";
+ private static final String ATTR_CREATION_TIME = "creationTime";
private static final String ATTR_COPIES = "copies";
+ private static final String ATTR_PRINTER_NAME = "printerName";
+ private static final String ATTR_STATE_REASON = "stateReason";
private static final String TAG_MEDIA_SIZE = "mediaSize";
private static final String TAG_RESOLUTION = "resolution";
@@ -714,7 +750,7 @@ public final class PrintSpoolerService extends Service {
private static final String ATTR_COLOR_MODE = "colorMode";
- private static final String ATTR_LOCAL_ID = "printerName";
+ private static final String ATTR_LOCAL_ID = "localId";
private static final String ATTR_SERVICE_NAME = "serviceName";
private static final String ATTR_WIDTH_MILS = "widthMils";
@@ -794,7 +830,17 @@ public final class PrintSpoolerService extends Service {
if (tag != null) {
serializer.attribute(null, ATTR_TAG, tag);
}
+ serializer.attribute(null, ATTR_CREATION_TIME, String.valueOf(
+ printJob.getCreationTime()));
serializer.attribute(null, ATTR_COPIES, String.valueOf(printJob.getCopies()));
+ String printerName = printJob.getPrinterName();
+ if (!TextUtils.isEmpty(printerName)) {
+ serializer.attribute(null, ATTR_PRINTER_NAME, printerName);
+ }
+ String stateReason = printJob.getStateReason();
+ if (!TextUtils.isEmpty(stateReason)) {
+ serializer.attribute(null, ATTR_STATE_REASON, stateReason);
+ }
PrinterId printerId = printJob.getPrinterId();
if (printerId != null) {
@@ -979,8 +1025,14 @@ public final class PrintSpoolerService extends Service {
printJob.setUserId(userId);
String tag = parser.getAttributeValue(null, ATTR_TAG);
printJob.setTag(tag);
+ String creationTime = parser.getAttributeValue(null, ATTR_CREATION_TIME);
+ printJob.setCreationTime(Long.parseLong(creationTime));
String copies = parser.getAttributeValue(null, ATTR_COPIES);
printJob.setCopies(Integer.parseInt(copies));
+ String printerName = parser.getAttributeValue(null, ATTR_PRINTER_NAME);
+ printJob.setPrinterName(printerName);
+ String stateReason = parser.getAttributeValue(null, ATTR_STATE_REASON);
+ printJob.setStateReason(stateReason);
parser.next();
diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java
index 5f8708a..625770c 100644
--- a/services/java/com/android/server/print/PrintManagerService.java
+++ b/services/java/com/android/server/print/PrintManagerService.java
@@ -32,9 +32,11 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.print.IPrintClient;
import android.print.IPrintDocumentAdapter;
+import android.print.IPrintJobStateChangeListener;
import android.print.IPrintManager;
import android.print.IPrinterDiscoveryObserver;
import android.print.PrintAttributes;
@@ -300,6 +302,39 @@ public final class PrintManagerService extends IPrintManager.Stub {
}
@Override
+ public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
+ int appId, int userId) throws RemoteException {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.addPrintJobStateChangeListener(listener, resolvedAppId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener,
+ int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.removePrintJobStateChangeListener(listener);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/services/java/com/android/server/print/RemotePrintSpooler.java b/services/java/com/android/server/print/RemotePrintSpooler.java
index 1bde6d7..f98a805 100644
--- a/services/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/java/com/android/server/print/RemotePrintSpooler.java
@@ -91,6 +91,7 @@ final class RemotePrintSpooler {
public static interface PrintSpoolerCallbacks {
public void onPrintJobQueued(PrintJobInfo printJob);
public void onAllPrintJobsForServiceHandled(ComponentName printService);
+ public void onPrintJobStateChanged(PrintJobId printJobId, int appId);
}
public RemotePrintSpooler(Context context, int userId,
@@ -345,6 +346,10 @@ final class RemotePrintSpooler {
}
}
+ private void onPrintJobStateChanged(PrintJobId printJobId, int appId) {
+ mCallbacks.onPrintJobStateChanged(printJobId, appId);
+ }
+
private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException {
synchronized (mLock) {
if (mRemoteInstance != null) {
@@ -618,5 +623,18 @@ final class RemotePrintSpooler {
}
}
}
+
+ @Override
+ public void onPrintJobStateChanged(PrintJobId printJobId, int appId) {
+ RemotePrintSpooler spooler = mWeakSpooler.get();
+ if (spooler != null) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ spooler.onPrintJobStateChanged(printJobId, appId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
}
}
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index 8c21827..e5f5842 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -36,6 +36,7 @@ import android.os.RemoteException;
import android.os.UserManager;
import android.print.IPrintClient;
import android.print.IPrintDocumentAdapter;
+import android.print.IPrintJobStateChangeListener;
import android.print.IPrinterDiscoveryObserver;
import android.print.PrintAttributes;
import android.print.PrintJobId;
@@ -103,8 +104,12 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
private final RemotePrintSpooler mSpooler;
+ private final Handler mHandler;
+
private PrinterDiscoverySessionMediator mPrinterDiscoverySession;
+ private List<PrintJobStateChangeListenerRecord> mPrintJobStateChangeListenerRecords;
+
private boolean mDestroyed;
public UserState(Context context, int userId, Object lock) {
@@ -112,6 +117,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
mUserId = userId;
mLock = lock;
mSpooler = new RemotePrintSpooler(context, userId, this);
+ mHandler = new UserStateHandler(context.getMainLooper());
synchronized (mLock) {
enableSystemPrintServicesOnFirstBootLocked();
}
@@ -164,6 +170,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
printJob.setLabel(printJobName);
printJob.setAttributes(attributes);
printJob.setState(PrintJobInfo.STATE_CREATED);
+ printJob.setCopies(1);
// Spin the spooler to add the job and show the config UI.
new AsyncTask<Void, Void, Void>() {
@@ -351,6 +358,51 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
}
}
+ public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
+ int appId) throws RemoteException {
+ synchronized (mLock) {
+ throwIfDestroyedLocked();
+ if (mPrintJobStateChangeListenerRecords == null) {
+ mPrintJobStateChangeListenerRecords =
+ new ArrayList<PrintJobStateChangeListenerRecord>();
+ }
+ mPrintJobStateChangeListenerRecords.add(
+ new PrintJobStateChangeListenerRecord(listener, appId) {
+ @Override
+ public void onBinderDied() {
+ mPrintJobStateChangeListenerRecords.remove(this);
+ }
+ });
+ }
+ }
+
+ public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener) {
+ synchronized (mLock) {
+ throwIfDestroyedLocked();
+ if (mPrintJobStateChangeListenerRecords == null) {
+ return;
+ }
+ final int recordCount = mPrintJobStateChangeListenerRecords.size();
+ for (int i = 0; i < recordCount; i++) {
+ PrintJobStateChangeListenerRecord record =
+ mPrintJobStateChangeListenerRecords.get(i);
+ if (record.listener.asBinder().equals(listener.asBinder())) {
+ mPrintJobStateChangeListenerRecords.remove(i);
+ break;
+ }
+ }
+ if (mPrintJobStateChangeListenerRecords.isEmpty()) {
+ mPrintJobStateChangeListenerRecords = null;
+ }
+ }
+ }
+
+ @Override
+ public void onPrintJobStateChanged(PrintJobId printJobId, int appId) {
+ mHandler.obtainMessage(UserStateHandler.MSG_DISPATCH_PRINT_JOB_STATE_CHANGED,
+ appId, 0, printJobId).sendToTarget();
+ }
+
@Override
public void onPrintersAdded(List<PrinterInfo> printers) {
synchronized (mLock) {
@@ -698,6 +750,65 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
}
}
+ private void handleDispatchPrintJobStateChanged(PrintJobId printJobId, int appId) {
+ final List<PrintJobStateChangeListenerRecord> records;
+ synchronized (mLock) {
+ if (mPrintJobStateChangeListenerRecords == null) {
+ return;
+ }
+ records = new ArrayList<PrintJobStateChangeListenerRecord>(
+ mPrintJobStateChangeListenerRecords);
+ }
+ final int recordCount = records.size();
+ for (int i = 0; i < recordCount; i++) {
+ PrintJobStateChangeListenerRecord record = records.get(i);
+ if (record.appId == PrintManager.APP_ID_ANY
+ || record.appId == appId)
+ try {
+ record.listener.onPrintJobStateChanged(printJobId);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error notifying for print job state change", re);
+ }
+ }
+ }
+
+ private final class UserStateHandler extends Handler {
+ public static final int MSG_DISPATCH_PRINT_JOB_STATE_CHANGED = 1;
+
+ public UserStateHandler(Looper looper) {
+ super(looper, null, false);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == MSG_DISPATCH_PRINT_JOB_STATE_CHANGED) {
+ PrintJobId printJobId = (PrintJobId) message.obj;
+ final int appId = message.arg1;
+ handleDispatchPrintJobStateChanged(printJobId, appId);
+ }
+ }
+ }
+
+ private abstract class PrintJobStateChangeListenerRecord implements DeathRecipient {
+ final IPrintJobStateChangeListener listener;
+ final int appId;
+
+ public PrintJobStateChangeListenerRecord(IPrintJobStateChangeListener listener,
+ int appId) throws RemoteException {
+ this.listener = listener;
+ this.appId = appId;
+ listener.asBinder().linkToDeath(this, 0);
+ }
+
+ @Override
+ public void binderDied() {
+ listener.asBinder().unlinkToDeath(this, 0);
+ onBinderDied();
+ }
+
+ public abstract void onBinderDied();
+ }
+
private class PrinterDiscoverySessionMediator {
private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
new ArrayMap<PrinterId, PrinterInfo>();