Dump print manager as proto
Test: incident_report print. Having no entries Change-Id: I3c7d611e44c0d3bf8e00775b1708bd82a334121a
This commit is contained in:
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.service.print.PrintAttributesProto;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
@@ -54,9 +55,9 @@ public final class PrintAttributes implements Parcelable {
|
||||
@interface ColorMode {
|
||||
}
|
||||
/** Color mode: Monochrome color scheme, for example one color is used. */
|
||||
public static final int COLOR_MODE_MONOCHROME = 1 << 0;
|
||||
public static final int COLOR_MODE_MONOCHROME = PrintAttributesProto.COLOR_MODE_MONOCHROME;
|
||||
/** Color mode: Color color scheme, for example many colors are used. */
|
||||
public static final int COLOR_MODE_COLOR = 1 << 1;
|
||||
public static final int COLOR_MODE_COLOR = PrintAttributesProto.COLOR_MODE_COLOR;
|
||||
|
||||
private static final int VALID_COLOR_MODES =
|
||||
COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR;
|
||||
@@ -69,11 +70,11 @@ public final class PrintAttributes implements Parcelable {
|
||||
@interface DuplexMode {
|
||||
}
|
||||
/** Duplex mode: No duplexing. */
|
||||
public static final int DUPLEX_MODE_NONE = 1 << 0;
|
||||
public static final int DUPLEX_MODE_NONE = PrintAttributesProto.DUPLEX_MODE_NONE;
|
||||
/** Duplex mode: Pages are turned sideways along the long edge - like a book. */
|
||||
public static final int DUPLEX_MODE_LONG_EDGE = 1 << 1;
|
||||
public static final int DUPLEX_MODE_LONG_EDGE = PrintAttributesProto.DUPLEX_MODE_LONG_EDGE;
|
||||
/** Duplex mode: Pages are turned upwards along the short edge - like a notpad. */
|
||||
public static final int DUPLEX_MODE_SHORT_EDGE = 1 << 2;
|
||||
public static final int DUPLEX_MODE_SHORT_EDGE = PrintAttributesProto.DUPLEX_MODE_SHORT_EDGE;
|
||||
|
||||
private static final int VALID_DUPLEX_MODES =
|
||||
DUPLEX_MODE_NONE | DUPLEX_MODE_LONG_EDGE | DUPLEX_MODE_SHORT_EDGE;
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.service.print.PrintJobInfoProto;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
@@ -88,7 +89,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* Next valid states: {@link #STATE_QUEUED}
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_CREATED = 1;
|
||||
public static final int STATE_CREATED = PrintJobInfoProto.STATE_CREATED;
|
||||
|
||||
/**
|
||||
* Print job state: The print jobs is created, it is ready
|
||||
@@ -98,7 +99,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* {@link #STATE_CANCELED}
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_QUEUED = 2;
|
||||
public static final int STATE_QUEUED = PrintJobInfoProto.STATE_QUEUED;
|
||||
|
||||
/**
|
||||
* Print job state: The print job is being printed.
|
||||
@@ -107,7 +108,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* {@link #STATE_CANCELED}, {@link #STATE_BLOCKED}
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_STARTED = 3;
|
||||
public static final int STATE_STARTED = PrintJobInfoProto.STATE_STARTED;
|
||||
|
||||
/**
|
||||
* Print job state: The print job is blocked.
|
||||
@@ -116,7 +117,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* {@link #STATE_STARTED}
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_BLOCKED = 4;
|
||||
public static final int STATE_BLOCKED = PrintJobInfoProto.STATE_BLOCKED;
|
||||
|
||||
/**
|
||||
* Print job state: The print job is successfully printed.
|
||||
@@ -125,7 +126,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* Next valid states: None
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_COMPLETED = 5;
|
||||
public static final int STATE_COMPLETED = PrintJobInfoProto.STATE_COMPLETED;
|
||||
|
||||
/**
|
||||
* Print job state: The print job was printing but printing failed.
|
||||
@@ -133,7 +134,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* Next valid states: {@link #STATE_CANCELED}, {@link #STATE_STARTED}
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_FAILED = 6;
|
||||
public static final int STATE_FAILED = PrintJobInfoProto.STATE_FAILED;
|
||||
|
||||
/**
|
||||
* Print job state: The print job is canceled.
|
||||
@@ -142,7 +143,7 @@ public final class PrintJobInfo implements Parcelable {
|
||||
* Next valid states: None
|
||||
* </p>
|
||||
*/
|
||||
public static final int STATE_CANCELED = 7;
|
||||
public static final int STATE_CANCELED = PrintJobInfoProto.STATE_CANCELED;
|
||||
|
||||
/** The unique print job id. */
|
||||
private PrintJobId mId;
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.service.print.PrinterInfoProto;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -59,13 +60,13 @@ public final class PrinterInfo implements Parcelable {
|
||||
public @interface Status {
|
||||
}
|
||||
/** Printer status: the printer is idle and ready to print. */
|
||||
public static final int STATUS_IDLE = 1;
|
||||
public static final int STATUS_IDLE = PrinterInfoProto.STATUS_IDLE;
|
||||
|
||||
/** Printer status: the printer is busy printing. */
|
||||
public static final int STATUS_BUSY = 2;
|
||||
public static final int STATUS_BUSY = PrinterInfoProto.STATUS_BUSY;
|
||||
|
||||
/** Printer status: the printer is not available. */
|
||||
public static final int STATUS_UNAVAILABLE = 3;
|
||||
public static final int STATUS_UNAVAILABLE = PrinterInfoProto.STATUS_UNAVAILABLE;
|
||||
|
||||
private final @NonNull PrinterId mId;
|
||||
|
||||
|
||||
@@ -16,12 +16,8 @@
|
||||
|
||||
package com.android.internal.os;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
@@ -30,6 +26,15 @@ import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Helper for transferring data through a pipe from a client app.
|
||||
*/
|
||||
@@ -81,6 +86,45 @@ public final class TransferPipe implements Runnable, Closeable {
|
||||
goDump(binder, out, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read raw bytes from a service's dump function.
|
||||
*
|
||||
* <p>This can be used for dumping {@link android.util.proto.ProtoOutputStream protos}.
|
||||
*
|
||||
* @param binder The service providing the data
|
||||
* @param args The arguments passed to the dump function of the service
|
||||
*/
|
||||
public static byte[] dumpAsync(@NonNull IBinder binder, @Nullable String... args)
|
||||
throws IOException, RemoteException {
|
||||
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
|
||||
try {
|
||||
TransferPipe.dumpAsync(binder, pipe[1].getFileDescriptor(), args);
|
||||
|
||||
// Data is written completely when dumpAsync is done
|
||||
pipe[1].close();
|
||||
pipe[1] = null;
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
try (ByteArrayOutputStream combinedBuffer = new ByteArrayOutputStream()) {
|
||||
try (FileInputStream is = new FileInputStream(pipe[0].getFileDescriptor())) {
|
||||
while (true) {
|
||||
int numRead = is.read(buffer);
|
||||
if (numRead == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
combinedBuffer.write(buffer, 0, numRead);
|
||||
}
|
||||
}
|
||||
|
||||
return combinedBuffer.toByteArray();
|
||||
}
|
||||
} finally {
|
||||
pipe[0].close();
|
||||
IoUtils.closeQuietly(pipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void go(Caller caller, IInterface iface, FileDescriptor out,
|
||||
String prefix, String[] args) throws IOException, RemoteException {
|
||||
go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
|
||||
|
||||
356
core/java/com/android/internal/print/DumpUtils.java
Normal file
356
core/java/com/android/internal/print/DumpUtils.java
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.internal.print;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ComponentNameProto;
|
||||
import android.content.Context;
|
||||
import android.print.PageRange;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintDocumentInfo;
|
||||
import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrinterCapabilitiesInfo;
|
||||
import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.service.print.MarginsProto;
|
||||
import android.service.print.MediaSizeProto;
|
||||
import android.service.print.PageRangeProto;
|
||||
import android.service.print.PrintAttributesProto;
|
||||
import android.service.print.PrintDocumentInfoProto;
|
||||
import android.service.print.PrintJobInfoProto;
|
||||
import android.service.print.PrinterCapabilitiesProto;
|
||||
import android.service.print.PrinterIdProto;
|
||||
import android.service.print.PrinterInfoProto;
|
||||
import android.service.print.ResolutionProto;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
/**
|
||||
* Utilities for dumping print related proto buffer
|
||||
*/
|
||||
public class DumpUtils {
|
||||
/**
|
||||
* Write a string to a proto if the string is not {@code null}.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the string
|
||||
* @param string The string to write
|
||||
*/
|
||||
public static void writeStringIfNotNull(@NonNull ProtoOutputStream proto, long id,
|
||||
@Nullable String string) {
|
||||
if (string != null) {
|
||||
proto.write(id, string);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link ComponentName} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param component The component name to write
|
||||
*/
|
||||
public static void writeComponentName(@NonNull ProtoOutputStream proto, long id,
|
||||
@NonNull ComponentName component) {
|
||||
long token = proto.start(id);
|
||||
proto.write(ComponentNameProto.PACKAGE_NAME, component.getPackageName());
|
||||
proto.write(ComponentNameProto.CLASS_NAME, component.getClassName());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrinterId} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param printerId The printer id to write
|
||||
*/
|
||||
public static void writePrinterId(@NonNull ProtoOutputStream proto, long id,
|
||||
@NonNull PrinterId printerId) {
|
||||
long token = proto.start(id);
|
||||
writeComponentName(proto, PrinterIdProto.SERVICE_NAME, printerId.getServiceName());
|
||||
proto.write(PrinterIdProto.LOCAL_ID, printerId.getLocalId());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrinterCapabilitiesInfo} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param cap The capabilities to write
|
||||
*/
|
||||
public static void writePrinterCapabilities(@NonNull Context context,
|
||||
@NonNull ProtoOutputStream proto, long id, @NonNull PrinterCapabilitiesInfo cap) {
|
||||
long token = proto.start(id);
|
||||
writeMargins(proto, PrinterCapabilitiesProto.MIN_MARGINS, cap.getMinMargins());
|
||||
|
||||
int numMediaSizes = cap.getMediaSizes().size();
|
||||
for (int i = 0; i < numMediaSizes; i++) {
|
||||
writeMediaSize(context, proto, PrinterCapabilitiesProto.MEDIA_SIZES,
|
||||
cap.getMediaSizes().get(i));
|
||||
}
|
||||
|
||||
int numResolutions = cap.getResolutions().size();
|
||||
for (int i = 0; i < numResolutions; i++) {
|
||||
writeResolution(proto, PrinterCapabilitiesProto.RESOLUTIONS,
|
||||
cap.getResolutions().get(i));
|
||||
}
|
||||
|
||||
if ((cap.getColorModes() & PrintAttributes.COLOR_MODE_MONOCHROME) != 0) {
|
||||
proto.write(PrinterCapabilitiesProto.COLOR_MODES,
|
||||
PrintAttributesProto.COLOR_MODE_MONOCHROME);
|
||||
}
|
||||
if ((cap.getColorModes() & PrintAttributes.COLOR_MODE_COLOR) != 0) {
|
||||
proto.write(PrinterCapabilitiesProto.COLOR_MODES,
|
||||
PrintAttributesProto.COLOR_MODE_COLOR);
|
||||
}
|
||||
|
||||
if ((cap.getDuplexModes() & PrintAttributes.DUPLEX_MODE_NONE) != 0) {
|
||||
proto.write(PrinterCapabilitiesProto.DUPLEX_MODES,
|
||||
PrintAttributesProto.DUPLEX_MODE_NONE);
|
||||
}
|
||||
if ((cap.getDuplexModes() & PrintAttributes.DUPLEX_MODE_LONG_EDGE) != 0) {
|
||||
proto.write(PrinterCapabilitiesProto.DUPLEX_MODES,
|
||||
PrintAttributesProto.DUPLEX_MODE_LONG_EDGE);
|
||||
}
|
||||
if ((cap.getDuplexModes() & PrintAttributes.DUPLEX_MODE_SHORT_EDGE) != 0) {
|
||||
proto.write(PrinterCapabilitiesProto.DUPLEX_MODES,
|
||||
PrintAttributesProto.DUPLEX_MODE_SHORT_EDGE);
|
||||
}
|
||||
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a {@link PrinterInfo} to a proto.
|
||||
*
|
||||
* @param context The context used to resolve resources
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param info The printer info to write
|
||||
*/
|
||||
public static void writePrinterInfo(@NonNull Context context, @NonNull ProtoOutputStream proto,
|
||||
long id, @NonNull PrinterInfo info) {
|
||||
long token = proto.start(id);
|
||||
writePrinterId(proto, PrinterInfoProto.ID, info.getId());
|
||||
proto.write(PrinterInfoProto.NAME, info.getName());
|
||||
proto.write(PrinterInfoProto.STATUS, info.getStatus());
|
||||
proto.write(PrinterInfoProto.DESCRIPTION, info.getDescription());
|
||||
|
||||
PrinterCapabilitiesInfo cap = info.getCapabilities();
|
||||
if (cap != null) {
|
||||
writePrinterCapabilities(context, proto, PrinterInfoProto.CAPABILITIES, cap);
|
||||
}
|
||||
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrintAttributes.MediaSize} to a proto.
|
||||
*
|
||||
* @param context The context used to resolve resources
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param mediaSize The media size to write
|
||||
*/
|
||||
public static void writeMediaSize(@NonNull Context context, @NonNull ProtoOutputStream proto,
|
||||
long id, @NonNull PrintAttributes.MediaSize mediaSize) {
|
||||
long token = proto.start(id);
|
||||
proto.write(MediaSizeProto.ID, mediaSize.getId());
|
||||
proto.write(MediaSizeProto.LABEL, mediaSize.getLabel(context.getPackageManager()));
|
||||
proto.write(MediaSizeProto.HEIGHT_MILS, mediaSize.getHeightMils());
|
||||
proto.write(MediaSizeProto.WIDTH_MILS, mediaSize.getWidthMils());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrintAttributes.Resolution} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param res The resolution to write
|
||||
*/
|
||||
public static void writeResolution(@NonNull ProtoOutputStream proto, long id,
|
||||
@NonNull PrintAttributes.Resolution res) {
|
||||
long token = proto.start(id);
|
||||
proto.write(ResolutionProto.ID, res.getId());
|
||||
proto.write(ResolutionProto.LABEL, res.getLabel());
|
||||
proto.write(ResolutionProto.HORIZONTAL_DPI, res.getHorizontalDpi());
|
||||
proto.write(ResolutionProto.VERTICAL_DPI, res.getVerticalDpi());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrintAttributes.Margins} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param margins The margins to write
|
||||
*/
|
||||
public static void writeMargins(@NonNull ProtoOutputStream proto, long id,
|
||||
@NonNull PrintAttributes.Margins margins) {
|
||||
long token = proto.start(id);
|
||||
proto.write(MarginsProto.TOP_MILS, margins.getTopMils());
|
||||
proto.write(MarginsProto.LEFT_MILS, margins.getLeftMils());
|
||||
proto.write(MarginsProto.RIGHT_MILS, margins.getRightMils());
|
||||
proto.write(MarginsProto.BOTTOM_MILS, margins.getBottomMils());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrintAttributes} to a proto.
|
||||
*
|
||||
* @param context The context used to resolve resources
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param attributes The attributes to write
|
||||
*/
|
||||
public static void writePrintAttributes(@NonNull Context context,
|
||||
@NonNull ProtoOutputStream proto, long id, @NonNull PrintAttributes attributes) {
|
||||
long token = proto.start(id);
|
||||
|
||||
PrintAttributes.MediaSize mediaSize = attributes.getMediaSize();
|
||||
if (mediaSize != null) {
|
||||
writeMediaSize(context, proto, PrintAttributesProto.MEDIA_SIZE, mediaSize);
|
||||
}
|
||||
|
||||
proto.write(PrintAttributesProto.IS_PORTRAIT, attributes.isPortrait());
|
||||
|
||||
PrintAttributes.Resolution res = attributes.getResolution();
|
||||
if (res != null) {
|
||||
writeResolution(proto, PrintAttributesProto.RESOLUTION, res);
|
||||
}
|
||||
|
||||
PrintAttributes.Margins minMargins = attributes.getMinMargins();
|
||||
if (minMargins != null) {
|
||||
writeMargins(proto, PrintAttributesProto.MIN_MARGINS, minMargins);
|
||||
}
|
||||
|
||||
proto.write(PrintAttributesProto.COLOR_MODE, attributes.getColorMode());
|
||||
proto.write(PrintAttributesProto.DUPLEX_MODE, attributes.getDuplexMode());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrintDocumentInfo} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param info The info to write
|
||||
*/
|
||||
public static void writePrintDocumentInfo(@NonNull ProtoOutputStream proto, long id,
|
||||
@NonNull PrintDocumentInfo info) {
|
||||
long token = proto.start(id);
|
||||
proto.write(PrintDocumentInfoProto.NAME, info.getName());
|
||||
|
||||
int pageCount = info.getPageCount();
|
||||
if (pageCount != PrintDocumentInfo.PAGE_COUNT_UNKNOWN) {
|
||||
proto.write(PrintDocumentInfoProto.PAGE_COUNT, pageCount);
|
||||
}
|
||||
|
||||
proto.write(PrintDocumentInfoProto.CONTENT_TYPE, info.getContentType());
|
||||
proto.write(PrintDocumentInfoProto.DATA_SIZE, info.getDataSize());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PageRange} to a proto.
|
||||
*
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param range The range to write
|
||||
*/
|
||||
public static void writePageRange(@NonNull ProtoOutputStream proto, long id,
|
||||
@NonNull PageRange range) {
|
||||
long token = proto.start(id);
|
||||
proto.write(PageRangeProto.START, range.getStart());
|
||||
proto.write(PageRangeProto.END, range.getEnd());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link PrintJobInfo} to a proto.
|
||||
*
|
||||
* @param context The context used to resolve resources
|
||||
* @param proto The proto to write to
|
||||
* @param id The proto-id of the component name
|
||||
* @param printJobInfo The print job info to write
|
||||
*/
|
||||
public static void writePrintJobInfo(@NonNull Context context, @NonNull ProtoOutputStream proto,
|
||||
long id, @NonNull PrintJobInfo printJobInfo) {
|
||||
long token = proto.start(id);
|
||||
proto.write(PrintJobInfoProto.LABEL, printJobInfo.getLabel());
|
||||
|
||||
PrintJobId printJobId = printJobInfo.getId();
|
||||
if (printJobId != null) {
|
||||
proto.write(PrintJobInfoProto.PRINT_JOB_ID, printJobId.flattenToString());
|
||||
}
|
||||
|
||||
int state = printJobInfo.getState();
|
||||
if (state >= PrintJobInfoProto.STATE_CREATED && state <= PrintJobInfoProto.STATE_CANCELED) {
|
||||
proto.write(PrintJobInfoProto.STATE, state);
|
||||
} else {
|
||||
proto.write(PrintJobInfoProto.STATE, PrintJobInfoProto.STATE_UNKNOWN);
|
||||
}
|
||||
|
||||
PrinterId printer = printJobInfo.getPrinterId();
|
||||
if (printer != null) {
|
||||
writePrinterId(proto, PrintJobInfoProto.PRINTER, printer);
|
||||
}
|
||||
|
||||
String tag = printJobInfo.getTag();
|
||||
if (tag != null) {
|
||||
proto.write(PrintJobInfoProto.TAG, tag);
|
||||
}
|
||||
|
||||
proto.write(PrintJobInfoProto.CREATION_TIME, printJobInfo.getCreationTime());
|
||||
|
||||
PrintAttributes attributes = printJobInfo.getAttributes();
|
||||
if (attributes != null) {
|
||||
writePrintAttributes(context, proto, PrintJobInfoProto.ATTRIBUTES, attributes);
|
||||
}
|
||||
|
||||
PrintDocumentInfo docInfo = printJobInfo.getDocumentInfo();
|
||||
if (docInfo != null) {
|
||||
writePrintDocumentInfo(proto, PrintJobInfoProto.DOCUMENT_INFO, docInfo);
|
||||
}
|
||||
|
||||
proto.write(PrintJobInfoProto.IS_CANCELING, printJobInfo.isCancelling());
|
||||
|
||||
PageRange[] pages = printJobInfo.getPages();
|
||||
if (pages != null) {
|
||||
for (int i = 0; i < pages.length; i++) {
|
||||
writePageRange(proto, PrintJobInfoProto.PAGES, pages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
proto.write(PrintJobInfoProto.HAS_ADVANCED_OPTIONS,
|
||||
printJobInfo.getAdvancedOptions() != null);
|
||||
proto.write(PrintJobInfoProto.PROGRESS, printJobInfo.getProgress());
|
||||
|
||||
CharSequence status = printJobInfo.getStatus(context.getPackageManager());
|
||||
if (status != null) {
|
||||
proto.write(PrintJobInfoProto.STATUS, status.toString());
|
||||
}
|
||||
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import "frameworks/base/core/proto/android/service/netstats.proto";
|
||||
import "frameworks/base/core/proto/android/service/notification.proto";
|
||||
import "frameworks/base/core/proto/android/service/package.proto";
|
||||
import "frameworks/base/core/proto/android/service/power.proto";
|
||||
import "frameworks/base/core/proto/android/service/print.proto";
|
||||
import "frameworks/base/core/proto/android/providers/settings.proto";
|
||||
import "frameworks/base/core/proto/android/os/kernelwake.proto";
|
||||
|
||||
@@ -66,4 +67,5 @@ message IncidentProto {
|
||||
android.service.notification.NotificationServiceDumpProto notification = 3004;
|
||||
android.service.pm.PackageServiceDumpProto package = 3008;
|
||||
android.service.power.PowerServiceDumpProto power = 3009;
|
||||
android.service.print.PrintServiceDumpProto print = 3010;
|
||||
}
|
||||
|
||||
368
core/proto/android/service/print.proto
Normal file
368
core/proto/android/service/print.proto
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package android.service.print;
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "PrintServiceProto";
|
||||
|
||||
import "frameworks/base/core/proto/android/content/component_name.proto";
|
||||
|
||||
message PrintServiceDumpProto {
|
||||
// Each user has a separate printer state
|
||||
repeated PrintUserStateProto userStates = 1;
|
||||
}
|
||||
|
||||
message PrintUserStateProto {
|
||||
// Should be 0, 10, 11, 12, etc. where 0 is the owner.
|
||||
int32 user_id = 1;
|
||||
|
||||
// The installed print services
|
||||
repeated InstalledPrintServiceProto installed_services = 2;
|
||||
|
||||
// The disabled print services
|
||||
repeated android.content.ComponentNameProto disabled_services = 3;
|
||||
|
||||
// The active print services
|
||||
repeated ActivePrintServiceProto active_services = 4;
|
||||
|
||||
// The cached print jobs
|
||||
repeated CachedPrintJobProto cached_print_jobs = 5;
|
||||
|
||||
// The printer discovery sessions
|
||||
repeated PrinterDiscoverySessionProto discovery_sessions = 6;
|
||||
|
||||
// The print spooler state
|
||||
PrintSpoolerStateProto print_spooler_state = 7;
|
||||
}
|
||||
|
||||
message PrintSpoolerStateProto {
|
||||
// Is the print spooler destroyed?
|
||||
bool is_destroyed = 1;
|
||||
|
||||
// Is the print spooler bound?
|
||||
bool is_bound = 2;
|
||||
|
||||
// State internal to the print spooler
|
||||
PrintSpoolerInternalStateProto internal_state = 3;
|
||||
}
|
||||
|
||||
message PrintSpoolerInternalStateProto {
|
||||
// Print jobs
|
||||
repeated PrintJobInfoProto print_jobs = 1;
|
||||
|
||||
// Files used by these print jobs
|
||||
repeated string print_job_files = 2;
|
||||
|
||||
// Approved print services
|
||||
repeated android.content.ComponentNameProto approved_services = 3;
|
||||
}
|
||||
|
||||
message PrinterCapabilitiesProto {
|
||||
// Minimum margins of the printer
|
||||
MarginsProto min_margins = 1;
|
||||
|
||||
// List of supported media sizes
|
||||
repeated MediaSizeProto media_sizes = 2;
|
||||
|
||||
// List of supported resolutions
|
||||
repeated ResolutionProto resolutions = 3;
|
||||
|
||||
// List of supported color modes
|
||||
repeated PrintAttributesProto.ColorMode color_modes = 4;
|
||||
|
||||
// List of supported duplex modes
|
||||
repeated PrintAttributesProto.DuplexMode duplex_modes = 5;
|
||||
}
|
||||
|
||||
message PrinterInfoProto {
|
||||
// The id of the printer
|
||||
PrinterIdProto id = 1;
|
||||
|
||||
// The name of the printer
|
||||
string name = 2;
|
||||
|
||||
enum Status {
|
||||
// unused
|
||||
__STATUS_UNUSED = 0;
|
||||
|
||||
// Printer is idle
|
||||
STATUS_IDLE = 1;
|
||||
|
||||
// Printer is busy
|
||||
STATUS_BUSY = 2;
|
||||
|
||||
// Printer is unavailable
|
||||
STATUS_UNAVAILABLE = 3;
|
||||
}
|
||||
// The status of the printer
|
||||
Status status = 3;
|
||||
|
||||
// The description of the printer
|
||||
string description = 4;
|
||||
|
||||
// The capabilities of the printer
|
||||
PrinterCapabilitiesProto capabilities = 5;
|
||||
}
|
||||
|
||||
message PrinterDiscoverySessionProto {
|
||||
// Is this session destroyed?
|
||||
bool is_destroyed = 1;
|
||||
|
||||
// Is printer discovery in progress?
|
||||
bool is_printer_discovery_in_progress = 2;
|
||||
|
||||
// List of printer discovery observers
|
||||
repeated string printer_discovery_observers = 3;
|
||||
|
||||
// List of discovery request
|
||||
repeated string discovery_requests = 4;
|
||||
|
||||
// List of ids of printers that are have tracking requests
|
||||
repeated PrinterIdProto tracked_printer_requests = 5;
|
||||
|
||||
// List of printers found
|
||||
repeated PrinterInfoProto printer = 6;
|
||||
}
|
||||
|
||||
message InstalledPrintServiceProto {
|
||||
// Component name of the service
|
||||
android.content.ComponentNameProto component_name = 1;
|
||||
|
||||
// Settings activity for this service
|
||||
string settings_activity = 2;
|
||||
|
||||
// Add printers activity for this service
|
||||
string add_printers_activity = 3;
|
||||
|
||||
// Advances options activity for this service
|
||||
string advanced_options_activity = 4;
|
||||
}
|
||||
|
||||
message PrinterIdProto {
|
||||
// Component name of the service that reported the printer
|
||||
android.content.ComponentNameProto service_name = 1;
|
||||
|
||||
// Local id of the printer
|
||||
string local_id = 2;
|
||||
}
|
||||
|
||||
message ActivePrintServiceProto {
|
||||
// Component name of the service
|
||||
android.content.ComponentNameProto component_name = 1;
|
||||
|
||||
// Is the active service destroyed
|
||||
bool is_destroyed = 2;
|
||||
|
||||
// Is the active service bound
|
||||
bool is_bound = 3;
|
||||
|
||||
// Has the active service a discovery session
|
||||
bool has_discovery_session = 4;
|
||||
|
||||
// Has the active service a active print jobs
|
||||
bool has_active_print_jobs = 5;
|
||||
|
||||
// Is the active service discovering printers
|
||||
bool is_discovering_printers = 6;
|
||||
|
||||
// The tracked printers of this active service
|
||||
repeated PrinterIdProto tracked_printers = 7;
|
||||
}
|
||||
|
||||
message MediaSizeProto {
|
||||
// Id of this media size
|
||||
string id = 1;
|
||||
|
||||
// Label of this media size
|
||||
string label = 2;
|
||||
|
||||
// Height of the media
|
||||
int32 height_mils = 3;
|
||||
|
||||
// Width of the media
|
||||
int32 width_mils = 4;
|
||||
}
|
||||
|
||||
message ResolutionProto {
|
||||
// Id of this resolution
|
||||
string id = 1;
|
||||
|
||||
// Label for this resoltion
|
||||
string label = 2;
|
||||
|
||||
// Resolution in horizontal orientation
|
||||
int32 horizontal_dpi = 3;
|
||||
|
||||
// Resolution in vertical orientation
|
||||
int32 vertical_dpi = 4;
|
||||
}
|
||||
|
||||
message MarginsProto {
|
||||
// Space at the top
|
||||
int32 top_mils = 1;
|
||||
|
||||
// Space at the left
|
||||
int32 left_mils = 2;
|
||||
|
||||
// Space at the right
|
||||
int32 right_mils = 3;
|
||||
|
||||
// Space at the bottom
|
||||
int32 bottom_mils = 4;
|
||||
}
|
||||
|
||||
message PrintAttributesProto {
|
||||
// Media to use
|
||||
ResolutionProto media_size = 1;
|
||||
|
||||
// Is the media in portrait mode?
|
||||
bool is_portrait = 2;
|
||||
|
||||
// Resolution to use
|
||||
ResolutionProto resolution = 3;
|
||||
|
||||
// Margins around the document
|
||||
MarginsProto min_margins = 4;
|
||||
|
||||
enum ColorMode {
|
||||
// unused
|
||||
__COLOR_MODE_UNUSED = 0;
|
||||
|
||||
// Use black, white, gray
|
||||
COLOR_MODE_MONOCHROME = 1;
|
||||
|
||||
// Use full color is available
|
||||
COLOR_MODE_COLOR = 2;
|
||||
}
|
||||
// Color mode to use
|
||||
ColorMode color_mode = 5;
|
||||
|
||||
enum DuplexMode {
|
||||
// unused
|
||||
__DUPLEX_MODE_UNUSED = 0;
|
||||
|
||||
// No duplex
|
||||
DUPLEX_MODE_NONE = 1;
|
||||
|
||||
// Duplex where the long edge attached
|
||||
DUPLEX_MODE_LONG_EDGE = 2;
|
||||
|
||||
// Duplex where the short edge attach
|
||||
DUPLEX_MODE_SHORT_EDGE = 4;
|
||||
}
|
||||
// Duplex mode to use
|
||||
DuplexMode duplex_mode = 6;
|
||||
}
|
||||
|
||||
message PrintDocumentInfoProto {
|
||||
// Name of the document to print
|
||||
string name = 1;
|
||||
|
||||
// Number of pages in the doc
|
||||
int32 page_count = 2;
|
||||
|
||||
// Type of content (see PrintDocumentInfo.ContentType)
|
||||
int32 content_type = 3;
|
||||
|
||||
// The size of the the document
|
||||
int64 data_size = 4;
|
||||
}
|
||||
|
||||
message PageRangeProto {
|
||||
// Start of the range
|
||||
int32 start = 1;
|
||||
|
||||
// End of the range (included)
|
||||
int32 end = 2;
|
||||
}
|
||||
|
||||
message PrintJobInfoProto {
|
||||
// Label of the job
|
||||
string label = 1;
|
||||
|
||||
// Id of the job
|
||||
string print_job_id = 2;
|
||||
|
||||
enum State {
|
||||
// Unknown state
|
||||
STATE_UNKNOWN = 0;
|
||||
|
||||
// The print job is being created but not yet ready to be printed
|
||||
STATE_CREATED = 1;
|
||||
|
||||
// The print jobs is created, it is ready to be printed and should be processed
|
||||
STATE_QUEUED = 2;
|
||||
|
||||
// The print job is being printed
|
||||
STATE_STARTED = 3;
|
||||
|
||||
// The print job is blocked
|
||||
STATE_BLOCKED = 4;
|
||||
|
||||
// The print job is successfully printed
|
||||
STATE_COMPLETED = 5;
|
||||
|
||||
// The print job was printing but printing failed
|
||||
STATE_FAILED = 6;
|
||||
|
||||
// The print job is canceled
|
||||
STATE_CANCELED = 7;
|
||||
}
|
||||
|
||||
// State of the job
|
||||
State state = 3;
|
||||
|
||||
// Printer handling the job
|
||||
PrinterIdProto printer = 4;
|
||||
|
||||
// Tag assigned to the job
|
||||
string tag = 5;
|
||||
|
||||
// Time the job was created
|
||||
int64 creation_time = 6;
|
||||
|
||||
// Attributes of the job
|
||||
PrintAttributesProto attributes = 7;
|
||||
|
||||
// Document info of the job
|
||||
PrintDocumentInfoProto document_info = 8;
|
||||
|
||||
// If the job current getting canceled
|
||||
bool is_canceling = 9;
|
||||
|
||||
// The selected ranges of the job
|
||||
repeated PageRangeProto pages = 10;
|
||||
|
||||
// Does the job have any advanced options
|
||||
bool has_advanced_options = 11;
|
||||
|
||||
// Progress of the job
|
||||
float progress = 12;
|
||||
|
||||
// The current service set state
|
||||
string status = 13;
|
||||
}
|
||||
|
||||
message CachedPrintJobProto {
|
||||
// The id of the app the job belongs to
|
||||
int32 app_id = 1;
|
||||
|
||||
// The print job
|
||||
PrintJobInfoProto print_job = 2;
|
||||
}
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.printspooler.model;
|
||||
|
||||
import static com.android.internal.print.DumpUtils.writeComponentName;
|
||||
import static com.android.internal.print.DumpUtils.writePrintJobInfo;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -26,6 +29,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
@@ -44,16 +48,19 @@ import android.print.PrintJobId;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterId;
|
||||
import android.service.print.PrintSpoolerInternalStateProto;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.os.HandlerCaller;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.printspooler.R;
|
||||
import com.android.printspooler.util.ApprovedPrintServices;
|
||||
|
||||
@@ -152,29 +159,26 @@ public final class PrintSpoolerService extends Service {
|
||||
return new PrintSpooler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
private void dumpLocked(PrintWriter pw, String[] args) {
|
||||
String prefix = (args.length > 0) ? args[0] : "";
|
||||
String tab = " ";
|
||||
|
||||
synchronized (mLock) {
|
||||
pw.append(prefix).append("print jobs:").println();
|
||||
final int printJobCount = mPrintJobs.size();
|
||||
for (int i = 0; i < printJobCount; i++) {
|
||||
PrintJobInfo printJob = mPrintJobs.get(i);
|
||||
pw.append(prefix).append(tab).append(printJob.toString());
|
||||
pw.println();
|
||||
}
|
||||
pw.append(prefix).append("print jobs:").println();
|
||||
final int printJobCount = mPrintJobs.size();
|
||||
for (int i = 0; i < printJobCount; i++) {
|
||||
PrintJobInfo printJob = mPrintJobs.get(i);
|
||||
pw.append(prefix).append(tab).append(printJob.toString());
|
||||
pw.println();
|
||||
}
|
||||
|
||||
pw.append(prefix).append("print job files:").println();
|
||||
File[] files = getFilesDir().listFiles();
|
||||
if (files != null) {
|
||||
final int fileCount = files.length;
|
||||
for (int i = 0; i < fileCount; i++) {
|
||||
File file = files[i];
|
||||
if (file.isFile() && file.getName().startsWith(PRINT_JOB_FILE_PREFIX)) {
|
||||
pw.append(prefix).append(tab).append(file.getName()).println();
|
||||
}
|
||||
pw.append(prefix).append("print job files:").println();
|
||||
File[] files = getFilesDir().listFiles();
|
||||
if (files != null) {
|
||||
final int fileCount = files.length;
|
||||
for (int i = 0; i < fileCount; i++) {
|
||||
File file = files[i];
|
||||
if (file.isFile() && file.getName().startsWith(PRINT_JOB_FILE_PREFIX)) {
|
||||
pw.append(prefix).append(tab).append(file.getName()).println();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,6 +192,68 @@ public final class PrintSpoolerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpLocked(@NonNull ProtoOutputStream proto) {
|
||||
int numPrintJobs = mPrintJobs.size();
|
||||
for (int i = 0; i < numPrintJobs; i++) {
|
||||
writePrintJobInfo(this, proto, PrintSpoolerInternalStateProto.PRINT_JOBS,
|
||||
mPrintJobs.get(i));
|
||||
}
|
||||
|
||||
File[] files = getFilesDir().listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
if (file.isFile() && file.getName().startsWith(PRINT_JOB_FILE_PREFIX)) {
|
||||
proto.write(PrintSpoolerInternalStateProto.PRINT_JOB_FILES, file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> approvedPrintServices = (new ApprovedPrintServices(this)).getApprovedServices();
|
||||
if (approvedPrintServices != null) {
|
||||
for (String approvedService : approvedPrintServices) {
|
||||
ComponentName componentName = ComponentName.unflattenFromString(approvedService);
|
||||
if (componentName != null) {
|
||||
writeComponentName(proto, PrintSpoolerInternalStateProto.APPROVED_SERVICES,
|
||||
componentName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proto.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
fd = Preconditions.checkNotNull(fd);
|
||||
|
||||
int opti = 0;
|
||||
boolean dumpAsProto = false;
|
||||
while (opti < args.length) {
|
||||
String opt = args[opti];
|
||||
if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
|
||||
break;
|
||||
}
|
||||
opti++;
|
||||
if ("--proto".equals(opt)) {
|
||||
dumpAsProto = true;
|
||||
}
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
if (dumpAsProto) {
|
||||
dumpLocked(new ProtoOutputStream(fd));
|
||||
} else {
|
||||
dumpLocked(pw, args);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOnPrintJobQueued(PrintJobInfo printJob) {
|
||||
Message message = mHandlerCaller.obtainMessageO(
|
||||
HandlerCallerCallback.MSG_ON_PRINT_JOB_QUEUED, printJob);
|
||||
@@ -752,7 +818,7 @@ public final class PrintSpoolerService extends Service {
|
||||
*
|
||||
* @param printerId the id of the printer the icon belongs to
|
||||
* @param icon the icon that was loaded
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon
|
||||
*/
|
||||
public void onCustomPrinterIconLoaded(PrinterId printerId, Icon icon) {
|
||||
mCustomIconCache.onCustomPrinterIconLoaded(printerId, icon);
|
||||
@@ -765,7 +831,7 @@ public final class PrintSpoolerService extends Service {
|
||||
* @param printerId the id of the printer the icon should be loaded for
|
||||
* @return the custom icon to be used for the printer or null if the icon is
|
||||
* not yet available
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon
|
||||
*/
|
||||
public Icon getCustomPrinterIcon(PrinterId printerId) {
|
||||
return mCustomIconCache.getIcon(printerId);
|
||||
|
||||
@@ -50,8 +50,10 @@ import android.printservice.PrintServiceInfo;
|
||||
import android.printservice.recommendation.IRecommendationsChangeListener;
|
||||
import android.printservice.recommendation.RecommendationInfo;
|
||||
import android.provider.Settings;
|
||||
import android.service.print.PrintServiceDumpProto;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
@@ -638,19 +640,32 @@ public final class PrintManagerService extends SystemService {
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
fd = Preconditions.checkNotNull(fd);
|
||||
pw = Preconditions.checkNotNull(pw);
|
||||
|
||||
if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
|
||||
|
||||
int opti = 0;
|
||||
boolean dumpAsProto = false;
|
||||
int user = UserHandle.USER_ALL;
|
||||
while (opti < args.length) {
|
||||
String opt = args[opti];
|
||||
if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
|
||||
break;
|
||||
}
|
||||
opti++;
|
||||
if ("--proto".equals(opt)) {
|
||||
dumpAsProto = true;
|
||||
} else {
|
||||
pw.println("Unknown argument: " + opt + "; use -h for help");
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
pw.println("PRINT MANAGER STATE (dumpsys print)");
|
||||
final int userStateCount = mUserStates.size();
|
||||
for (int i = 0; i < userStateCount; i++) {
|
||||
UserState userState = mUserStates.valueAt(i);
|
||||
userState.dump(fd, pw, "");
|
||||
pw.println();
|
||||
if (dumpAsProto) {
|
||||
dumpLocked(new ProtoOutputStream(fd), UserHandle.of(user));
|
||||
} else {
|
||||
dumpLocked(fd, pw, UserHandle.of(user));
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -658,6 +673,37 @@ public final class PrintManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpLocked(@NonNull ProtoOutputStream proto, @NonNull UserHandle user) {
|
||||
final int userStateCount = mUserStates.size();
|
||||
for (int i = 0; i < userStateCount; i++) {
|
||||
UserState userState = mUserStates.valueAt(i);
|
||||
|
||||
if (user.equals(UserHandle.ALL) || mUserStates.keyAt(i) == user.getIdentifier()) {
|
||||
long token = proto.start(PrintServiceDumpProto.USER_STATES);
|
||||
userState.dump(proto);
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
proto.flush();
|
||||
}
|
||||
|
||||
private void dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
|
||||
@NonNull UserHandle user) {
|
||||
pw = Preconditions.checkNotNull(pw);
|
||||
|
||||
pw.println("PRINT MANAGER STATE (dumpsys print)");
|
||||
final int userStateCount = mUserStates.size();
|
||||
for (int i = 0; i < userStateCount; i++) {
|
||||
UserState userState = mUserStates.valueAt(i);
|
||||
|
||||
if (user.equals(UserHandle.ALL) || mUserStates.keyAt(i) == user.getIdentifier()) {
|
||||
userState.dump(fd, pw, "");
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerContentObservers() {
|
||||
final Uri enabledPrintServicesUri = Settings.Secure.getUriFor(
|
||||
Settings.Secure.DISABLED_PRINT_SERVICES);
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.server.print;
|
||||
|
||||
import static com.android.internal.print.DumpUtils.writeComponentName;
|
||||
import static com.android.internal.print.DumpUtils.writePrinterId;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -42,7 +45,11 @@ import android.print.PrinterId;
|
||||
import android.print.PrinterInfo;
|
||||
import android.printservice.IPrintService;
|
||||
import android.printservice.IPrintServiceClient;
|
||||
import android.service.print.ActivePrintServiceProto;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -60,6 +67,8 @@ final class RemotePrintService implements DeathRecipient {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private final ComponentName mComponentName;
|
||||
@@ -94,6 +103,7 @@ final class RemotePrintService implements DeathRecipient {
|
||||
|
||||
private List<PrinterId> mDiscoveryPriorityList;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private List<PrinterId> mTrackedPrinterList;
|
||||
|
||||
public static interface PrintServiceCallbacks {
|
||||
@@ -443,11 +453,14 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
private void handleStartPrinterStateTracking(final @NonNull PrinterId printerId) {
|
||||
// Take a note we are tracking the printer.
|
||||
if (mTrackedPrinterList == null) {
|
||||
mTrackedPrinterList = new ArrayList<PrinterId>();
|
||||
synchronized (mLock) {
|
||||
// Take a note we are tracking the printer.
|
||||
if (mTrackedPrinterList == null) {
|
||||
mTrackedPrinterList = new ArrayList<PrinterId>();
|
||||
}
|
||||
mTrackedPrinterList.add(printerId);
|
||||
}
|
||||
mTrackedPrinterList.add(printerId);
|
||||
|
||||
if (!isBound()) {
|
||||
ensureBound();
|
||||
mPendingCommands.add(new Runnable() {
|
||||
@@ -474,13 +487,16 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
private void handleStopPrinterStateTracking(final PrinterId printerId) {
|
||||
// We are no longer tracking the printer.
|
||||
if (mTrackedPrinterList == null || !mTrackedPrinterList.remove(printerId)) {
|
||||
return;
|
||||
}
|
||||
if (mTrackedPrinterList.isEmpty()) {
|
||||
mTrackedPrinterList = null;
|
||||
synchronized (mLock) {
|
||||
// We are no longer tracking the printer.
|
||||
if (mTrackedPrinterList == null || !mTrackedPrinterList.remove(printerId)) {
|
||||
return;
|
||||
}
|
||||
if (mTrackedPrinterList.isEmpty()) {
|
||||
mTrackedPrinterList = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isBound()) {
|
||||
ensureBound();
|
||||
mPendingCommands.add(new Runnable() {
|
||||
@@ -502,14 +518,37 @@ final class RemotePrintService implements DeathRecipient {
|
||||
}
|
||||
|
||||
private void stopTrackingAllPrinters() {
|
||||
if (mTrackedPrinterList == null) {
|
||||
return;
|
||||
synchronized (mLock) {
|
||||
if (mTrackedPrinterList == null) {
|
||||
return;
|
||||
}
|
||||
final int trackedPrinterCount = mTrackedPrinterList.size();
|
||||
for (int i = trackedPrinterCount - 1; i >= 0; i--) {
|
||||
PrinterId printerId = mTrackedPrinterList.get(i);
|
||||
if (printerId.getServiceName().equals(mComponentName)) {
|
||||
handleStopPrinterStateTracking(printerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
final int trackedPrinterCount = mTrackedPrinterList.size();
|
||||
for (int i = trackedPrinterCount - 1; i >= 0; i--) {
|
||||
PrinterId printerId = mTrackedPrinterList.get(i);
|
||||
if (printerId.getServiceName().equals(mComponentName)) {
|
||||
handleStopPrinterStateTracking(printerId);
|
||||
}
|
||||
|
||||
public void dump(@NonNull ProtoOutputStream proto) {
|
||||
writeComponentName(proto, ActivePrintServiceProto.COMPONENT_NAME, mComponentName);
|
||||
|
||||
proto.write(ActivePrintServiceProto.IS_DESTROYED, mDestroyed);
|
||||
proto.write(ActivePrintServiceProto.IS_BOUND, isBound());
|
||||
proto.write(ActivePrintServiceProto.HAS_DISCOVERY_SESSION, mHasPrinterDiscoverySession);
|
||||
proto.write(ActivePrintServiceProto.HAS_ACTIVE_PRINT_JOBS, mHasActivePrintJobs);
|
||||
proto.write(ActivePrintServiceProto.IS_DISCOVERING_PRINTERS,
|
||||
mDiscoveryPriorityList != null);
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mTrackedPrinterList != null) {
|
||||
int numTrackedPrinters = mTrackedPrinterList.size();
|
||||
for (int i = 0; i < numTrackedPrinters; i++) {
|
||||
writePrinterId(proto, ActivePrintServiceProto.TRACKED_PRINTERS,
|
||||
mTrackedPrinterList.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,8 +568,11 @@ final class RemotePrintService implements DeathRecipient {
|
||||
.append(String.valueOf(mHasActivePrintJobs)).println();
|
||||
pw.append(prefix).append(tab).append("isDiscoveringPrinters=")
|
||||
.append(String.valueOf(mDiscoveryPriorityList != null)).println();
|
||||
pw.append(prefix).append(tab).append("trackedPrinters=")
|
||||
.append((mTrackedPrinterList != null) ? mTrackedPrinterList.toString() : "null");
|
||||
|
||||
synchronized (mLock) {
|
||||
pw.append(prefix).append(tab).append("trackedPrinters=").append(
|
||||
(mTrackedPrinterList != null) ? mTrackedPrinterList.toString() : "null");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBound() {
|
||||
@@ -574,7 +616,11 @@ final class RemotePrintService implements DeathRecipient {
|
||||
mHasActivePrintJobs = false;
|
||||
mHasPrinterDiscoverySession = false;
|
||||
mDiscoveryPriorityList = null;
|
||||
mTrackedPrinterList = null;
|
||||
|
||||
synchronized (mLock) {
|
||||
mTrackedPrinterList = null;
|
||||
}
|
||||
|
||||
if (isBound()) {
|
||||
try {
|
||||
mPrintService.setClient(null);
|
||||
@@ -617,11 +663,13 @@ final class RemotePrintService implements DeathRecipient {
|
||||
if (mServiceDied && mDiscoveryPriorityList != null) {
|
||||
handleStartPrinterDiscovery(mDiscoveryPriorityList);
|
||||
}
|
||||
// If the service died and printers were tracked, start tracking.
|
||||
if (mServiceDied && mTrackedPrinterList != null) {
|
||||
final int trackedPrinterCount = mTrackedPrinterList.size();
|
||||
for (int i = 0; i < trackedPrinterCount; i++) {
|
||||
handleStartPrinterStateTracking(mTrackedPrinterList.get(i));
|
||||
synchronized (mLock) {
|
||||
// If the service died and printers were tracked, start tracking.
|
||||
if (mServiceDied && mTrackedPrinterList != null) {
|
||||
final int trackedPrinterCount = mTrackedPrinterList.size();
|
||||
for (int i = 0; i < trackedPrinterCount; i++) {
|
||||
handleStartPrinterStateTracking(mTrackedPrinterList.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally, do all the pending work.
|
||||
|
||||
@@ -40,8 +40,10 @@ import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.print.PrinterId;
|
||||
import android.printservice.PrintService;
|
||||
import android.service.print.PrintSpoolerStateProto;
|
||||
import android.util.Slog;
|
||||
import android.util.TimedRemoteCaller;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.os.TransferPipe;
|
||||
@@ -363,7 +365,7 @@ final class RemotePrintSpooler {
|
||||
*
|
||||
* @param printerId the id of the printer the icon belongs to
|
||||
* @param icon the icon that was loaded
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon
|
||||
*/
|
||||
public final void onCustomPrinterIconLoaded(@NonNull PrinterId printerId,
|
||||
@Nullable Icon icon) {
|
||||
@@ -396,7 +398,7 @@ final class RemotePrintSpooler {
|
||||
* @param printerId the id of the printer the icon should be loaded for
|
||||
* @return the custom icon to be used for the printer or null if the icon is
|
||||
* not yet available
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
|
||||
* @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon
|
||||
*/
|
||||
public final @Nullable Icon getCustomPrinterIcon(@NonNull PrinterId printerId) {
|
||||
throwIfCalledOnMainThread();
|
||||
@@ -556,6 +558,20 @@ final class RemotePrintSpooler {
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(@NonNull ProtoOutputStream proto) {
|
||||
synchronized (mLock) {
|
||||
proto.write(PrintSpoolerStateProto.IS_DESTROYED, mDestroyed);
|
||||
proto.write(PrintSpoolerStateProto.IS_BOUND, mRemoteInstance != null);
|
||||
}
|
||||
|
||||
try {
|
||||
proto.write(PrintSpoolerStateProto.INTERNAL_STATE,
|
||||
TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), "--proto"));
|
||||
} catch (IOException | TimeoutException | RemoteException | InterruptedException e) {
|
||||
Slog.e(LOG_TAG, "Failed to dump remote instance", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
|
||||
synchronized (mLock) {
|
||||
pw.append(prefix).append("destroyed=")
|
||||
|
||||
@@ -20,6 +20,12 @@ import static android.content.pm.PackageManager.GET_META_DATA;
|
||||
import static android.content.pm.PackageManager.GET_SERVICES;
|
||||
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
|
||||
|
||||
import static com.android.internal.print.DumpUtils.writeComponentName;
|
||||
import static com.android.internal.print.DumpUtils.writePrintJobInfo;
|
||||
import static com.android.internal.print.DumpUtils.writePrinterId;
|
||||
import static com.android.internal.print.DumpUtils.writePrinterInfo;
|
||||
import static com.android.internal.print.DumpUtils.writeStringIfNotNull;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.PendingIntent;
|
||||
@@ -58,6 +64,10 @@ import android.printservice.recommendation.IRecommendationsChangeListener;
|
||||
import android.printservice.recommendation.RecommendationInfo;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.Settings;
|
||||
import android.service.print.CachedPrintJobProto;
|
||||
import android.service.print.InstalledPrintServiceProto;
|
||||
import android.service.print.PrintUserStateProto;
|
||||
import android.service.print.PrinterDiscoverySessionProto;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextUtils.SimpleStringSplitter;
|
||||
import android.util.ArrayMap;
|
||||
@@ -65,6 +75,7 @@ import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
@@ -803,55 +814,107 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
|
||||
mDestroyed = true;
|
||||
}
|
||||
|
||||
public void dump(@NonNull ProtoOutputStream proto) {
|
||||
synchronized (mLock) {
|
||||
proto.write(PrintUserStateProto.USER_ID, mUserId);
|
||||
|
||||
final int installedServiceCount = mInstalledServices.size();
|
||||
for (int i = 0; i < installedServiceCount; i++) {
|
||||
long token = proto.start(PrintUserStateProto.INSTALLED_SERVICES);
|
||||
PrintServiceInfo installedService = mInstalledServices.get(i);
|
||||
|
||||
ResolveInfo resolveInfo = installedService.getResolveInfo();
|
||||
writeComponentName(proto, InstalledPrintServiceProto.COMPONENT_NAME,
|
||||
new ComponentName(resolveInfo.serviceInfo.packageName,
|
||||
resolveInfo.serviceInfo.name));
|
||||
|
||||
writeStringIfNotNull(proto, InstalledPrintServiceProto.SETTINGS_ACTIVITY,
|
||||
installedService.getSettingsActivityName());
|
||||
writeStringIfNotNull(proto, InstalledPrintServiceProto.ADD_PRINTERS_ACTIVITY,
|
||||
installedService.getAddPrintersActivityName());
|
||||
writeStringIfNotNull(proto, InstalledPrintServiceProto.ADVANCED_OPTIONS_ACTIVITY,
|
||||
installedService.getAdvancedOptionsActivityName());
|
||||
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
for (ComponentName disabledService : mDisabledServices) {
|
||||
writeComponentName(proto, PrintUserStateProto.DISABLED_SERVICES, disabledService);
|
||||
}
|
||||
|
||||
final int activeServiceCount = mActiveServices.size();
|
||||
for (int i = 0; i < activeServiceCount; i++) {
|
||||
long token = proto.start(PrintUserStateProto.ACTIVE_SERVICES);
|
||||
mActiveServices.valueAt(i).dump(proto);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
mPrintJobForAppCache.dumpLocked(proto);
|
||||
|
||||
if (mPrinterDiscoverySession != null) {
|
||||
long token = proto.start(PrintUserStateProto.DISCOVERY_SESSIONS);
|
||||
mPrinterDiscoverySession.dumpLocked(proto);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
long token = proto.start(PrintUserStateProto.PRINT_SPOOLER_STATE);
|
||||
mSpooler.dump(proto);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String prefix) {
|
||||
pw.append(prefix).append("user state ").append(String.valueOf(mUserId)).append(":");
|
||||
pw.println();
|
||||
|
||||
String tab = " ";
|
||||
|
||||
pw.append(prefix).append(tab).append("installed services:").println();
|
||||
final int installedServiceCount = mInstalledServices.size();
|
||||
for (int i = 0; i < installedServiceCount; i++) {
|
||||
PrintServiceInfo installedService = mInstalledServices.get(i);
|
||||
String installedServicePrefix = prefix + tab + tab;
|
||||
pw.append(installedServicePrefix).append("service:").println();
|
||||
ResolveInfo resolveInfo = installedService.getResolveInfo();
|
||||
ComponentName componentName = new ComponentName(
|
||||
resolveInfo.serviceInfo.packageName,
|
||||
resolveInfo.serviceInfo.name);
|
||||
pw.append(installedServicePrefix).append(tab).append("componentName=")
|
||||
.append(componentName.flattenToString()).println();
|
||||
pw.append(installedServicePrefix).append(tab).append("settingsActivity=")
|
||||
.append(installedService.getSettingsActivityName()).println();
|
||||
pw.append(installedServicePrefix).append(tab).append("addPrintersActivity=")
|
||||
.append(installedService.getAddPrintersActivityName()).println();
|
||||
pw.append(installedServicePrefix).append(tab).append("avancedOptionsActivity=")
|
||||
.append(installedService.getAdvancedOptionsActivityName()).println();
|
||||
}
|
||||
synchronized (mLock) {
|
||||
pw.append(prefix).append(tab).append("installed services:").println();
|
||||
final int installedServiceCount = mInstalledServices.size();
|
||||
for (int i = 0; i < installedServiceCount; i++) {
|
||||
PrintServiceInfo installedService = mInstalledServices.get(i);
|
||||
String installedServicePrefix = prefix + tab + tab;
|
||||
pw.append(installedServicePrefix).append("service:").println();
|
||||
ResolveInfo resolveInfo = installedService.getResolveInfo();
|
||||
ComponentName componentName = new ComponentName(
|
||||
resolveInfo.serviceInfo.packageName,
|
||||
resolveInfo.serviceInfo.name);
|
||||
pw.append(installedServicePrefix).append(tab).append("componentName=")
|
||||
.append(componentName.flattenToString()).println();
|
||||
pw.append(installedServicePrefix).append(tab).append("settingsActivity=")
|
||||
.append(installedService.getSettingsActivityName()).println();
|
||||
pw.append(installedServicePrefix).append(tab).append("addPrintersActivity=")
|
||||
.append(installedService.getAddPrintersActivityName()).println();
|
||||
pw.append(installedServicePrefix).append(tab).append("avancedOptionsActivity=")
|
||||
.append(installedService.getAdvancedOptionsActivityName()).println();
|
||||
}
|
||||
|
||||
pw.append(prefix).append(tab).append("disabled services:").println();
|
||||
for (ComponentName disabledService : mDisabledServices) {
|
||||
String disabledServicePrefix = prefix + tab + tab;
|
||||
pw.append(disabledServicePrefix).append("service:").println();
|
||||
pw.append(disabledServicePrefix).append(tab).append("componentName=")
|
||||
.append(disabledService.flattenToString());
|
||||
pw.println();
|
||||
}
|
||||
pw.append(prefix).append(tab).append("disabled services:").println();
|
||||
for (ComponentName disabledService : mDisabledServices) {
|
||||
String disabledServicePrefix = prefix + tab + tab;
|
||||
pw.append(disabledServicePrefix).append("service:").println();
|
||||
pw.append(disabledServicePrefix).append(tab).append("componentName=")
|
||||
.append(disabledService.flattenToString());
|
||||
pw.println();
|
||||
}
|
||||
|
||||
pw.append(prefix).append(tab).append("active services:").println();
|
||||
final int activeServiceCount = mActiveServices.size();
|
||||
for (int i = 0; i < activeServiceCount; i++) {
|
||||
RemotePrintService activeService = mActiveServices.valueAt(i);
|
||||
activeService.dump(pw, prefix + tab + tab);
|
||||
pw.println();
|
||||
}
|
||||
pw.append(prefix).append(tab).append("active services:").println();
|
||||
final int activeServiceCount = mActiveServices.size();
|
||||
for (int i = 0; i < activeServiceCount; i++) {
|
||||
RemotePrintService activeService = mActiveServices.valueAt(i);
|
||||
activeService.dump(pw, prefix + tab + tab);
|
||||
pw.println();
|
||||
}
|
||||
|
||||
pw.append(prefix).append(tab).append("cached print jobs:").println();
|
||||
mPrintJobForAppCache.dump(pw, prefix + tab + tab);
|
||||
pw.append(prefix).append(tab).append("cached print jobs:").println();
|
||||
mPrintJobForAppCache.dumpLocked(pw, prefix + tab + tab);
|
||||
|
||||
pw.append(prefix).append(tab).append("discovery mediator:").println();
|
||||
if (mPrinterDiscoverySession != null) {
|
||||
mPrinterDiscoverySession.dump(pw, prefix + tab + tab);
|
||||
pw.append(prefix).append(tab).append("discovery mediator:").println();
|
||||
if (mPrinterDiscoverySession != null) {
|
||||
mPrinterDiscoverySession.dumpLocked(pw, prefix + tab + tab);
|
||||
}
|
||||
}
|
||||
|
||||
pw.append(prefix).append(tab).append("print spooler:").println();
|
||||
@@ -1611,7 +1674,40 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw, String prefix) {
|
||||
public void dumpLocked(@NonNull ProtoOutputStream proto) {
|
||||
proto.write(PrinterDiscoverySessionProto.IS_DESTROYED, mDestroyed);
|
||||
proto.write(PrinterDiscoverySessionProto.IS_PRINTER_DISCOVERY_IN_PROGRESS,
|
||||
!mStartedPrinterDiscoveryTokens.isEmpty());
|
||||
|
||||
final int observerCount = mDiscoveryObservers.beginBroadcast();
|
||||
for (int i = 0; i < observerCount; i++) {
|
||||
IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
|
||||
proto.write(PrinterDiscoverySessionProto.PRINTER_DISCOVERY_OBSERVERS,
|
||||
observer.toString());
|
||||
}
|
||||
mDiscoveryObservers.finishBroadcast();
|
||||
|
||||
final int tokenCount = this.mStartedPrinterDiscoveryTokens.size();
|
||||
for (int i = 0; i < tokenCount; i++) {
|
||||
IBinder token = mStartedPrinterDiscoveryTokens.get(i);
|
||||
proto.write(PrinterDiscoverySessionProto.DISCOVERY_REQUESTS, token.toString());
|
||||
}
|
||||
|
||||
final int trackedPrinters = mStateTrackedPrinters.size();
|
||||
for (int i = 0; i < trackedPrinters; i++) {
|
||||
PrinterId printer = mStateTrackedPrinters.get(i);
|
||||
writePrinterId(proto, PrinterDiscoverySessionProto.TRACKED_PRINTER_REQUESTS,
|
||||
printer);
|
||||
}
|
||||
|
||||
final int printerCount = mPrinters.size();
|
||||
for (int i = 0; i < printerCount; i++) {
|
||||
PrinterInfo printer = mPrinters.valueAt(i);
|
||||
writePrinterInfo(mContext, proto, PrinterDiscoverySessionProto.PRINTER, printer);
|
||||
}
|
||||
}
|
||||
|
||||
public void dumpLocked(PrintWriter pw, String prefix) {
|
||||
pw.append(prefix).append("destroyed=")
|
||||
.append(String.valueOf(mDestroyed)).println();
|
||||
|
||||
@@ -1989,19 +2085,36 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw, String prefix) {
|
||||
synchronized (mLock) {
|
||||
String tab = " ";
|
||||
final int bucketCount = mPrintJobsForRunningApp.size();
|
||||
for (int i = 0; i < bucketCount; i++) {
|
||||
final int appId = mPrintJobsForRunningApp.keyAt(i);
|
||||
pw.append(prefix).append("appId=" + appId).append(':').println();
|
||||
List<PrintJobInfo> bucket = mPrintJobsForRunningApp.valueAt(i);
|
||||
final int printJobCount = bucket.size();
|
||||
for (int j = 0; j < printJobCount; j++) {
|
||||
PrintJobInfo printJob = bucket.get(j);
|
||||
pw.append(prefix).append(tab).append(printJob.toString()).println();
|
||||
}
|
||||
public void dumpLocked(PrintWriter pw, String prefix) {
|
||||
String tab = " ";
|
||||
final int bucketCount = mPrintJobsForRunningApp.size();
|
||||
for (int i = 0; i < bucketCount; i++) {
|
||||
final int appId = mPrintJobsForRunningApp.keyAt(i);
|
||||
pw.append(prefix).append("appId=" + appId).append(':').println();
|
||||
List<PrintJobInfo> bucket = mPrintJobsForRunningApp.valueAt(i);
|
||||
final int printJobCount = bucket.size();
|
||||
for (int j = 0; j < printJobCount; j++) {
|
||||
PrintJobInfo printJob = bucket.get(j);
|
||||
pw.append(prefix).append(tab).append(printJob.toString()).println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dumpLocked(@NonNull ProtoOutputStream proto) {
|
||||
final int bucketCount = mPrintJobsForRunningApp.size();
|
||||
for (int i = 0; i < bucketCount; i++) {
|
||||
final int appId = mPrintJobsForRunningApp.keyAt(i);
|
||||
List<PrintJobInfo> bucket = mPrintJobsForRunningApp.valueAt(i);
|
||||
final int printJobCount = bucket.size();
|
||||
for (int j = 0; j < printJobCount; j++) {
|
||||
long token = proto.start(PrintUserStateProto.CACHED_PRINT_JOBS);
|
||||
|
||||
proto.write(CachedPrintJobProto.APP_ID, appId);
|
||||
|
||||
writePrintJobInfo(mContext, proto, CachedPrintJobProto.PRINT_JOB,
|
||||
bucket.get(j));
|
||||
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user