Merge "App UI freezes when printing. API clean up." into klp-dev
This commit is contained in:
@@ -19174,15 +19174,21 @@ package android.print {
|
||||
|
||||
public final class PrintJob {
|
||||
method public void cancel();
|
||||
method public int getId();
|
||||
method public android.print.PrintJobId getId();
|
||||
method public android.print.PrintJobInfo getInfo();
|
||||
}
|
||||
|
||||
public final class PrintJobId implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator CREATOR;
|
||||
}
|
||||
|
||||
public final class PrintJobInfo implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.print.PrintAttributes getAttributes();
|
||||
method public int getCopies();
|
||||
method public int getId();
|
||||
method public android.print.PrintJobId getId();
|
||||
method public java.lang.String getLabel();
|
||||
method public android.print.PageRange[] getPages();
|
||||
method public android.print.PrinterId getPrinterId();
|
||||
@@ -19194,6 +19200,7 @@ package android.print {
|
||||
field public static final int STATE_BLOCKED = 4; // 0x4
|
||||
field public static final int STATE_CANCELED = 7; // 0x7
|
||||
field public static final int STATE_COMPLETED = 5; // 0x5
|
||||
field public static final int STATE_CREATED = 1; // 0x1
|
||||
field public static final int STATE_FAILED = 6; // 0x6
|
||||
field public static final int STATE_QUEUED = 2; // 0x2
|
||||
field public static final int STATE_STARTED = 3; // 0x3
|
||||
@@ -19201,7 +19208,6 @@ package android.print {
|
||||
|
||||
public final class PrintManager {
|
||||
method public java.util.List<android.print.PrintJob> getPrintJobs();
|
||||
method public android.print.PrintJob print(java.lang.String, java.io.File, android.print.PrintDocumentInfo, android.print.PrintAttributes);
|
||||
method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes);
|
||||
}
|
||||
|
||||
@@ -19312,7 +19318,7 @@ package android.printservice {
|
||||
method public boolean complete();
|
||||
method public boolean fail(java.lang.String);
|
||||
method public android.printservice.PrintDocument getDocument();
|
||||
method public int getId();
|
||||
method public android.print.PrintJobId getId();
|
||||
method public android.print.PrintJobInfo getInfo();
|
||||
method public boolean isBlocked();
|
||||
method public boolean isCancelled();
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.print;
|
||||
import android.print.IPrinterDiscoveryObserver;
|
||||
import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrintClient;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintAttributes;
|
||||
@@ -31,12 +32,12 @@ import android.printservice.PrintServiceInfo;
|
||||
*/
|
||||
interface IPrintManager {
|
||||
List<PrintJobInfo> getPrintJobInfos(int appId, int userId);
|
||||
PrintJobInfo getPrintJobInfo(int printJobId, int appId, int userId);
|
||||
PrintJobInfo getPrintJobInfo(in PrintJobId printJobId, int appId, int userId);
|
||||
PrintJobInfo print(String printJobName, in IPrintClient client,
|
||||
in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
|
||||
int appId, int userId);
|
||||
void cancelPrintJob(int printJobId, int appId, int userId);
|
||||
void restartPrintJob(int printJobId, int appId, int userId);
|
||||
void cancelPrintJob(in PrintJobId printJobId, int appId, int userId);
|
||||
void restartPrintJob(in PrintJobId printJobId, int appId, int userId);
|
||||
|
||||
List<PrintServiceInfo> getEnabledPrintServices(int userId);
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.print.IPrintSpoolerClient;
|
||||
import android.print.IPrintSpoolerCallbacks;
|
||||
import android.print.PrinterInfo;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
|
||||
/**
|
||||
* Interface for communication with the print spooler service.
|
||||
@@ -33,17 +35,18 @@ import android.print.PrintAttributes;
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IPrintSpooler {
|
||||
void removeObsoletePrintJobs();
|
||||
void forgetPrintJobs(in List<PrintJobId> printJob);
|
||||
void getPrintJobInfos(IPrintSpoolerCallbacks callback, in ComponentName componentName,
|
||||
int state, int appId, int sequence);
|
||||
void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback,
|
||||
void getPrintJobInfo(in PrintJobId printJobId, IPrintSpoolerCallbacks callback,
|
||||
int appId, int sequence);
|
||||
void createPrintJob(String printJobName, in IPrintClient client,
|
||||
in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
|
||||
IPrintSpoolerCallbacks callback, int appId, int sequence);
|
||||
void setPrintJobState(int printJobId, int status, String error,
|
||||
void createPrintJob(in PrintJobInfo printJob, in IPrintClient client,
|
||||
in IPrintDocumentAdapter printAdapter);
|
||||
void setPrintJobState(in PrintJobId printJobId, int status, String stateReason,
|
||||
IPrintSpoolerCallbacks callback, int sequence);
|
||||
void setPrintJobTag(int printJobId, String tag, IPrintSpoolerCallbacks callback,
|
||||
void setPrintJobTag(in PrintJobId printJobId, String tag, IPrintSpoolerCallbacks callback,
|
||||
int sequence);
|
||||
void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
|
||||
void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);
|
||||
void setClient(IPrintSpoolerClient client);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.List;
|
||||
*/
|
||||
oneway interface IPrintSpoolerCallbacks {
|
||||
void onGetPrintJobInfosResult(in List<PrintJobInfo> printJob, int sequence);
|
||||
void onCreatePrintJobResult(in PrintJobInfo printJob, int sequence);
|
||||
void onCancelPrintJobResult(boolean canceled, int sequence);
|
||||
void onSetPrintJobStateResult(boolean success, int sequence);
|
||||
void onSetPrintJobTagResult(boolean success, int sequence);
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.print;
|
||||
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
|
||||
/**
|
||||
* Interface for observing discovered printers by a discovery session.
|
||||
@@ -25,6 +26,6 @@ import android.print.PrinterInfo;
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IPrinterDiscoveryObserver {
|
||||
void onPrintersAdded(in List<PrinterInfo> printers);
|
||||
void onPrintersRemoved(in List<PrinterId> printerIds);
|
||||
void onPrintersAdded(in ParceledListSlice printers);
|
||||
void onPrintersRemoved(in ParceledListSlice printerIds);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ package android.print;
|
||||
*/
|
||||
public final class PrintJob {
|
||||
|
||||
private final int mId;
|
||||
|
||||
private final PrintManager mPrintManager;
|
||||
|
||||
private PrintJobInfo mCachedInfo;
|
||||
@@ -31,7 +29,6 @@ public final class PrintJob {
|
||||
PrintJob(PrintJobInfo info, PrintManager printManager) {
|
||||
mCachedInfo = info;
|
||||
mPrintManager = printManager;
|
||||
mId = info.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,8 +36,8 @@ public final class PrintJob {
|
||||
*
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
public PrintJobId getId() {
|
||||
return mCachedInfo.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +54,7 @@ public final class PrintJob {
|
||||
if (isInImmutableState()) {
|
||||
return mCachedInfo;
|
||||
}
|
||||
PrintJobInfo info = mPrintManager.getPrintJobInfo(mId);
|
||||
PrintJobInfo info = mPrintManager.getPrintJobInfo(mCachedInfo.getId());
|
||||
if (info != null) {
|
||||
mCachedInfo = info;
|
||||
}
|
||||
@@ -69,7 +66,7 @@ public final class PrintJob {
|
||||
*/
|
||||
public void cancel() {
|
||||
if (!isInImmutableState()) {
|
||||
mPrintManager.cancelPrintJob(mId);
|
||||
mPrintManager.cancelPrintJob(mCachedInfo.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +88,11 @@ public final class PrintJob {
|
||||
return false;
|
||||
}
|
||||
PrintJob other = (PrintJob) obj;
|
||||
return mId == other.mId;
|
||||
return mCachedInfo.getId().equals(other.mCachedInfo.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mId;
|
||||
return mCachedInfo.getId().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
19
core/java/android/print/PrintJobId.aidl
Normal file
19
core/java/android/print/PrintJobId.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
parcelable PrintJobId;
|
||||
122
core/java/android/print/PrintJobId.java
Normal file
122
core/java/android/print/PrintJobId.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This class represents the id of a print job.
|
||||
*/
|
||||
public final class PrintJobId implements Parcelable {
|
||||
private final String mValue;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public PrintJobId() {
|
||||
this(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param value The internal value.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public PrintJobId(String value) {
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((mValue != null) ? mValue.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
PrintJobId other = (PrintJobId) obj;
|
||||
if (!TextUtils.equals(mValue, other.mValue)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeString(mValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens this id to a string.
|
||||
*
|
||||
* @return The flattened id.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public String flattenToString() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unflattens a print job id from a string.
|
||||
*
|
||||
* @string The string.
|
||||
* @return The unflattened id, or null if the string is malformed.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static PrintJobId unflattenFromString(String string) {
|
||||
return new PrintJobId(string);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<PrintJobId> CREATOR =
|
||||
new Parcelable.Creator<PrintJobId>() {
|
||||
@Override
|
||||
public PrintJobId createFromParcel(Parcel parcel) {
|
||||
return new PrintJobId(parcel.readString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintJobId[] newArray(int size) {
|
||||
return new PrintJobId[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -56,8 +56,6 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* <p>
|
||||
* Next valid states: {@link #STATE_QUEUED}
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int STATE_CREATED = 1;
|
||||
|
||||
@@ -117,7 +115,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
public static final int STATE_CANCELED = 7;
|
||||
|
||||
/** The unique print job id. */
|
||||
private int mId;
|
||||
private PrintJobId mId;
|
||||
|
||||
/** The human readable print job label. */
|
||||
private String mLabel;
|
||||
@@ -178,7 +176,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
}
|
||||
|
||||
private PrintJobInfo(Parcel parcel) {
|
||||
mId = parcel.readInt();
|
||||
mId = parcel.readParcelable(null);
|
||||
mLabel = parcel.readString();
|
||||
mPrinterId = parcel.readParcelable(null);
|
||||
mPrinterName = parcel.readString();
|
||||
@@ -208,7 +206,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
*
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
public PrintJobId getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
@@ -219,7 +217,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setId(int id) {
|
||||
public void setId(PrintJobId id) {
|
||||
this.mId = id;
|
||||
}
|
||||
|
||||
@@ -485,7 +483,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeInt(mId);
|
||||
parcel.writeParcelable(mId, flags);
|
||||
parcel.writeString(mLabel);
|
||||
parcel.writeParcelable(mPrinterId, flags);
|
||||
parcel.writeString(mPrinterName);
|
||||
|
||||
@@ -36,7 +36,6 @@ import com.android.internal.os.SomeArgs;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -114,7 +113,7 @@ public final class PrintManager {
|
||||
return new PrintManager(mContext, mService, userId, APP_ID_ANY);
|
||||
}
|
||||
|
||||
PrintJobInfo getPrintJobInfo(int printJobId) {
|
||||
PrintJobInfo getPrintJobInfo(PrintJobId printJobId) {
|
||||
try {
|
||||
return mService.getPrintJobInfo(printJobId, mAppId, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
@@ -148,7 +147,7 @@ public final class PrintManager {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
void cancelPrintJob(int printJobId) {
|
||||
void cancelPrintJob(PrintJobId printJobId) {
|
||||
try {
|
||||
mService.cancelPrintJob(printJobId, mAppId, mUserId);
|
||||
} catch (RemoteException re) {
|
||||
@@ -156,24 +155,6 @@ public final class PrintManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a print job for printing a file with default print attributes.
|
||||
*
|
||||
* @param printJobName A name for the new print job.
|
||||
* @param pdfFile The PDF file to print.
|
||||
* @param documentInfo Information about the printed document.
|
||||
* @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, File pdfFile, PrintDocumentInfo documentInfo,
|
||||
PrintAttributes attributes) {
|
||||
PrintFileDocumentAdapter documentAdapter = new PrintFileDocumentAdapter(
|
||||
mContext, pdfFile, documentInfo);
|
||||
return print(printJobName, documentAdapter, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a print job for printing a {@link PrintDocumentAdapter} with default print
|
||||
* attributes.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.print;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -270,20 +271,22 @@ public final class PrinterDiscoverySession {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void onPrintersAdded(ParceledListSlice printers) {
|
||||
PrinterDiscoverySession session = mWeakSession.get();
|
||||
if (session != null) {
|
||||
session.mHandler.obtainMessage(MSG_PRINTERS_ADDED,
|
||||
printers).sendToTarget();
|
||||
printers.getList()).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void onPrintersRemoved(ParceledListSlice printerIds) {
|
||||
PrinterDiscoverySession session = mWeakSession.get();
|
||||
if (session != null) {
|
||||
session.mHandler.obtainMessage(MSG_PRINTERS_REMOVED,
|
||||
printerIds).sendToTarget();
|
||||
printerIds.getList()).sendToTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.print.PrintJobId;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
|
||||
/**
|
||||
* The top-level interface from a print service to the system.
|
||||
@@ -28,11 +30,11 @@ import android.print.PrinterInfo;
|
||||
*/
|
||||
interface IPrintServiceClient {
|
||||
List<PrintJobInfo> getPrintJobInfos();
|
||||
PrintJobInfo getPrintJobInfo(int printJobId);
|
||||
boolean setPrintJobState(int printJobId, int state, String error);
|
||||
boolean setPrintJobTag(int printJobId, String tag);
|
||||
oneway void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
|
||||
PrintJobInfo getPrintJobInfo(in PrintJobId printJobId);
|
||||
boolean setPrintJobState(in PrintJobId printJobId, int state, String error);
|
||||
boolean setPrintJobTag(in PrintJobId printJobId, String tag);
|
||||
oneway void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);
|
||||
|
||||
void onPrintersAdded(in List<PrinterInfo> printers);
|
||||
void onPrintersRemoved(in List<PrinterId> printerIds);
|
||||
void onPrintersAdded(in ParceledListSlice printers);
|
||||
void onPrintersRemoved(in ParceledListSlice printerIds);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.printservice;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.print.PrintDocumentInfo;
|
||||
import android.print.PrintJobId;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -35,13 +36,13 @@ public final class PrintDocument {
|
||||
|
||||
private static final String LOG_TAG = "PrintDocument";
|
||||
|
||||
private final int mPrintJobId;
|
||||
private final PrintJobId mPrintJobId;
|
||||
|
||||
private final IPrintServiceClient mPrintServiceClient;
|
||||
|
||||
private final PrintDocumentInfo mInfo;
|
||||
|
||||
PrintDocument(int printJobId, IPrintServiceClient printServiceClient,
|
||||
PrintDocument(PrintJobId printJobId, IPrintServiceClient printServiceClient,
|
||||
PrintDocumentInfo info) {
|
||||
mPrintJobId = printJobId;
|
||||
mPrintServiceClient = printServiceClient;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.printservice;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
@@ -52,7 +53,7 @@ public final class PrintJob {
|
||||
*
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
public PrintJobId getId() {
|
||||
PrintService.throwIfNotCalledOnMainThread();
|
||||
return mCachedInfo.getId();
|
||||
}
|
||||
@@ -312,12 +313,12 @@ public final class PrintJob {
|
||||
return false;
|
||||
}
|
||||
PrintJob other = (PrintJob) obj;
|
||||
return (mCachedInfo.getId() == other.mCachedInfo.getId());
|
||||
return (mCachedInfo.getId().equals(other.mCachedInfo.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mCachedInfo.getId();
|
||||
return mCachedInfo.getId().hashCode();
|
||||
}
|
||||
|
||||
private boolean isInImmutableState() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.printservice;
|
||||
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.os.RemoteException;
|
||||
import android.print.PrinterCapabilitiesInfo;
|
||||
import android.print.PrinterId;
|
||||
@@ -80,8 +81,6 @@ import java.util.List;
|
||||
public abstract class PrinterDiscoverySession {
|
||||
private static final String LOG_TAG = "PrinterDiscoverySession";
|
||||
|
||||
private static final int MAX_ITEMS_PER_CALLBACK = 50;
|
||||
|
||||
private static int sIdCounter = 0;
|
||||
|
||||
private final int mId;
|
||||
@@ -112,7 +111,11 @@ public abstract class PrinterDiscoverySession {
|
||||
// If some printers were added in the method that
|
||||
// created the session, send them over.
|
||||
if (!mPrinters.isEmpty()) {
|
||||
sendAddedPrinters(mObserver, getPrinters());
|
||||
try {
|
||||
mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(getPrinters()));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +187,11 @@ public abstract class PrinterDiscoverySession {
|
||||
|
||||
// Send the added printers, if such.
|
||||
if (addedPrinters != null) {
|
||||
sendAddedPrinters(mObserver, addedPrinters);
|
||||
try {
|
||||
mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remember the last sent printers if needed.
|
||||
@@ -203,27 +210,6 @@ public abstract class PrinterDiscoverySession {
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendAddedPrinters(IPrintServiceClient observer,
|
||||
List<PrinterInfo> printers) {
|
||||
try {
|
||||
final int printerCount = printers.size();
|
||||
if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
|
||||
observer.onPrintersAdded(printers);
|
||||
} else {
|
||||
// Send the added printers in chunks avoiding the binder transaction limit.
|
||||
final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
|
||||
for (int i = 0; i < transactionCount; i++) {
|
||||
final int start = i * MAX_ITEMS_PER_CALLBACK;
|
||||
final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
|
||||
List<PrinterInfo> subPrinters = printers.subList(start, end);
|
||||
observer.onPrintersAdded(subPrinters);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes added printers. Removing an already removed or never added
|
||||
* printer has no effect. Removed printers can be added again. You can
|
||||
@@ -261,7 +247,12 @@ public abstract class PrinterDiscoverySession {
|
||||
|
||||
// Send the removed printers, if such.
|
||||
if (!removedPrinterIds.isEmpty()) {
|
||||
sendRemovedPrinters(mObserver, removedPrinterIds);
|
||||
try {
|
||||
mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(
|
||||
removedPrinterIds));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending removed printers", re);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remember the last sent printers if needed.
|
||||
@@ -278,26 +269,6 @@ public abstract class PrinterDiscoverySession {
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendRemovedPrinters(IPrintServiceClient observer,
|
||||
List<PrinterId> printerIds) {
|
||||
try {
|
||||
final int printerIdCount = printerIds.size();
|
||||
if (printerIdCount <= MAX_ITEMS_PER_CALLBACK) {
|
||||
observer.onPrintersRemoved(printerIds);
|
||||
} else {
|
||||
final int transactionCount = (printerIdCount / MAX_ITEMS_PER_CALLBACK) + 1;
|
||||
for (int i = 0; i < transactionCount; i++) {
|
||||
final int start = i * MAX_ITEMS_PER_CALLBACK;
|
||||
final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerIdCount);
|
||||
List<PrinterId> subPrinterIds = printerIds.subList(start, end);
|
||||
observer.onPrintersRemoved(subPrinterIds);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending removed printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOutOfDiscoveryPeriodPrinterChanges() {
|
||||
// Noting changed since the last discovery period - nothing to do.
|
||||
if (mLastSentPrinters == null || mLastSentPrinters.isEmpty()) {
|
||||
@@ -319,7 +290,11 @@ public abstract class PrinterDiscoverySession {
|
||||
|
||||
// Send the added printers, if such.
|
||||
if (addedPrinters != null) {
|
||||
sendAddedPrinters(mObserver, addedPrinters);
|
||||
try {
|
||||
mObserver.onPrintersAdded(new ParceledListSlice<PrinterInfo>(addedPrinters));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the removed printers.
|
||||
@@ -335,7 +310,11 @@ public abstract class PrinterDiscoverySession {
|
||||
|
||||
// Send the removed printers, if such.
|
||||
if (removedPrinterIds != null) {
|
||||
sendRemovedPrinters(mObserver, removedPrinterIds);
|
||||
try {
|
||||
mObserver.onPrintersRemoved(new ParceledListSlice<PrinterId>(removedPrinterIds));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending removed printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
mLastSentPrinters = null;
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18"/>
|
||||
|
||||
<application
|
||||
android:allowClearUserData="false"
|
||||
android:allowClearUserData="true"
|
||||
android:label="@string/app_label"
|
||||
android:allowBackup= "false"
|
||||
android:supportsRtl="true">
|
||||
|
||||
@@ -139,18 +139,20 @@
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want
|
||||
to allow the application to do this. -->
|
||||
<string name="permlab_accessAllPrintJobs">access all print jobs</string>
|
||||
<string name="permlab_accessAllPrintJobs" translatable="false">access all print jobs</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether
|
||||
they want to allow the application to do this. -->
|
||||
<string name="permdesc_accessAllPrintJobs">Allows the holder to access print jobs
|
||||
created by another app. Should never be needed for normal apps.</string>
|
||||
<string name="permdesc_accessAllPrintJobs" translatable="false">Allows the holder to access
|
||||
print jobs created by another app. Should never be needed for normal apps.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want
|
||||
to allow the application to do this. -->
|
||||
<string name="permlab_startPrintServiceConfigActivity">start print service configuration activities</string>
|
||||
<string name="permlab_startPrintServiceConfigActivity" translatable="false">start print
|
||||
service configuration activities</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they
|
||||
want to allow the application to do this. -->
|
||||
<string name="permdesc_startPrintServiceConfigActivity">Allows the holder to start the
|
||||
configuration activities of a print service. Should never be needed for normal apps.</string>
|
||||
<string name="permdesc_startPrintServiceConfigActivity" translatable="false">Allows the
|
||||
holder to start the configuration activities of a print service. Should never be needed
|
||||
for normal apps.</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -23,13 +23,13 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.print.IPrintManager;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.text.TextUtils;
|
||||
@@ -40,12 +40,13 @@ import android.util.Log;
|
||||
* based on print job state transitions.
|
||||
*/
|
||||
public class NotificationController {
|
||||
public static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
|
||||
public static final boolean DEBUG = false;
|
||||
|
||||
public static final String LOG_TAG = "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";
|
||||
@@ -61,8 +62,9 @@ public class NotificationController {
|
||||
|
||||
public void onPrintJobStateChanged(PrintJobInfo printJob) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: " + printJob.getId()
|
||||
+ " state:" + PrintJobInfo.stateToString(printJob.getState()));
|
||||
Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: "
|
||||
+ printJob.getId().flattenToString() + " state:"
|
||||
+ PrintJobInfo.stateToString(printJob.getState()));
|
||||
}
|
||||
switch (printJob.getState()) {
|
||||
case PrintJobInfo.STATE_QUEUED:
|
||||
@@ -96,7 +98,7 @@ public class NotificationController {
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setOngoing(true)
|
||||
.setShowWhen(true);
|
||||
mNotificationManager.notify(printJob.getId(), builder.build());
|
||||
mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build());
|
||||
}
|
||||
|
||||
private void createFailedNotification(PrintJobInfo printJob) {
|
||||
@@ -115,7 +117,7 @@ public class NotificationController {
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setOngoing(true)
|
||||
.setShowWhen(true);
|
||||
mNotificationManager.notify(printJob.getId(), builder.build());
|
||||
mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build());
|
||||
}
|
||||
|
||||
private void createBlockedNotification(PrintJobInfo printJob) {
|
||||
@@ -132,25 +134,25 @@ public class NotificationController {
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setOngoing(true)
|
||||
.setShowWhen(true);
|
||||
mNotificationManager.notify(printJob.getId(), builder.build());
|
||||
mNotificationManager.notify(printJob.getId().flattenToString(), 0, builder.build());
|
||||
}
|
||||
|
||||
private void removeNotification(int printJobId) {
|
||||
mNotificationManager.cancel(printJobId);
|
||||
private void removeNotification(PrintJobId printJobId) {
|
||||
mNotificationManager.cancel(printJobId.flattenToString(), 0);
|
||||
}
|
||||
|
||||
private PendingIntent createCancelIntent(PrintJobInfo printJob) {
|
||||
Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
|
||||
intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + String.valueOf(printJob.getId()));
|
||||
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());
|
||||
return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
}
|
||||
|
||||
private PendingIntent createRestartIntent(int printJobId) {
|
||||
private PendingIntent createRestartIntent(PrintJobId printJobId) {
|
||||
Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
|
||||
intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + String.valueOf(printJobId));
|
||||
intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + printJobId.flattenToString());
|
||||
intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJobId);
|
||||
return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
}
|
||||
@@ -162,17 +164,17 @@ public class NotificationController {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action != null && action.startsWith(INTENT_ACTION_CANCEL_PRINTJOB)) {
|
||||
final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID);
|
||||
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);
|
||||
handleCancelPrintJob(context, printJobId, printJobLabel, printerName);
|
||||
} else if (action != null && action.startsWith(INTENT_ACTION_RESTART_PRINTJOB)) {
|
||||
final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID);
|
||||
PrintJobId printJobId = intent.getExtras().getParcelable(INTENT_EXTRA_PRINTJOB_ID);
|
||||
handleRestartPrintJob(context, printJobId);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCancelPrintJob(final Context context, final int printJobId,
|
||||
private void handleCancelPrintJob(final Context context, final PrintJobId printJobId,
|
||||
final String printJobLabel, final String printerName) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "handleCancelPrintJob() printJobId:" + printJobId);
|
||||
@@ -190,7 +192,7 @@ public class NotificationController {
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setOngoing(true)
|
||||
.setShowWhen(true);
|
||||
notificationManager.notify(printJobId, builder.build());
|
||||
notificationManager.notify(printJobId.flattenToString(), 0, builder.build());
|
||||
|
||||
// Call into the print manager service off the main thread since
|
||||
// the print manager service may end up binding to the print spooler
|
||||
@@ -226,7 +228,7 @@ public class NotificationController {
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
|
||||
}
|
||||
|
||||
private void handleRestartPrintJob(final Context context, final int printJobId) {
|
||||
private void handleRestartPrintJob(final Context context, final PrintJobId printJobId) {
|
||||
if (DEBUG) {
|
||||
Log.i(LOG_TAG, "handleRestartPrintJob() printJobId:" + printJobId);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import android.print.PrintAttributes.MediaSize;
|
||||
import android.print.PrintAttributes.Resolution;
|
||||
import android.print.PrintDocumentAdapter;
|
||||
import android.print.PrintDocumentInfo;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterCapabilitiesInfo;
|
||||
@@ -104,8 +105,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
|
||||
|
||||
public static final String EXTRA_PRINT_DOCUMENT_ADAPTER = "printDocumentAdapter";
|
||||
public static final String EXTRA_PRINT_ATTRIBUTES = "printAttributes";
|
||||
public static final String EXTRA_PRINT_JOB_ID = "printJobId";
|
||||
public static final String EXTRA_PRINT_JOB = "printJob";
|
||||
|
||||
public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
|
||||
|
||||
@@ -163,7 +163,7 @@ public class PrintJobConfigActivity extends Activity {
|
||||
private Document mDocument;
|
||||
private PrintController mController;
|
||||
|
||||
private int mPrintJobId;
|
||||
private PrintJobId mPrintJobId;
|
||||
|
||||
private IBinder mIPrintDocumentAdapter;
|
||||
|
||||
@@ -175,17 +175,18 @@ public class PrintJobConfigActivity extends Activity {
|
||||
|
||||
Bundle extras = getIntent().getExtras();
|
||||
|
||||
mPrintJobId = extras.getInt(EXTRA_PRINT_JOB_ID, -1);
|
||||
if (mPrintJobId < 0) {
|
||||
throw new IllegalArgumentException("Invalid print job id: " + mPrintJobId);
|
||||
PrintJobInfo printJob = extras.getParcelable(EXTRA_PRINT_JOB);
|
||||
if (printJob == null) {
|
||||
throw new IllegalArgumentException("printJob cannot be null");
|
||||
}
|
||||
|
||||
mPrintJobId = printJob.getId();
|
||||
mIPrintDocumentAdapter = extras.getBinder(EXTRA_PRINT_DOCUMENT_ADAPTER);
|
||||
if (mIPrintDocumentAdapter == null) {
|
||||
throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
|
||||
}
|
||||
|
||||
PrintAttributes attributes = getIntent().getParcelableExtra(EXTRA_PRINT_ATTRIBUTES);
|
||||
PrintAttributes attributes = printJob.getAttributes();
|
||||
if (attributes != null) {
|
||||
mCurrPrintAttributes.copyFrom(attributes);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.print.PrintAttributes.Margins;
|
||||
import android.print.PrintAttributes.MediaSize;
|
||||
import android.print.PrintAttributes.Resolution;
|
||||
import android.print.PrintDocumentInfo;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterId;
|
||||
@@ -51,6 +52,8 @@ import com.android.internal.os.HandlerCaller;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
@@ -63,8 +66,6 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
/**
|
||||
* Service for exposing some of the {@link PrintSpooler} functionality to
|
||||
* another process.
|
||||
@@ -73,7 +74,7 @@ public final class PrintSpoolerService extends Service {
|
||||
|
||||
private static final String LOG_TAG = "PrintSpoolerService";
|
||||
|
||||
private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = false;
|
||||
private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = true;
|
||||
|
||||
private static final boolean DEBUG_PERSISTENCE = false;
|
||||
|
||||
@@ -91,10 +92,6 @@ public final class PrintSpoolerService extends Service {
|
||||
|
||||
private static PrintSpoolerService sInstance;
|
||||
|
||||
private static int sPrintJobIdCounter;
|
||||
|
||||
private Intent mStartPrintJobConfigActivityIntent;
|
||||
|
||||
private IPrintSpoolerClient mClient;
|
||||
|
||||
private HandlerCaller mHandlerCaller;
|
||||
@@ -112,8 +109,6 @@ public final class PrintSpoolerService extends Service {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mStartPrintJobConfigActivityIntent = new Intent(PrintSpoolerService.this,
|
||||
PrintJobConfigActivity.class);
|
||||
mHandlerCaller = new HandlerCaller(this, getMainLooper(),
|
||||
new HandlerCallerCallback(), false);
|
||||
|
||||
@@ -147,7 +142,7 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback,
|
||||
public void getPrintJobInfo(PrintJobId printJobId, IPrintSpoolerCallbacks callback,
|
||||
int appId, int sequence) throws RemoteException {
|
||||
PrintJobInfo printJob = null;
|
||||
try {
|
||||
@@ -159,38 +154,28 @@ public final class PrintSpoolerService extends Service {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void createPrintJob(String printJobName, IPrintClient client,
|
||||
IPrintDocumentAdapter printAdapter, PrintAttributes attributes,
|
||||
IPrintSpoolerCallbacks callback, int appId, int sequence)
|
||||
throws RemoteException {
|
||||
PrintJobInfo printJob = null;
|
||||
try {
|
||||
printJob = PrintSpoolerService.this.createPrintJob(
|
||||
printJobName, client, attributes, appId);
|
||||
if (printJob != null) {
|
||||
Intent intent = mStartPrintJobConfigActivityIntent;
|
||||
intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
|
||||
printAdapter.asBinder());
|
||||
intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB_ID,
|
||||
printJob.getId());
|
||||
intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_ATTRIBUTES, attributes);
|
||||
public void createPrintJob(PrintJobInfo printJob, IPrintClient client,
|
||||
IPrintDocumentAdapter printAdapter) throws RemoteException {
|
||||
PrintSpoolerService.this.createPrintJob(printJob);
|
||||
|
||||
IntentSender sender = PendingIntent.getActivity(
|
||||
PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
|
||||
| PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
|
||||
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);
|
||||
|
||||
Message message = mHandlerCaller.obtainMessageOO(
|
||||
HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
|
||||
client, sender);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
} finally {
|
||||
callback.onCreatePrintJobResult(printJob, sequence);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintJobState(int printJobId, int state, String error,
|
||||
public void setPrintJobState(PrintJobId printJobId, int state, String error,
|
||||
IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
|
||||
boolean success = false;
|
||||
try {
|
||||
@@ -202,7 +187,7 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrintJobTag(int printJobId, String tag,
|
||||
public void setPrintJobTag(PrintJobId printJobId, String tag,
|
||||
IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
|
||||
boolean success = false;
|
||||
try {
|
||||
@@ -213,7 +198,7 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
|
||||
public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
|
||||
PrintSpoolerService.this.writePrintJobData(fd, printJobId);
|
||||
}
|
||||
|
||||
@@ -223,6 +208,16 @@ public final class PrintSpoolerService extends Service {
|
||||
HandlerCallerCallback.MSG_SET_CLIENT, client);
|
||||
mHandlerCaller.executeOrSendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObsoletePrintJobs() {
|
||||
PrintSpoolerService.this.removeObsoletePrintJobs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgetPrintJobs(List<PrintJobId> printJobIds) {
|
||||
PrintSpoolerService.this.forgetPrintJobs(printJobIds);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -351,15 +346,16 @@ public final class PrintSpoolerService extends Service {
|
||||
|
||||
private boolean isStateVisibleToUser(int state) {
|
||||
return (isActiveState(state) && (state == PrintJobInfo.STATE_FAILED
|
||||
|| state == PrintJobInfo.STATE_COMPLETED|| state == PrintJobInfo.STATE_CANCELED));
|
||||
|| state == PrintJobInfo.STATE_COMPLETED || state == PrintJobInfo.STATE_CANCELED
|
||||
|| state == PrintJobInfo.STATE_BLOCKED));
|
||||
}
|
||||
|
||||
public PrintJobInfo getPrintJobInfo(int printJobId, int appId) {
|
||||
public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
|
||||
synchronized (mLock) {
|
||||
final int printJobCount = mPrintJobs.size();
|
||||
for (int i = 0; i < printJobCount; i++) {
|
||||
PrintJobInfo printJob = mPrintJobs.get(i);
|
||||
if (printJob.getId() == printJobId
|
||||
if (printJob.getId().equals(printJobId)
|
||||
&& (appId == PrintManager.APP_ID_ANY
|
||||
|| appId == printJob.getAppId())) {
|
||||
return printJob;
|
||||
@@ -369,20 +365,9 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public PrintJobInfo createPrintJob(String label, IPrintClient client,
|
||||
PrintAttributes attributes, int appId) {
|
||||
public void createPrintJob(PrintJobInfo printJob) {
|
||||
synchronized (mLock) {
|
||||
final int printJobId = generatePrintJobIdLocked();
|
||||
PrintJobInfo printJob = new PrintJobInfo();
|
||||
printJob.setId(printJobId);
|
||||
printJob.setAppId(appId);
|
||||
printJob.setLabel(label);
|
||||
printJob.setAttributes(attributes);
|
||||
printJob.setState(PrintJobInfo.STATE_CREATED);
|
||||
|
||||
addPrintJobLocked(printJob);
|
||||
|
||||
return printJob;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,8 +389,7 @@ public final class PrintSpoolerService extends Service {
|
||||
// decide whether to restart the job or just cancel it.
|
||||
setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
|
||||
getString(R.string.no_connection_to_printer));
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -418,26 +402,7 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private int generatePrintJobIdLocked() {
|
||||
int printJobId = sPrintJobIdCounter++;
|
||||
while (isDuplicatePrintJobId(printJobId)) {
|
||||
printJobId = sPrintJobIdCounter++;
|
||||
}
|
||||
return printJobId;
|
||||
}
|
||||
|
||||
private boolean isDuplicatePrintJobId(int printJobId) {
|
||||
final int printJobCount = mPrintJobs.size();
|
||||
for (int j = 0; j < printJobCount; j++) {
|
||||
PrintJobInfo printJob = mPrintJobs.get(j);
|
||||
if (printJob.getId() == printJobId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void writePrintJobData(final ParcelFileDescriptor fd, final int printJobId) {
|
||||
public void writePrintJobData(final ParcelFileDescriptor fd, final PrintJobId printJobId) {
|
||||
final PrintJobInfo printJob;
|
||||
synchronized (mLock) {
|
||||
printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
@@ -476,9 +441,9 @@ public final class PrintSpoolerService extends Service {
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
|
||||
}
|
||||
|
||||
public File generateFileForPrintJob(int printJobId) {
|
||||
public File generateFileForPrintJob(PrintJobId printJobId) {
|
||||
return new File(getFilesDir(), "print_job_"
|
||||
+ printJobId + "." + PRINT_FILE_EXTENSION);
|
||||
+ printJobId.flattenToString() + "." + PRINT_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
private void addPrintJobLocked(PrintJobInfo printJob) {
|
||||
@@ -488,16 +453,59 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void removePrintJobLocked(PrintJobInfo printJob) {
|
||||
if (mPrintJobs.remove(printJob)) {
|
||||
generateFileForPrintJob(printJob.getId()).delete();
|
||||
if (DEBUG_PRINT_JOB_LIFECYCLE) {
|
||||
Slog.i(LOG_TAG, "[REMOVE] " + printJob);
|
||||
private void forgetPrintJobs(List<PrintJobId> printJobIds) {
|
||||
synchronized (mLock) {
|
||||
boolean printJobsRemoved = false;
|
||||
final int removedPrintJobCount = printJobIds.size();
|
||||
for (int i = 0; i < removedPrintJobCount; i++) {
|
||||
PrintJobId removedPrintJobId = printJobIds.get(i);
|
||||
final int printJobCount = mPrintJobs.size();
|
||||
for (int j = printJobCount - 1; j >= 0; j--) {
|
||||
PrintJobInfo printJob = mPrintJobs.get(j);
|
||||
if (removedPrintJobId.equals(printJob.getId())) {
|
||||
mPrintJobs.remove(j);
|
||||
printJobsRemoved = true;
|
||||
if (DEBUG_PRINT_JOB_LIFECYCLE) {
|
||||
Slog.i(LOG_TAG, "[FORGOT] " + printJob.getId().flattenToString());
|
||||
}
|
||||
removePrintJobFileLocked(printJob.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printJobsRemoved) {
|
||||
mPersistanceManager.writeStateLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setPrintJobState(int printJobId, int state, String error) {
|
||||
private void removeObsoletePrintJobs() {
|
||||
synchronized (mLock) {
|
||||
final int printJobCount = mPrintJobs.size();
|
||||
for (int i = printJobCount - 1; i >= 0; i--) {
|
||||
PrintJobInfo printJob = mPrintJobs.get(i);
|
||||
if (isObsoleteState(printJob.getState())) {
|
||||
mPrintJobs.remove(i);
|
||||
if (DEBUG_PRINT_JOB_LIFECYCLE) {
|
||||
Slog.i(LOG_TAG, "[REMOVE] " + printJob.getId().flattenToString());
|
||||
}
|
||||
removePrintJobFileLocked(printJob.getId());
|
||||
}
|
||||
}
|
||||
mPersistanceManager.writeStateLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private void removePrintJobFileLocked(PrintJobId printJobId) {
|
||||
File file = generateFileForPrintJob(printJobId);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
if (DEBUG_PRINT_JOB_LIFECYCLE) {
|
||||
Slog.i(LOG_TAG, "[REMOVE FILE FOR] " + printJobId.flattenToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
|
||||
boolean success = false;
|
||||
|
||||
synchronized (mLock) {
|
||||
@@ -516,7 +524,11 @@ public final class PrintSpoolerService extends Service {
|
||||
switch (state) {
|
||||
case PrintJobInfo.STATE_COMPLETED:
|
||||
case PrintJobInfo.STATE_CANCELED:
|
||||
removePrintJobLocked(printJob);
|
||||
// Just remove the file but keep the print job info since
|
||||
// the app that created it may be holding onto the PrintJob
|
||||
// instance and query it for its most recent state. We will
|
||||
// remove the info for this job when told so by the system.
|
||||
removePrintJobFileLocked(printJob.getId());
|
||||
// $fall-through$
|
||||
|
||||
case PrintJobInfo.STATE_FAILED: {
|
||||
@@ -570,6 +582,11 @@ public final class PrintSpoolerService extends Service {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isObsoleteState(int printJobState) {
|
||||
return (isTeminalState(printJobState)
|
||||
|| printJobState == PrintJobInfo.STATE_QUEUED);
|
||||
}
|
||||
|
||||
private boolean isActiveState(int printJobState) {
|
||||
return printJobState == PrintJobInfo.STATE_CREATED
|
||||
|| printJobState == PrintJobInfo.STATE_QUEUED
|
||||
@@ -577,7 +594,12 @@ public final class PrintSpoolerService extends Service {
|
||||
|| printJobState == PrintJobInfo.STATE_BLOCKED;
|
||||
}
|
||||
|
||||
public boolean setPrintJobTag(int printJobId, String tag) {
|
||||
private boolean isTeminalState(int printJobState) {
|
||||
return printJobState == PrintJobInfo.STATE_COMPLETED
|
||||
|| printJobState == PrintJobInfo.STATE_CANCELED;
|
||||
}
|
||||
|
||||
public boolean setPrintJobTag(PrintJobId printJobId, String tag) {
|
||||
synchronized (mLock) {
|
||||
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
if (printJob != null) {
|
||||
@@ -599,7 +621,7 @@ public final class PrintSpoolerService extends Service {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setPrintJobCopiesNoPersistence(int printJobId, int copies) {
|
||||
public void setPrintJobCopiesNoPersistence(PrintJobId printJobId, int copies) {
|
||||
synchronized (mLock) {
|
||||
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
if (printJob != null) {
|
||||
@@ -608,7 +630,8 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrintJobPrintDocumentInfoNoPersistence(int printJobId, PrintDocumentInfo info) {
|
||||
public void setPrintJobPrintDocumentInfoNoPersistence(PrintJobId printJobId,
|
||||
PrintDocumentInfo info) {
|
||||
synchronized (mLock) {
|
||||
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
if (printJob != null) {
|
||||
@@ -617,7 +640,8 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrintJobAttributesNoPersistence(int printJobId, PrintAttributes attributes) {
|
||||
public void setPrintJobAttributesNoPersistence(PrintJobId printJobId,
|
||||
PrintAttributes attributes) {
|
||||
synchronized (mLock) {
|
||||
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
if (printJob != null) {
|
||||
@@ -626,7 +650,7 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrintJobPrinterNoPersistence(int printJobId, PrinterInfo printer) {
|
||||
public void setPrintJobPrinterNoPersistence(PrintJobId printJobId, PrinterInfo printer) {
|
||||
synchronized (mLock) {
|
||||
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
if (printJob != null) {
|
||||
@@ -636,7 +660,7 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrintJobPagesNoPersistence(int printJobId, PageRange[] pages) {
|
||||
public void setPrintJobPagesNoPersistence(PrintJobId printJobId, PageRange[] pages) {
|
||||
synchronized (mLock) {
|
||||
PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
|
||||
if (printJob != null) {
|
||||
@@ -759,15 +783,9 @@ public final class PrintSpoolerService extends Service {
|
||||
for (int j = 0; j < printJobCount; j++) {
|
||||
PrintJobInfo printJob = printJobs.get(j);
|
||||
|
||||
final int state = printJob.getState();
|
||||
if (state < PrintJobInfo.STATE_QUEUED
|
||||
|| state > PrintJobInfo.STATE_CANCELED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
serializer.startTag(null, TAG_JOB);
|
||||
|
||||
serializer.attribute(null, ATTR_ID, String.valueOf(printJob.getId()));
|
||||
serializer.attribute(null, ATTR_ID, printJob.getId().flattenToString());
|
||||
serializer.attribute(null, ATTR_LABEL, printJob.getLabel().toString());
|
||||
serializer.attribute(null, ATTR_STATE, String.valueOf(printJob.getState()));
|
||||
serializer.attribute(null, ATTR_APP_ID, String.valueOf(printJob.getAppId()));
|
||||
@@ -948,7 +966,8 @@ public final class PrintSpoolerService extends Service {
|
||||
|
||||
PrintJobInfo printJob = new PrintJobInfo();
|
||||
|
||||
final int printJobId = Integer.parseInt(parser.getAttributeValue(null, ATTR_ID));
|
||||
PrintJobId printJobId = PrintJobId.unflattenFromString(
|
||||
parser.getAttributeValue(null, ATTR_ID));
|
||||
printJob.setId(printJobId);
|
||||
String label = parser.getAttributeValue(null, ATTR_LABEL);
|
||||
printJob.setLabel(label);
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrintManager;
|
||||
import android.print.IPrinterDiscoveryObserver;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrinterId;
|
||||
import android.printservice.PrintServiceInfo;
|
||||
@@ -70,30 +71,32 @@ public final class PrintManagerService extends IPrintManager.Stub {
|
||||
BackgroundThread.getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
UserState userState = getCurrentUserStateLocked();
|
||||
userState = getCurrentUserStateLocked();
|
||||
userState.updateIfNeededLocked();
|
||||
userState.getSpoolerLocked().start();
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintJobInfo print(String printJobName, IPrintClient client,
|
||||
IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, int appId,
|
||||
int userId) {
|
||||
public PrintJobInfo print(String printJobName, final IPrintClient client,
|
||||
final IPrintDocumentAdapter documentAdapter, PrintAttributes attributes,
|
||||
int appId, int userId) {
|
||||
final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
final RemotePrintSpooler spooler;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
spooler = userState.getSpoolerLocked();
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return spooler.createPrintJob(printJobName, client, documentAdapter,
|
||||
return userState.print(printJobName, client, documentAdapter,
|
||||
attributes, resolvedAppId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -105,95 +108,65 @@ public final class PrintManagerService extends IPrintManager.Stub {
|
||||
final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
final RemotePrintSpooler spooler;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
spooler = userState.getSpoolerLocked();
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return spooler.getPrintJobInfos(null, PrintJobInfo.STATE_ANY,
|
||||
resolvedAppId);
|
||||
return userState.getPrintJobInfos(resolvedAppId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintJobInfo getPrintJobInfo(int printJobId, int appId, int userId) {
|
||||
public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
|
||||
final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
final RemotePrintSpooler spooler;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
spooler = userState.getSpoolerLocked();
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return spooler.getPrintJobInfo(printJobId, resolvedAppId);
|
||||
return userState.getPrintJobInfo(printJobId, resolvedAppId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelPrintJob(int printJobId, int appId, int userId) {
|
||||
public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
|
||||
final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final UserState userState;
|
||||
final RemotePrintSpooler spooler;
|
||||
synchronized (mLock) {
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
spooler = userState.getSpoolerLocked();
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
PrintJobInfo printJobInfo = spooler.getPrintJobInfo(printJobId, resolvedAppId);
|
||||
if (printJobInfo == null) {
|
||||
return;
|
||||
}
|
||||
if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
|
||||
ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName();
|
||||
RemotePrintService printService = null;
|
||||
synchronized (mLock) {
|
||||
printService = userState.getActiveServicesLocked().get(printServiceName);
|
||||
}
|
||||
if (printService == null) {
|
||||
return;
|
||||
}
|
||||
printService.onRequestCancelPrintJob(printJobInfo);
|
||||
} else {
|
||||
// If the print job is failed we do not need cooperation
|
||||
// from the print service.
|
||||
spooler.setPrintJobState(printJobId, PrintJobInfo.STATE_CANCELED, null);
|
||||
}
|
||||
userState.cancelPrintJob(printJobId, resolvedAppId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restartPrintJob(int printJobId, int appId, int userId) {
|
||||
public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
|
||||
final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
final RemotePrintSpooler spooler;
|
||||
final UserState userState;
|
||||
synchronized (mLock) {
|
||||
spooler = getOrCreateUserStateLocked(resolvedUserId).getSpoolerLocked();
|
||||
userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
}
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, resolvedAppId, resolvedUserId);
|
||||
if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
|
||||
return;
|
||||
}
|
||||
spooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null);
|
||||
userState.restartPrintJob(printJobId, resolvedAppId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<PrintServiceInfo> getEnabledPrintServices(int userId) {
|
||||
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
|
||||
@@ -443,6 +416,7 @@ public final class PrintManagerService extends IPrintManager.Stub {
|
||||
// user changes
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
|
||||
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
|
||||
|
||||
mContext.registerReceiverAsUser(new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -471,15 +445,24 @@ public final class PrintManagerService extends IPrintManager.Stub {
|
||||
}
|
||||
|
||||
private void switchUser(int newUserId) {
|
||||
UserState userState;
|
||||
synchronized (mLock) {
|
||||
if (newUserId == mCurrentUserId) {
|
||||
return;
|
||||
}
|
||||
mCurrentUserId = newUserId;
|
||||
UserState userState = getCurrentUserStateLocked();
|
||||
userState.updateIfNeededLocked();
|
||||
userState.getSpoolerLocked().start();
|
||||
userState = mUserStates.get(mCurrentUserId);
|
||||
if (userState == null) {
|
||||
userState = getCurrentUserStateLocked();
|
||||
userState.updateIfNeededLocked();
|
||||
} else {
|
||||
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 removeUser(int removedUserId) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -29,6 +30,7 @@ import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterId;
|
||||
@@ -690,7 +692,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintJobInfo getPrintJobInfo(int printJobId) {
|
||||
public PrintJobInfo getPrintJobInfo(PrintJobId printJobId) {
|
||||
RemotePrintService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
@@ -705,7 +707,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPrintJobState(int printJobId, int state, String error) {
|
||||
public boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
|
||||
RemotePrintService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
@@ -719,7 +721,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPrintJobTag(int printJobId, String tag) {
|
||||
public boolean setPrintJobTag(PrintJobId printJobId, String tag) {
|
||||
RemotePrintService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
@@ -733,7 +735,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
|
||||
public void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
|
||||
RemotePrintService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
@@ -746,13 +748,15 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersAdded(List<PrinterInfo> printers) {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public void onPrintersAdded(ParceledListSlice printers) {
|
||||
RemotePrintService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
|
||||
List<PrinterInfo> addedPrinters = (List<PrinterInfo>) printers.getList();
|
||||
throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, addedPrinters);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
service.mCallbacks.onPrintersAdded(printers);
|
||||
service.mCallbacks.onPrintersAdded(addedPrinters);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -760,13 +764,15 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrintersRemoved(List<PrinterId> printerIds) {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public void onPrintersRemoved(ParceledListSlice printerIds) {
|
||||
RemotePrintService service = mWeakService.get();
|
||||
if (service != null) {
|
||||
throwIfPrinterIdsTampered(service.mComponentName, printerIds);
|
||||
List<PrinterId> removedPrinterIds = (List<PrinterId>) printerIds.getList();
|
||||
throwIfPrinterIdsTampered(service.mComponentName, removedPrinterIds);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
service.mCallbacks.onPrintersRemoved(printerIds);
|
||||
service.mCallbacks.onPrintersRemoved(removedPrinterIds);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
@@ -31,20 +31,20 @@ import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrintSpooler;
|
||||
import android.print.IPrintSpoolerCallbacks;
|
||||
import android.print.IPrintSpoolerClient;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.util.Slog;
|
||||
import android.util.TimedRemoteCaller;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
/**
|
||||
* This represents the remote print spooler as a local object to the
|
||||
* PrintManagerSerivce. It is responsible to connecting to the remote
|
||||
@@ -64,8 +64,6 @@ final class RemotePrintSpooler {
|
||||
|
||||
private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller();
|
||||
|
||||
private final CreatePrintJobCaller mCreatePrintJobCaller = new CreatePrintJobCaller();
|
||||
|
||||
private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller();
|
||||
|
||||
private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller();
|
||||
@@ -132,16 +130,15 @@ final class RemotePrintSpooler {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final PrintJobInfo createPrintJob(String printJobName, IPrintClient client,
|
||||
IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, int appId) {
|
||||
public final void createPrintJob(PrintJobInfo printJob, IPrintClient client,
|
||||
IPrintDocumentAdapter documentAdapter) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
mCanUnbind = false;
|
||||
}
|
||||
try {
|
||||
return mCreatePrintJobCaller.createPrintJob(getRemoteInstanceLazy(),
|
||||
printJobName, client, documentAdapter, attributes, appId);
|
||||
getRemoteInstanceLazy().createPrintJob(printJob, client, documentAdapter);
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(LOG_TAG, "Error creating print job.", re);
|
||||
} catch (TimeoutException te) {
|
||||
@@ -155,10 +152,9 @@ final class RemotePrintSpooler {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
|
||||
public final void writePrintJobData(ParcelFileDescriptor fd, PrintJobId printJobId) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
@@ -184,7 +180,7 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
}
|
||||
|
||||
public final PrintJobInfo getPrintJobInfo(int printJobId, int appId) {
|
||||
public final PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
@@ -209,7 +205,7 @@ final class RemotePrintSpooler {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final boolean setPrintJobState(int printJobId, int state, String error) {
|
||||
public final boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
@@ -234,7 +230,7 @@ final class RemotePrintSpooler {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final boolean setPrintJobTag(int printJobId, String tag) {
|
||||
public final boolean setPrintJobTag(PrintJobId printJobId, String tag) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
@@ -259,19 +255,46 @@ final class RemotePrintSpooler {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final void start() {
|
||||
public final void removeObsoletePrintJobs() {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
mCanUnbind = false;
|
||||
}
|
||||
try {
|
||||
getRemoteInstanceLazy();
|
||||
getRemoteInstanceLazy().removeObsoletePrintJobs();
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re);
|
||||
} catch (TimeoutException te) {
|
||||
Slog.e(LOG_TAG, "Error starting the spooler.", te);
|
||||
Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te);
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] start()");
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
|
||||
+ "] removeObsoletePrintJobs()");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mCanUnbind = true;
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void forgetPrintJobs(List<PrintJobId> printJobIds) {
|
||||
throwIfCalledOnMainThread();
|
||||
synchronized (mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
mCanUnbind = false;
|
||||
}
|
||||
try {
|
||||
getRemoteInstanceLazy().forgetPrintJobs(printJobIds);
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(LOG_TAG, "Error forgeting print jobs", re);
|
||||
} catch (TimeoutException te) {
|
||||
Slog.e(LOG_TAG, "Error forgeting print jobs", te);
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
|
||||
+ "] forgetPrintJobs()");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mCanUnbind = true;
|
||||
@@ -333,6 +356,9 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
|
||||
private void bindLocked() throws TimeoutException {
|
||||
if (mRemoteInstance != null) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()");
|
||||
}
|
||||
@@ -362,6 +388,9 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
|
||||
private void unbindLocked() {
|
||||
if (mRemoteInstance == null) {
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
if (mCanUnbind) {
|
||||
if (DEBUG) {
|
||||
@@ -452,29 +481,6 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CreatePrintJobCaller extends TimedRemoteCaller<PrintJobInfo> {
|
||||
private final IPrintSpoolerCallbacks mCallback;
|
||||
|
||||
public CreatePrintJobCaller() {
|
||||
super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
|
||||
mCallback = new BasePrintSpoolerServiceCallbacks() {
|
||||
@Override
|
||||
public void onCreatePrintJobResult(PrintJobInfo printJob, int sequence) {
|
||||
onRemoteMethodResult(printJob, sequence);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public PrintJobInfo createPrintJob(IPrintSpooler target, String printJobName,
|
||||
IPrintClient client, IPrintDocumentAdapter documentAdapter,
|
||||
PrintAttributes attributes, int appId) throws RemoteException, TimeoutException {
|
||||
final int sequence = onBeforeRemoteCall();
|
||||
target.createPrintJob(printJobName, client, documentAdapter, attributes,
|
||||
mCallback, appId, sequence);
|
||||
return getResultTimed(sequence);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> {
|
||||
private final IPrintSpoolerCallbacks mCallback;
|
||||
|
||||
@@ -488,7 +494,7 @@ final class RemotePrintSpooler {
|
||||
};
|
||||
}
|
||||
|
||||
public PrintJobInfo getPrintJobInfo(IPrintSpooler target, int printJobId,
|
||||
public PrintJobInfo getPrintJobInfo(IPrintSpooler target, PrintJobId printJobId,
|
||||
int appId) throws RemoteException, TimeoutException {
|
||||
final int sequence = onBeforeRemoteCall();
|
||||
target.getPrintJobInfo(printJobId, mCallback, appId, sequence);
|
||||
@@ -509,7 +515,7 @@ final class RemotePrintSpooler {
|
||||
};
|
||||
}
|
||||
|
||||
public boolean setPrintJobState(IPrintSpooler target, int printJobId,
|
||||
public boolean setPrintJobState(IPrintSpooler target, PrintJobId printJobId,
|
||||
int status, String error) throws RemoteException, TimeoutException {
|
||||
final int sequence = onBeforeRemoteCall();
|
||||
target.setPrintJobState(printJobId, status, error, mCallback, sequence);
|
||||
@@ -530,7 +536,7 @@ final class RemotePrintSpooler {
|
||||
};
|
||||
}
|
||||
|
||||
public boolean setPrintJobTag(IPrintSpooler target, int printJobId,
|
||||
public boolean setPrintJobTag(IPrintSpooler target, PrintJobId printJobId,
|
||||
String tag) throws RemoteException, TimeoutException {
|
||||
final int sequence = onBeforeRemoteCall();
|
||||
target.setPrintJobTag(printJobId, tag, mCallback, sequence);
|
||||
@@ -550,11 +556,6 @@ final class RemotePrintSpooler {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePrintJobResult(PrintJobInfo printJob, int sequence) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelPrintJobResult(boolean canceled, int sequence) {
|
||||
/* do nothing */
|
||||
|
||||
@@ -21,17 +21,24 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.IBinder.DeathRecipient;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserManager;
|
||||
import android.print.IPrintClient;
|
||||
import android.print.IPrintDocumentAdapter;
|
||||
import android.print.IPrinterDiscoveryObserver;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterId;
|
||||
@@ -46,6 +53,7 @@ import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.server.print.RemotePrintService.PrintServiceCallbacks;
|
||||
import com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks;
|
||||
@@ -56,7 +64,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -68,8 +75,6 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final int MAX_ITEMS_PER_CALLBACK = 50;
|
||||
|
||||
private static final char COMPONENT_NAME_SEPARATOR = ':';
|
||||
|
||||
private final SimpleStringSplitter mStringColonSplitter =
|
||||
@@ -87,6 +92,9 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
private final Set<ComponentName> mEnabledServices =
|
||||
new ArraySet<ComponentName>();
|
||||
|
||||
private final CreatedPrintJobTracker mCreatedPrintJobTracker =
|
||||
new CreatedPrintJobTracker();
|
||||
|
||||
private final Object mLock;
|
||||
|
||||
private final Context mContext;
|
||||
@@ -134,6 +142,79 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeObsoletePrintJobs() {
|
||||
mSpooler.removeObsoletePrintJobs();
|
||||
}
|
||||
|
||||
public PrintJobInfo print(String printJobName, final IPrintClient client,
|
||||
final IPrintDocumentAdapter documentAdapter, PrintAttributes attributes,
|
||||
int appId) {
|
||||
PrintJobId printJobId = new PrintJobId();
|
||||
|
||||
// Track this job so we can forget it when the creator dies.
|
||||
if (!mCreatedPrintJobTracker.onPrintJobCreatedLocked(client.asBinder(), printJobId)) {
|
||||
// Not adding a print job means the client is dead - done.
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create print job place holder.
|
||||
final PrintJobInfo printJob = new PrintJobInfo();
|
||||
printJob.setId(printJobId);
|
||||
printJob.setAppId(appId);
|
||||
printJob.setLabel(printJobName);
|
||||
printJob.setAttributes(attributes);
|
||||
printJob.setState(PrintJobInfo.STATE_CREATED);
|
||||
|
||||
// Spin the spooler to add the job and show the config UI.
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
mSpooler.createPrintJob(printJob, client, documentAdapter);
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
|
||||
|
||||
return printJob;
|
||||
}
|
||||
|
||||
public List<PrintJobInfo> getPrintJobInfos(int appId) {
|
||||
return mSpooler.getPrintJobInfos(null, PrintJobInfo.STATE_ANY, appId);
|
||||
}
|
||||
|
||||
public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
|
||||
return mSpooler.getPrintJobInfo(printJobId, appId);
|
||||
}
|
||||
|
||||
public void cancelPrintJob(PrintJobId printJobId, int appId) {
|
||||
PrintJobInfo printJobInfo = mSpooler.getPrintJobInfo(printJobId, appId);
|
||||
if (printJobInfo == null) {
|
||||
return;
|
||||
}
|
||||
if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
|
||||
ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName();
|
||||
RemotePrintService printService = null;
|
||||
synchronized (mLock) {
|
||||
printService = mActiveServices.get(printServiceName);
|
||||
}
|
||||
if (printService == null) {
|
||||
return;
|
||||
}
|
||||
printService.onRequestCancelPrintJob(printJobInfo);
|
||||
} else {
|
||||
// If the print job is failed we do not need cooperation
|
||||
// from the print service.
|
||||
mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_CANCELED, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void restartPrintJob(PrintJobId printJobId, int appId) {
|
||||
PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, appId);
|
||||
if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
|
||||
return;
|
||||
}
|
||||
mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null);
|
||||
}
|
||||
|
||||
public List<PrintServiceInfo> getEnabledPrintServices() {
|
||||
synchronized (mLock) {
|
||||
List<PrintServiceInfo> enabledServices = null;
|
||||
@@ -328,18 +409,6 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
public RemotePrintSpooler getSpoolerLocked() {
|
||||
throwIfDestroyedLocked();
|
||||
return mSpooler;
|
||||
}
|
||||
|
||||
public Map<ComponentName, RemotePrintService> getActiveServicesLocked() {
|
||||
synchronized(mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
return mActiveServices;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<ComponentName> getEnabledServices() {
|
||||
synchronized(mLock) {
|
||||
throwIfDestroyedLocked();
|
||||
@@ -593,13 +662,12 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
// just died. Do this off the main thread since we do to allow
|
||||
// calls into the spooler on the main thread.
|
||||
if (Looper.getMainLooper().isCurrentThread()) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
BackgroundThread.getHandler().post(new Runnable() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
public void run() {
|
||||
failActivePrintJobsForServiceInternal(serviceName);
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
|
||||
});
|
||||
} else {
|
||||
failActivePrintJobsForServiceInternal(serviceName);
|
||||
}
|
||||
@@ -1088,19 +1156,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
private void handlePrintersAdded(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterInfo> printers) {
|
||||
try {
|
||||
final int printerCount = printers.size();
|
||||
if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
|
||||
observer.onPrintersAdded(printers);
|
||||
} else {
|
||||
// Send the added printers in chunks avoiding the binder transaction limit.
|
||||
final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
|
||||
for (int i = 0; i < transactionCount; i++) {
|
||||
final int start = i * MAX_ITEMS_PER_CALLBACK;
|
||||
final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
|
||||
List<PrinterInfo> subPrinters = printers.subList(start, end);
|
||||
observer.onPrintersAdded(subPrinters);
|
||||
}
|
||||
}
|
||||
observer.onPrintersAdded(new ParceledListSlice<PrinterInfo>(printers));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
}
|
||||
@@ -1109,21 +1165,9 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
private void handlePrintersRemoved(IPrinterDiscoveryObserver observer,
|
||||
List<PrinterId> printerIds) {
|
||||
try {
|
||||
final int printerCount = printerIds.size();
|
||||
if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
|
||||
observer.onPrintersRemoved(printerIds);
|
||||
} else {
|
||||
// Send the added printers in chunks avoiding the binder transaction limit.
|
||||
final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
|
||||
for (int i = 0; i < transactionCount; i++) {
|
||||
final int start = i * MAX_ITEMS_PER_CALLBACK;
|
||||
final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
|
||||
List<PrinterId> subPrinterIds = printerIds.subList(start, end);
|
||||
observer.onPrintersRemoved(subPrinterIds);
|
||||
}
|
||||
}
|
||||
observer.onPrintersRemoved(new ParceledListSlice<PrinterId>(printerIds));
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error sending added printers", re);
|
||||
Log.e(LOG_TAG, "Error sending removed printers", re);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1255,4 +1299,51 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class CreatedPrintJobTracker {
|
||||
private final ArrayMap<IBinder, List<PrintJobId>> mCreatedPrintJobs =
|
||||
new ArrayMap<IBinder, List<PrintJobId>>();
|
||||
|
||||
public boolean onPrintJobCreatedLocked(final IBinder creator, PrintJobId printJobId) {
|
||||
try {
|
||||
creator.linkToDeath(new DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
creator.unlinkToDeath(this, 0);
|
||||
UserManager userManager = (UserManager) mContext.getSystemService(
|
||||
Context.USER_SERVICE);
|
||||
// If the death is a result of the user being removed, then
|
||||
// do nothing since the spooler data for this user will be
|
||||
// wiped and we cannot bind to the spooler at this point.
|
||||
if (userManager.getUserInfo(mUserId) == null) {
|
||||
return;
|
||||
}
|
||||
List<PrintJobId> printJobIds = null;
|
||||
synchronized (mLock) {
|
||||
printJobIds = mCreatedPrintJobs.remove(creator);
|
||||
if (printJobIds == null) {
|
||||
return;
|
||||
}
|
||||
printJobIds = new ArrayList<PrintJobId>(printJobIds);
|
||||
}
|
||||
if (printJobIds != null) {
|
||||
mSpooler.forgetPrintJobs(printJobIds);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
} catch (RemoteException re) {
|
||||
/* The process is already dead - we just failed. */
|
||||
return false;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
List<PrintJobId> printJobIds = mCreatedPrintJobs.get(creator);
|
||||
if (printJobIds == null) {
|
||||
printJobIds = new ArrayList<PrintJobId>();
|
||||
mCreatedPrintJobs.put(creator, printJobIds);
|
||||
}
|
||||
printJobIds.add(printJobId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user