diff options
Diffstat (limited to 'core/java/android')
36 files changed, 1844 insertions, 1598 deletions
diff --git a/core/java/android/hardware/photography/CameraPropertiesKeys.java b/core/java/android/hardware/photography/CameraPropertiesKeys.java index 7e6380e..f511ae7 100644 --- a/core/java/android/hardware/photography/CameraPropertiesKeys.java +++ b/core/java/android/hardware/photography/CameraPropertiesKeys.java @@ -39,11 +39,8 @@ import static android.hardware.photography.CameraMetadata.Key; **/ public final class CameraPropertiesKeys { public static final class Control { - public static final Key<byte[]> AE_AVAILABLE_ANTIBANDING_MODES = new Key<byte[]>("android.control.aeAvailableAntibandingModes", byte[].class); - public static final Key<byte[]> AE_AVAILABLE_MODES = - new Key<byte[]>("android.control.aeAvailableModes", byte[].class); public static final Key<int[]> AE_AVAILABLE_TARGET_FPS_RANGES = new Key<int[]>("android.control.aeAvailableTargetFpsRanges", int[].class); public static final Key<int[]> AE_COMPENSATION_RANGE = @@ -62,40 +59,23 @@ public final class CameraPropertiesKeys { new Key<byte[]>("android.control.awbAvailableModes", byte[].class); public static final Key<Integer> MAX_REGIONS = new Key<Integer>("android.control.maxRegions", int.class); - public static final Key<byte[]> SCENE_MODE_OVERRIDES = - new Key<byte[]>("android.control.sceneModeOverrides", byte[].class); } + public static final class Flash { public static final class Info { public static final Key<Byte> AVAILABLE = new Key<Byte>("android.flash.info.available", byte.class); - public static final Key<Long> CHARGE_DURATION = - new Key<Long>("android.flash.info.chargeDuration", long.class); } - public static final Key<Byte> COLOR_TEMPERATURE = - new Key<Byte>("android.flash.colorTemperature", byte.class); - public static final Key<Byte> MAX_ENERGY = - new Key<Byte>("android.flash.maxEnergy", byte.class); - } - public static final class HotPixel { - public static final class Info { - public static final Key<int[]> MAP = - new Key<int[]>("android.hotPixel.info.map", int[].class); - } - - } public static final class Jpeg { - public static final Key<int[]> AVAILABLE_THUMBNAIL_SIZES = new Key<int[]>("android.jpeg.availableThumbnailSizes", int[].class); - public static final Key<Integer> MAX_SIZE = - new Key<Integer>("android.jpeg.maxSize", int.class); } + public static final class Lens { public static final class Info { public static final Key<float[]> AVAILABLE_APERTURES = @@ -106,21 +86,14 @@ public final class CameraPropertiesKeys { new Key<float[]>("android.lens.info.availableFocalLengths", float[].class); public static final Key<byte[]> AVAILABLE_OPTICAL_STABILIZATION = new Key<byte[]>("android.lens.info.availableOpticalStabilization", byte[].class); - public static final Key<float[]> GEOMETRIC_CORRECTION_MAP = - new Key<float[]>("android.lens.info.geometricCorrectionMap", float[].class); - public static final Key<int[]> GEOMETRIC_CORRECTION_MAP_SIZE = - new Key<int[]>("android.lens.info.geometricCorrectionMapSize", int[].class); public static final Key<Float> HYPERFOCAL_DISTANCE = new Key<Float>("android.lens.info.hyperfocalDistance", float.class); public static final Key<Float> MINIMUM_FOCUS_DISTANCE = new Key<Float>("android.lens.info.minimumFocusDistance", float.class); - public static final Key<float[]> SHADING_MAP = - new Key<float[]>("android.lens.info.shadingMap", float[].class); public static final Key<int[]> SHADING_MAP_SIZE = new Key<int[]>("android.lens.info.shadingMapSize", int[].class); } - public static final class FacingKey extends Key<Lens.FacingKey.Enum> { public enum Enum { FRONT, @@ -139,32 +112,16 @@ public final class CameraPropertiesKeys { public static final Key<Lens.FacingKey.Enum> FACING = new FacingKey("android.lens.facing"); - public static final Key<float[]> OPTICAL_AXIS_ANGLE = - new Key<float[]>("android.lens.opticalAxisAngle", float[].class); - public static final Key<float[]> POSITION = - new Key<float[]>("android.lens.position", float[].class); } - public static final class Quirks { - public static final Key<Byte> METERING_CROP_REGION = - new Key<Byte>("android.quirks.meteringCropRegion", byte.class); - public static final Key<Byte> TRIGGER_AF_WITH_AUTO = - new Key<Byte>("android.quirks.triggerAfWithAuto", byte.class); - public static final Key<Byte> USE_ZSL_FORMAT = - new Key<Byte>("android.quirks.useZslFormat", byte.class); - - } public static final class Request { - public static final Key<int[]> MAX_NUM_OUTPUT_STREAMS = new Key<int[]>("android.request.maxNumOutputStreams", int[].class); - public static final Key<int[]> MAX_NUM_REPROCESS_STREAMS = - new Key<int[]>("android.request.maxNumReprocessStreams", int[].class); } - public static final class Scaler { + public static final class Scaler { public static final class AvailableFormatsKey extends Key<Scaler.AvailableFormatsKey.Enum[]> { public enum Enum { @@ -212,184 +169,55 @@ public final class CameraPropertiesKeys { new Key<long[]>("android.scaler.availableProcessedMinDurations", long[].class); public static final Key<int[]> AVAILABLE_PROCESSED_SIZES = new Key<int[]>("android.scaler.availableProcessedSizes", int[].class); - public static final Key<long[]> AVAILABLE_RAW_MIN_DURATIONS = - new Key<long[]>("android.scaler.availableRawMinDurations", long[].class); - public static final Key<int[]> AVAILABLE_RAW_SIZES = - new Key<int[]>("android.scaler.availableRawSizes", int[].class); } + public static final class Sensor { public static final class Info { public static final Key<int[]> ACTIVE_ARRAY_SIZE = new Key<int[]>("android.sensor.info.activeArraySize", int[].class); public static final Key<int[]> AVAILABLE_SENSITIVITIES = new Key<int[]>("android.sensor.info.availableSensitivities", int[].class); - - public static final class ColorFilterArrangementKey extends Key<Sensor.Info.ColorFilterArrangementKey.Enum> { - public enum Enum { - RGGB, - GRBG, - GBRG, - BGGR, - RGB; - } - - public static final Enum RGGB = Enum.RGGB; - public static final Enum GRBG = Enum.GRBG; - public static final Enum GBRG = Enum.GBRG; - public static final Enum BGGR = Enum.BGGR; - public static final Enum RGB = Enum.RGB; - - // TODO: remove requirement for constructor by making Key an interface - private ColorFilterArrangementKey(String name) { - super(name, Sensor.Info.ColorFilterArrangementKey.Enum.class); - } - - } - - public static final Key<Sensor.Info.ColorFilterArrangementKey.Enum> COLOR_FILTER_ARRANGEMENT = - new ColorFilterArrangementKey("android.sensor.info.colorFilterArrangement"); public static final Key<long[]> EXPOSURE_TIME_RANGE = new Key<long[]>("android.sensor.info.exposureTimeRange", long[].class); public static final Key<Long> MAX_FRAME_DURATION = new Key<Long>("android.sensor.info.maxFrameDuration", long.class); public static final Key<float[]> PHYSICAL_SIZE = new Key<float[]>("android.sensor.info.physicalSize", float[].class); - public static final Key<int[]> PIXEL_ARRAY_SIZE = - new Key<int[]>("android.sensor.info.pixelArraySize", int[].class); - public static final Key<Integer> WHITE_LEVEL = - new Key<Integer>("android.sensor.info.whiteLevel", int.class); } - public static final Key<Rational> BASE_GAIN_FACTOR = new Key<Rational>("android.sensor.baseGainFactor", Rational.class); - public static final Key<int[]> BLACK_LEVEL_PATTERN = - new Key<int[]>("android.sensor.blackLevelPattern", int[].class); - public static final Key<Rational[]> CALIBRATION_TRANSFORM1 = - new Key<Rational[]>("android.sensor.calibrationTransform1", Rational[].class); - public static final Key<Rational[]> CALIBRATION_TRANSFORM2 = - new Key<Rational[]>("android.sensor.calibrationTransform2", Rational[].class); - public static final Key<Rational[]> COLOR_TRANSFORM1 = - new Key<Rational[]>("android.sensor.colorTransform1", Rational[].class); - public static final Key<Rational[]> COLOR_TRANSFORM2 = - new Key<Rational[]>("android.sensor.colorTransform2", Rational[].class); - public static final Key<Rational[]> FORWARD_MATRIX1 = - new Key<Rational[]>("android.sensor.forwardMatrix1", Rational[].class); - public static final Key<Rational[]> FORWARD_MATRIX2 = - new Key<Rational[]>("android.sensor.forwardMatrix2", Rational[].class); public static final Key<Integer> MAX_ANALOG_SENSITIVITY = new Key<Integer>("android.sensor.maxAnalogSensitivity", int.class); - public static final Key<float[]> NOISE_MODEL_COEFFICIENTS = - new Key<float[]>("android.sensor.noiseModelCoefficients", float[].class); public static final Key<Integer> ORIENTATION = new Key<Integer>("android.sensor.orientation", int.class); - public static final class ReferenceIlluminant1Key extends Key<Sensor.ReferenceIlluminant1Key.Enum> { - public enum Enum { - DAYLIGHT, - FLUORESCENT, - TUNGSTEN, - FLASH, - FINE_WEATHER, - CLOUDY_WEATHER, - SHADE, - DAYLIGHT_FLUORESCENT, - DAY_WHITE_FLUORESCENT, - COOL_WHITE_FLUORESCENT, - WHITE_FLUORESCENT, - STANDARD_A, - STANDARD_B, - STANDARD_C, - D55, - D65, - D75, - D50, - ISO_STUDIO_TUNGSTEN; - } - - public static final Enum DAYLIGHT = Enum.DAYLIGHT; - public static final Enum FLUORESCENT = Enum.FLUORESCENT; - public static final Enum TUNGSTEN = Enum.TUNGSTEN; - public static final Enum FLASH = Enum.FLASH; - public static final Enum FINE_WEATHER = Enum.FINE_WEATHER; - public static final Enum CLOUDY_WEATHER = Enum.CLOUDY_WEATHER; - public static final Enum SHADE = Enum.SHADE; - public static final Enum DAYLIGHT_FLUORESCENT = Enum.DAYLIGHT_FLUORESCENT; - public static final Enum DAY_WHITE_FLUORESCENT = Enum.DAY_WHITE_FLUORESCENT; - public static final Enum COOL_WHITE_FLUORESCENT = Enum.COOL_WHITE_FLUORESCENT; - public static final Enum WHITE_FLUORESCENT = Enum.WHITE_FLUORESCENT; - public static final Enum STANDARD_A = Enum.STANDARD_A; - public static final Enum STANDARD_B = Enum.STANDARD_B; - public static final Enum STANDARD_C = Enum.STANDARD_C; - public static final Enum D55 = Enum.D55; - public static final Enum D65 = Enum.D65; - public static final Enum D75 = Enum.D75; - public static final Enum D50 = Enum.D50; - public static final Enum ISO_STUDIO_TUNGSTEN = Enum.ISO_STUDIO_TUNGSTEN; - - // TODO: remove requirement for constructor by making Key an interface - private ReferenceIlluminant1Key(String name) { - super(name, Sensor.ReferenceIlluminant1Key.Enum.class); - } - - static { - CameraMetadata.registerEnumValues(Sensor.ReferenceIlluminant1Key.Enum.class, new int[] { - 1, // DAYLIGHT - 2, // FLUORESCENT - 3, // TUNGSTEN - 4, // FLASH - 9, // FINE_WEATHER - 10, // CLOUDY_WEATHER - 11, // SHADE - 12, // DAYLIGHT_FLUORESCENT - 13, // DAY_WHITE_FLUORESCENT - 14, // COOL_WHITE_FLUORESCENT - 15, // WHITE_FLUORESCENT - 17, // STANDARD_A - 18, // STANDARD_B - 19, // STANDARD_C - 20, // D55 - 21, // D65 - 22, // D75 - 23, // D50 - 24 // ISO_STUDIO_TUNGSTEN - }); - } - } - - public static final Key<Sensor.ReferenceIlluminant1Key.Enum> REFERENCE_ILLUMINANT1 = - new ReferenceIlluminant1Key("android.sensor.referenceIlluminant1"); - public static final Key<Byte> REFERENCE_ILLUMINANT2 = - new Key<Byte>("android.sensor.referenceIlluminant2", byte.class); - } + public static final class Statistics { public static final class Info { public static final Key<byte[]> AVAILABLE_FACE_DETECT_MODES = new Key<byte[]>("android.statistics.info.availableFaceDetectModes", byte[].class); - public static final Key<Integer> HISTOGRAM_BUCKET_COUNT = - new Key<Integer>("android.statistics.info.histogramBucketCount", int.class); public static final Key<Integer> MAX_FACE_COUNT = new Key<Integer>("android.statistics.info.maxFaceCount", int.class); - public static final Key<Integer> MAX_HISTOGRAM_COUNT = - new Key<Integer>("android.statistics.info.maxHistogramCount", int.class); - public static final Key<Integer> MAX_SHARPNESS_MAP_VALUE = - new Key<Integer>("android.statistics.info.maxSharpnessMapValue", int.class); - public static final Key<int[]> SHARPNESS_MAP_SIZE = - new Key<int[]>("android.statistics.info.sharpnessMapSize", int[].class); } - } - public static final class Tonemap { + public static final class Tonemap { public static final Key<Integer> MAX_CURVE_POINTS = new Key<Integer>("android.tonemap.maxCurvePoints", int.class); } - public static final class Led { + /** + * @hide + */ + public static final class Led { + /** + * @hide + */ public static final class AvailableLedsKey extends Key<Led.AvailableLedsKey.Enum[]> { public enum Enum { TRANSMIT; @@ -404,12 +232,15 @@ public final class CameraPropertiesKeys { } + /** + * @hide + */ public static final Key<Led.AvailableLedsKey.Enum[]> AVAILABLE_LEDS = new AvailableLedsKey("android.led.availableLeds"); } - public static final class Info { + public static final class Info { public static final class SupportedHardwareLevelKey extends Key<Info.SupportedHardwareLevelKey.Enum> { public enum Enum { @@ -431,6 +262,7 @@ public final class CameraPropertiesKeys { new SupportedHardwareLevelKey("android.info.supportedHardwareLevel"); } + } diff --git a/core/java/android/hardware/photography/CaptureRequestKeys.java b/core/java/android/hardware/photography/CaptureRequestKeys.java index b8abe2b..b23e71d 100644 --- a/core/java/android/hardware/photography/CaptureRequestKeys.java +++ b/core/java/android/hardware/photography/CaptureRequestKeys.java @@ -40,7 +40,6 @@ import static android.hardware.photography.CameraMetadata.Key; public final class CaptureRequestKeys { public static final class ColorCorrection { - public static final class ModeKey extends Key<ColorCorrection.ModeKey.Enum> { public enum Enum { TRANSFORM_MATRIX, @@ -65,8 +64,8 @@ public final class CaptureRequestKeys { new Key<float[]>("android.colorCorrection.transform", float[].class); } - public static final class Control { + public static final class Control { public static final class AeAntibandingModeKey extends Key<Control.AeAntibandingModeKey.Enum> { public enum Enum { @@ -435,32 +434,9 @@ public final class CaptureRequestKeys { new VideoStabilizationModeKey("android.control.videoStabilizationMode"); } - public static final class Demosaic { - - - public static final class ModeKey extends Key<Demosaic.ModeKey.Enum> { - public enum Enum { - FAST, - HIGH_QUALITY; - } - - public static final Enum FAST = Enum.FAST; - public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY; - - // TODO: remove requirement for constructor by making Key an interface - private ModeKey(String name) { - super(name, Demosaic.ModeKey.Enum.class); - } - - } - - public static final Key<Demosaic.ModeKey.Enum> MODE = - new ModeKey("android.demosaic.mode"); - } public static final class Edge { - public static final class ModeKey extends Key<Edge.ModeKey.Enum> { public enum Enum { OFF, @@ -481,16 +457,10 @@ public final class CaptureRequestKeys { public static final Key<Edge.ModeKey.Enum> MODE = new ModeKey("android.edge.mode"); - public static final Key<Byte> STRENGTH = - new Key<Byte>("android.edge.strength", byte.class); } - public static final class Flash { - public static final Key<Byte> FIRING_POWER = - new Key<Byte>("android.flash.firingPower", byte.class); - public static final Key<Long> FIRING_TIME = - new Key<Long>("android.flash.firingTime", long.class); + public static final class Flash { public static final class ModeKey extends Key<Flash.ModeKey.Enum> { public enum Enum { @@ -514,60 +484,8 @@ public final class CaptureRequestKeys { new ModeKey("android.flash.mode"); } - public static final class Geometric { - - - public static final class ModeKey extends Key<Geometric.ModeKey.Enum> { - public enum Enum { - OFF, - FAST, - HIGH_QUALITY; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum FAST = Enum.FAST; - public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY; - - // TODO: remove requirement for constructor by making Key an interface - private ModeKey(String name) { - super(name, Geometric.ModeKey.Enum.class); - } - - } - - public static final Key<Geometric.ModeKey.Enum> MODE = - new ModeKey("android.geometric.mode"); - public static final Key<Byte> STRENGTH = - new Key<Byte>("android.geometric.strength", byte.class); - - } - public static final class HotPixel { - - public static final class ModeKey extends Key<HotPixel.ModeKey.Enum> { - public enum Enum { - OFF, - FAST, - HIGH_QUALITY; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum FAST = Enum.FAST; - public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY; - - // TODO: remove requirement for constructor by making Key an interface - private ModeKey(String name) { - super(name, HotPixel.ModeKey.Enum.class); - } - - } - - public static final Key<HotPixel.ModeKey.Enum> MODE = - new ModeKey("android.hotPixel.mode"); - - } public static final class Jpeg { - public static final Key<double[]> GPS_COORDINATES = new Key<double[]>("android.jpeg.gpsCoordinates", double[].class); public static final Key<Byte> GPS_PROCESSING_METHOD = @@ -584,8 +502,8 @@ public final class CaptureRequestKeys { new Key<int[]>("android.jpeg.thumbnailSize", int[].class); } - public static final class Lens { + public static final class Lens { public static final Key<Float> APERTURE = new Key<Float>("android.lens.aperture", float.class); public static final Key<Float> FILTER_DENSITY = @@ -615,8 +533,8 @@ public final class CaptureRequestKeys { new OpticalStabilizationModeKey("android.lens.opticalStabilizationMode"); } - public static final class NoiseReduction { + public static final class NoiseReduction { public static final class ModeKey extends Key<NoiseReduction.ModeKey.Enum> { public enum Enum { @@ -638,68 +556,28 @@ public final class CaptureRequestKeys { public static final Key<NoiseReduction.ModeKey.Enum> MODE = new ModeKey("android.noiseReduction.mode"); - public static final Key<Byte> STRENGTH = - new Key<Byte>("android.noiseReduction.strength", byte.class); } - public static final class Request { - public static final Key<Integer> FRAME_COUNT = - new Key<Integer>("android.request.frameCount", int.class); + /** + * @hide + */ + public static final class Request { + /** + * @hide + */ public static final Key<Integer> ID = new Key<Integer>("android.request.id", int.class); - public static final Key<Byte> INPUT_STREAMS = - new Key<Byte>("android.request.inputStreams", byte.class); - - public static final class MetadataModeKey extends Key<Request.MetadataModeKey.Enum> { - public enum Enum { - NONE, - FULL; - } - - public static final Enum NONE = Enum.NONE; - public static final Enum FULL = Enum.FULL; - - // TODO: remove requirement for constructor by making Key an interface - private MetadataModeKey(String name) { - super(name, Request.MetadataModeKey.Enum.class); - } - - } - - public static final Key<Request.MetadataModeKey.Enum> METADATA_MODE = - new MetadataModeKey("android.request.metadataMode"); - public static final Key<Byte> OUTPUT_STREAMS = - new Key<Byte>("android.request.outputStreams", byte.class); - - public static final class TypeKey extends Key<Request.TypeKey.Enum> { - public enum Enum { - CAPTURE, - REPROCESS; - } - - public static final Enum CAPTURE = Enum.CAPTURE; - public static final Enum REPROCESS = Enum.REPROCESS; - - // TODO: remove requirement for constructor by making Key an interface - private TypeKey(String name) { - super(name, Request.TypeKey.Enum.class); - } - - } - - public static final Key<Request.TypeKey.Enum> TYPE = - new TypeKey("android.request.type"); } - public static final class Scaler { + public static final class Scaler { public static final Key<int[]> CROP_REGION = new Key<int[]>("android.scaler.cropRegion", int[].class); } - public static final class Sensor { + public static final class Sensor { public static final Key<Long> EXPOSURE_TIME = new Key<Long>("android.sensor.exposureTime", long.class); public static final Key<Long> FRAME_DURATION = @@ -708,36 +586,9 @@ public final class CaptureRequestKeys { new Key<Integer>("android.sensor.sensitivity", int.class); } - public static final class Shading { - - - public static final class ModeKey extends Key<Shading.ModeKey.Enum> { - public enum Enum { - OFF, - FAST, - HIGH_QUALITY; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum FAST = Enum.FAST; - public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY; - - // TODO: remove requirement for constructor by making Key an interface - private ModeKey(String name) { - super(name, Shading.ModeKey.Enum.class); - } - - } - - public static final Key<Shading.ModeKey.Enum> MODE = - new ModeKey("android.shading.mode"); - public static final Key<Byte> STRENGTH = - new Key<Byte>("android.shading.strength", byte.class); - } public static final class Statistics { - public static final class FaceDetectModeKey extends Key<Statistics.FaceDetectModeKey.Enum> { public enum Enum { OFF, @@ -759,47 +610,9 @@ public final class CaptureRequestKeys { public static final Key<Statistics.FaceDetectModeKey.Enum> FACE_DETECT_MODE = new FaceDetectModeKey("android.statistics.faceDetectMode"); - public static final class HistogramModeKey extends Key<Statistics.HistogramModeKey.Enum> { - public enum Enum { - OFF, - ON; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum ON = Enum.ON; - - // TODO: remove requirement for constructor by making Key an interface - private HistogramModeKey(String name) { - super(name, Statistics.HistogramModeKey.Enum.class); - } - - } - - public static final Key<Statistics.HistogramModeKey.Enum> HISTOGRAM_MODE = - new HistogramModeKey("android.statistics.histogramMode"); - - public static final class SharpnessMapModeKey extends Key<Statistics.SharpnessMapModeKey.Enum> { - public enum Enum { - OFF, - ON; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum ON = Enum.ON; - - // TODO: remove requirement for constructor by making Key an interface - private SharpnessMapModeKey(String name) { - super(name, Statistics.SharpnessMapModeKey.Enum.class); - } - - } - - public static final Key<Statistics.SharpnessMapModeKey.Enum> SHARPNESS_MAP_MODE = - new SharpnessMapModeKey("android.statistics.sharpnessMapMode"); - } - public static final class Tonemap { + public static final class Tonemap { public static final Key<Float> CURVE_BLUE = new Key<Float>("android.tonemap.curveBlue", float.class); public static final Key<Float> CURVE_GREEN = @@ -829,9 +642,15 @@ public final class CaptureRequestKeys { new ModeKey("android.tonemap.mode"); } - public static final class Led { + /** + * @hide + */ + public static final class Led { + /** + * @hide + */ public static final class TransmitKey extends Key<Led.TransmitKey.Enum> { public enum Enum { OFF, @@ -848,10 +667,14 @@ public final class CaptureRequestKeys { } + /** + * @hide + */ public static final Key<Led.TransmitKey.Enum> TRANSMIT = new TransmitKey("android.led.transmit"); } + } diff --git a/core/java/android/hardware/photography/CaptureResultKeys.java b/core/java/android/hardware/photography/CaptureResultKeys.java index 5a638ed..e44fc91 100644 --- a/core/java/android/hardware/photography/CaptureResultKeys.java +++ b/core/java/android/hardware/photography/CaptureResultKeys.java @@ -40,7 +40,6 @@ import static android.hardware.photography.CameraMetadata.Key; public final class CaptureResultKeys { public static final class ColorCorrection { - public static final class ModeKey extends Key<ColorCorrection.ModeKey.Enum> { public enum Enum { TRANSFORM_MATRIX, @@ -63,8 +62,11 @@ public final class CaptureResultKeys { new ModeKey("android.colorCorrection.mode"); } - public static final class Control { + public static final class Control { + /** + * @hide + */ public static final Key<Integer> AE_PRECAPTURE_ID = new Key<Integer>("android.control.aePrecaptureId", int.class); public static final Key<int[]> AE_REGIONS = @@ -152,6 +154,9 @@ public final class CaptureResultKeys { public static final Key<Control.AfStateKey.Enum> AF_STATE = new AfStateKey("android.control.afState"); + /** + * @hide + */ public static final Key<Integer> AF_TRIGGER_ID = new Key<Integer>("android.control.afTriggerId", int.class); @@ -235,8 +240,8 @@ public final class CaptureResultKeys { new ModeKey("android.control.mode"); } - public static final class Edge { + public static final class Edge { public static final class ModeKey extends Key<Edge.ModeKey.Enum> { public enum Enum { @@ -260,12 +265,8 @@ public final class CaptureResultKeys { new ModeKey("android.edge.mode"); } - public static final class Flash { - public static final Key<Byte> FIRING_POWER = - new Key<Byte>("android.flash.firingPower", byte.class); - public static final Key<Long> FIRING_TIME = - new Key<Long>("android.flash.firingTime", long.class); + public static final class Flash { public static final class ModeKey extends Key<Flash.ModeKey.Enum> { public enum Enum { @@ -312,33 +313,8 @@ public final class CaptureResultKeys { new StateKey("android.flash.state"); } - public static final class HotPixel { - - - public static final class ModeKey extends Key<HotPixel.ModeKey.Enum> { - public enum Enum { - OFF, - FAST, - HIGH_QUALITY; - } - public static final Enum OFF = Enum.OFF; - public static final Enum FAST = Enum.FAST; - public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY; - - // TODO: remove requirement for constructor by making Key an interface - private ModeKey(String name) { - super(name, HotPixel.ModeKey.Enum.class); - } - - } - - public static final Key<HotPixel.ModeKey.Enum> MODE = - new ModeKey("android.hotPixel.mode"); - - } public static final class Jpeg { - public static final Key<double[]> GPS_COORDINATES = new Key<double[]>("android.jpeg.gpsCoordinates", double[].class); public static final Key<Byte> GPS_PROCESSING_METHOD = @@ -349,16 +325,14 @@ public final class CaptureResultKeys { new Key<Integer>("android.jpeg.orientation", int.class); public static final Key<Byte> QUALITY = new Key<Byte>("android.jpeg.quality", byte.class); - public static final Key<Integer> SIZE = - new Key<Integer>("android.jpeg.size", int.class); public static final Key<Byte> THUMBNAIL_QUALITY = new Key<Byte>("android.jpeg.thumbnailQuality", byte.class); public static final Key<int[]> THUMBNAIL_SIZE = new Key<int[]>("android.jpeg.thumbnailSize", int[].class); } - public static final class Lens { + public static final class Lens { public static final Key<Float> APERTURE = new Key<Float>("android.lens.aperture", float.class); public static final Key<Float> FILTER_DENSITY = @@ -407,8 +381,8 @@ public final class CaptureResultKeys { new StateKey("android.lens.state"); } - public static final class NoiseReduction { + public static final class NoiseReduction { public static final class ModeKey extends Key<NoiseReduction.ModeKey.Enum> { public enum Enum { @@ -432,43 +406,25 @@ public final class CaptureResultKeys { new ModeKey("android.noiseReduction.mode"); } - public static final class Request { + public static final class Request { public static final Key<Integer> FRAME_COUNT = new Key<Integer>("android.request.frameCount", int.class); + /** + * @hide + */ public static final Key<Integer> ID = new Key<Integer>("android.request.id", int.class); - public static final class MetadataModeKey extends Key<Request.MetadataModeKey.Enum> { - public enum Enum { - NONE, - FULL; - } - - public static final Enum NONE = Enum.NONE; - public static final Enum FULL = Enum.FULL; - - // TODO: remove requirement for constructor by making Key an interface - private MetadataModeKey(String name) { - super(name, Request.MetadataModeKey.Enum.class); - } - - } - - public static final Key<Request.MetadataModeKey.Enum> METADATA_MODE = - new MetadataModeKey("android.request.metadataMode"); - public static final Key<Byte> OUTPUT_STREAMS = - new Key<Byte>("android.request.outputStreams", byte.class); - } - public static final class Scaler { + public static final class Scaler { public static final Key<int[]> CROP_REGION = new Key<int[]>("android.scaler.cropRegion", int[].class); } - public static final class Sensor { + public static final class Sensor { public static final Key<Long> EXPOSURE_TIME = new Key<Long>("android.sensor.exposureTime", long.class); public static final Key<Long> FRAME_DURATION = @@ -479,34 +435,9 @@ public final class CaptureResultKeys { new Key<Long>("android.sensor.timestamp", long.class); } - public static final class Shading { - - - public static final class ModeKey extends Key<Shading.ModeKey.Enum> { - public enum Enum { - OFF, - FAST, - HIGH_QUALITY; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum FAST = Enum.FAST; - public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY; - - // TODO: remove requirement for constructor by making Key an interface - private ModeKey(String name) { - super(name, Shading.ModeKey.Enum.class); - } - } - - public static final Key<Shading.ModeKey.Enum> MODE = - new ModeKey("android.shading.mode"); - - } public static final class Statistics { - public static final class FaceDetectModeKey extends Key<Statistics.FaceDetectModeKey.Enum> { public enum Enum { OFF, @@ -535,52 +466,10 @@ public final class CaptureResultKeys { new Key<int[]>("android.statistics.faceRectangles", int[].class); public static final Key<byte[]> FACE_SCORES = new Key<byte[]>("android.statistics.faceScores", byte[].class); - public static final Key<int[]> HISTOGRAM = - new Key<int[]>("android.statistics.histogram", int[].class); - - public static final class HistogramModeKey extends Key<Statistics.HistogramModeKey.Enum> { - public enum Enum { - OFF, - ON; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum ON = Enum.ON; - - // TODO: remove requirement for constructor by making Key an interface - private HistogramModeKey(String name) { - super(name, Statistics.HistogramModeKey.Enum.class); - } - - } - - public static final Key<Statistics.HistogramModeKey.Enum> HISTOGRAM_MODE = - new HistogramModeKey("android.statistics.histogramMode"); - public static final Key<int[]> SHARPNESS_MAP = - new Key<int[]>("android.statistics.sharpnessMap", int[].class); - - public static final class SharpnessMapModeKey extends Key<Statistics.SharpnessMapModeKey.Enum> { - public enum Enum { - OFF, - ON; - } - - public static final Enum OFF = Enum.OFF; - public static final Enum ON = Enum.ON; - - // TODO: remove requirement for constructor by making Key an interface - private SharpnessMapModeKey(String name) { - super(name, Statistics.SharpnessMapModeKey.Enum.class); - } - - } - - public static final Key<Statistics.SharpnessMapModeKey.Enum> SHARPNESS_MAP_MODE = - new SharpnessMapModeKey("android.statistics.sharpnessMapMode"); } - public static final class Tonemap { + public static final class Tonemap { public static final Key<Float> CURVE_BLUE = new Key<Float>("android.tonemap.curveBlue", float.class); public static final Key<Float> CURVE_GREEN = @@ -610,9 +499,15 @@ public final class CaptureResultKeys { new ModeKey("android.tonemap.mode"); } - public static final class Led { + /** + * @hide + */ + public static final class Led { + /** + * @hide + */ public static final class TransmitKey extends Key<Led.TransmitKey.Enum> { public enum Enum { OFF, @@ -629,10 +524,14 @@ public final class CaptureResultKeys { } + /** + * @hide + */ public static final Key<Led.TransmitKey.Enum> TRANSMIT = new TransmitKey("android.led.transmit"); } + } diff --git a/core/java/android/print/PrintFileAdapter.java b/core/java/android/print/FileDocumentAdapter.java index dab9648..2871d45 100644 --- a/core/java/android/print/PrintFileAdapter.java +++ b/core/java/android/print/FileDocumentAdapter.java @@ -16,11 +16,14 @@ package android.print; +import android.content.Context; import android.os.AsyncTask; import android.os.CancellationSignal; import android.os.CancellationSignal.OnCancelListener; import android.util.Log; +import com.android.internal.R; + import libcore.io.IoUtils; import java.io.File; @@ -36,53 +39,54 @@ import java.util.List; /** * Adapter for printing files. */ -class PrintFileAdapter extends PrintAdapter { +final class FileDocumentAdapter extends PrintDocumentAdapter { + + private static final String LOG_TAG = "FileDocumentAdapter"; - private static final String LOG_TAG = "PrintFileAdapter"; + private final Context mContext; private final File mFile; private WriteFileAsyncTask mWriteFileAsyncTask; - public PrintFileAdapter(File file) { + public FileDocumentAdapter(Context context, File file) { if (file == null) { throw new IllegalArgumentException("File cannot be null!"); } + mContext = context; mFile = file; } @Override - public void onPrint(List<PageRange> pages, FileDescriptor destination, - CancellationSignal cancellationSignal, PrintResultCallback callback) { - mWriteFileAsyncTask = new WriteFileAsyncTask(mFile, destination, cancellationSignal, - callback); - mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, - (Void[]) null); - + public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, + CancellationSignal cancellationSignal, LayoutResultCallback callback) { + // TODO: When we have a PDF rendering library we should query the page count. + PrintDocumentInfo info = new PrintDocumentInfo.Builder() + .setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN).create(); + callback.onLayoutFinished(info, false); } @Override - public PrintAdapterInfo getInfo() { - // TODO: When we have PDF render library we should query the page count. - return new PrintAdapterInfo.Builder().create(); + public void onWrite(List<PageRange> pages, FileDescriptor destination, + CancellationSignal cancellationSignal, WriteResultCallback callback) { + mWriteFileAsyncTask = new WriteFileAsyncTask(destination, cancellationSignal, callback); + mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, + (Void[]) null); } - private static final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> { - - private final File mSource; + private final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> { private final FileDescriptor mDestination; - private final PrintResultCallback mResultCallback; + private final WriteResultCallback mResultCallback; private final CancellationSignal mCancellationSignal; - public WriteFileAsyncTask(File source, FileDescriptor destination, - CancellationSignal cancellationSignal, PrintResultCallback callback) { - mSource = source; + public WriteFileAsyncTask(FileDescriptor destination, + CancellationSignal cancellationSignal, WriteResultCallback callback) { mDestination = destination; mResultCallback = callback; - mCancellationSignal = cancellationSignal; + mCancellationSignal = cancellationSignal; mCancellationSignal.setOnCancelListener(new OnCancelListener() { @Override public void onCancel() { @@ -97,8 +101,11 @@ class PrintFileAdapter extends PrintAdapter { OutputStream out = new FileOutputStream(mDestination); final byte[] buffer = new byte[8192]; try { - in = new FileInputStream(mSource); + in = new FileInputStream(mFile); while (true) { + if (isCancelled()) { + break; + } final int readByteCount = in.read(buffer); if (readByteCount < 0) { break; @@ -106,20 +113,28 @@ class PrintFileAdapter extends PrintAdapter { out.write(buffer, 0, readByteCount); } } catch (IOException ioe) { - Log.e(LOG_TAG, "Error writing data!", ioe); + Log.e(LOG_TAG, "Error writing data!", ioe); + mResultCallback.onWriteFailed(mContext.getString( + R.string.write_fail_reason_cannot_write)); } finally { IoUtils.closeQuietly(in); IoUtils.closeQuietly(out); - if (!isCancelled()) { - List<PageRange> pages = new ArrayList<PageRange>(); - pages.add(PageRange.ALL_PAGES); - mResultCallback.onPrintFinished(pages); - } else { - mResultCallback.onPrintFailed("Cancelled"); - } } return null; } + + @Override + protected void onPostExecute(Void result) { + List<PageRange> pages = new ArrayList<PageRange>(); + pages.add(PageRange.ALL_PAGES); + mResultCallback.onWriteFinished(pages); + } + + @Override + protected void onCancelled(Void result) { + mResultCallback.onWriteFailed(mContext.getString( + R.string.write_fail_reason_cancelled)); + } } } diff --git a/core/java/android/print/ILayoutResultCallback.aidl b/core/java/android/print/ILayoutResultCallback.aidl new file mode 100644 index 0000000..e4d79f3 --- /dev/null +++ b/core/java/android/print/ILayoutResultCallback.aidl @@ -0,0 +1,31 @@ +/* + * 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.ICancellationSignal; +import android.print.PrintDocumentInfo; + +/** + * Callback for observing the result of android.print.PrintAdapter#onLayout. + * + * @hide + */ +oneway interface ILayoutResultCallback { + void onLayoutStarted(ICancellationSignal cancellationSignal); + void onLayoutFinished(in PrintDocumentInfo info, boolean changed); + void onLayoutFailed(CharSequence error); +} diff --git a/core/java/android/print/IPrintAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl index f3ff8c4..36938e3 100644 --- a/core/java/android/print/IPrintAdapter.aidl +++ b/core/java/android/print/IPrintDocumentAdapter.aidl @@ -17,7 +17,8 @@ package android.print; import android.os.ParcelFileDescriptor; -import android.print.IPrintResultCallback; +import android.print.ILayoutResultCallback; +import android.print.IWriteResultCallback; import android.print.PageRange; import android.print.PrintAttributes; @@ -26,10 +27,11 @@ import android.print.PrintAttributes; * * @hide */ -oneway interface IPrintAdapter { +oneway interface IPrintDocumentAdapter { void start(); - void printAttributesChanged(in PrintAttributes attributes); - void print(in List<PageRange> pages, in ParcelFileDescriptor fd, - IPrintResultCallback callback); + void layout(in PrintAttributes oldAttributes, in PrintAttributes newAttributes, + ILayoutResultCallback callback); + void write(in List<PageRange> pages, in ParcelFileDescriptor fd, + IWriteResultCallback callback); void finish(); } diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl index ff9877e..a466e74 100644 --- a/core/java/android/print/IPrintManager.aidl +++ b/core/java/android/print/IPrintManager.aidl @@ -16,11 +16,8 @@ package android.print; -import android.os.ICancellationSignal; -import android.print.IPrintAdapter; +import android.print.IPrintDocumentAdapter; import android.print.IPrintClient; -import android.print.IPrinterDiscoveryObserver; -import android.print.PrinterId; import android.print.PrintJobInfo; import android.print.PrintAttributes; @@ -30,12 +27,11 @@ import android.print.PrintAttributes; * @hide */ interface IPrintManager { - List<PrintJobInfo> getPrintJobs(int appId, int userId); - PrintJobInfo getPrintJob(int printJobId, int appId, int userId); - PrintJobInfo print(String printJobName, in IPrintClient client, in IPrintAdapter printAdapter, - in PrintAttributes attributes, int appId, int userId); + List<PrintJobInfo> getPrintJobInfos(int appId, int userId); + PrintJobInfo getPrintJobInfo(int 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 onPrintJobQueued(in PrinterId printerId, in PrintJobInfo printJob); - void startDiscoverPrinters(IPrinterDiscoveryObserver observer); - void stopDiscoverPrinters(); + } diff --git a/core/java/android/print/IPrintSpoolerService.aidl b/core/java/android/print/IPrintSpooler.aidl index e84d592..c55205d 100644 --- a/core/java/android/print/IPrintSpoolerService.aidl +++ b/core/java/android/print/IPrintSpooler.aidl @@ -18,32 +18,35 @@ package android.print; import android.content.ComponentName; import android.os.ParcelFileDescriptor; -import android.print.IPrintAdapter; +import android.print.IPrintDocumentAdapter; import android.print.IPrintClient; -import android.print.IPrintSpoolerServiceCallbacks; +import android.print.IPrintSpoolerClient; +import android.print.IPrintSpoolerCallbacks; import android.print.PrinterInfo; import android.print.PrintAttributes; /** * Interface for communication with the print spooler service. * - * @see android.print.IPrintSpoolerServiceCallbacks + * @see android.print.IPrintSpoolerCallbacks * * @hide */ -oneway interface IPrintSpoolerService { - void getPrintJobs(IPrintSpoolerServiceCallbacks callback, in ComponentName componentName, +oneway interface IPrintSpooler { + void getPrintJobInfos(IPrintSpoolerCallbacks callback, in ComponentName componentName, int state, int appId, int sequence); - void getPrintJob(int printJobId, IPrintSpoolerServiceCallbacks callback, + void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback, int appId, int sequence); - void createPrintJob(String printJobName, in IPrintClient client, in IPrintAdapter printAdapter, - in PrintAttributes attributes, IPrintSpoolerServiceCallbacks callback, int appId, - int sequence); - void cancelPrintJob(int printJobId, IPrintSpoolerServiceCallbacks callback, + void createPrintJob(String printJobName, in IPrintClient client, + in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes, + IPrintSpoolerCallbacks callback, int appId, int sequence); + void cancelPrintJob(int printJobId, IPrintSpoolerCallbacks callback, int appId, int sequence); - void setPrintJobState(int printJobId, int status, IPrintSpoolerServiceCallbacks callback, + void setPrintJobState(int printJobId, int status, IPrintSpoolerCallbacks callback, int sequence); - void setPrintJobTag(int printJobId, String tag, IPrintSpoolerServiceCallbacks callback, + void setPrintJobTag(int printJobId, String tag, IPrintSpoolerCallbacks callback, int sequence); void writePrintJobData(in ParcelFileDescriptor fd, int printJobId); -}
\ No newline at end of file + void setClient(IPrintSpoolerClient client); + void notifyClientForActivteJobs(); +} diff --git a/core/java/android/print/IPrintSpoolerServiceCallbacks.aidl b/core/java/android/print/IPrintSpoolerCallbacks.aidl index 0c51913..7912964 100644 --- a/core/java/android/print/IPrintSpoolerServiceCallbacks.aidl +++ b/core/java/android/print/IPrintSpoolerCallbacks.aidl @@ -26,8 +26,8 @@ import java.util.List; * * @hide */ -oneway interface IPrintSpoolerServiceCallbacks { - void onGetPrintJobsResult(in List<PrintJobInfo> printJob, int sequence); +oneway interface IPrintSpoolerCallbacks { + void onGetPrintJobInfosResult(in List<PrintJobInfo> printJob, int sequence); void onGetPrintJobInfoResult(in PrintJobInfo printJob, int sequence); void onCreatePrintJobResult(in PrintJobInfo printJob, int sequence); void onCancelPrintJobResult(boolean canceled, int sequence); diff --git a/core/java/android/print/IPrintSpoolerClient.aidl b/core/java/android/print/IPrintSpoolerClient.aidl new file mode 100644 index 0000000..47975e1 --- /dev/null +++ b/core/java/android/print/IPrintSpoolerClient.aidl @@ -0,0 +1,35 @@ +/* + * 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.content.ComponentName; +import android.print.IPrinterDiscoveryObserver; +import android.print.PrintJobInfo; + + +/** + * Interface for receiving interesting state updates from the print spooler. + * + * @hide + */ +oneway interface IPrintSpoolerClient { + void onPrintJobQueued(in PrintJobInfo printJob); + void onStartPrinterDiscovery(IPrinterDiscoveryObserver observer); + void onStopPrinterDiscovery(); + void onAllPrintJobsForServiceHandled(in ComponentName printService); + void onAllPrintJobsHandled(); +} diff --git a/core/java/android/print/IPrintSpoolerObserver.aidl b/core/java/android/print/IPrintSpoolerObserver.aidl new file mode 100644 index 0000000..7b8f40e --- /dev/null +++ b/core/java/android/print/IPrintSpoolerObserver.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.print; + +import android.print.PrinterId; +import android.print.PrinterInfo; + +/** + * Interface for observing the state of the print spooler. + * + * @hide + */ +oneway interface IPrinterDiscoveryObserver { + void onPrintJobQueued(in PrinterId printerId, in PrintJobInfo printJob); + void onAllPrintJobsHandled(in ComponentName printService); + void onAllPrintJobsHandled(); +} diff --git a/core/java/android/print/IPrintResultCallback.aidl b/core/java/android/print/IWriteResultCallback.aidl index 838377e..d5428b1 100644 --- a/core/java/android/print/IPrintResultCallback.aidl +++ b/core/java/android/print/IWriteResultCallback.aidl @@ -18,16 +18,14 @@ package android.print; import android.os.ICancellationSignal; import android.print.PageRange; -import android.print.PrintAdapterInfo; /** - * Callbacks for observing the print progress (writing of printed content) - * of a PrintAdapter. + * Callback for observing the result of android.print.DocuemntAdapter#onWrite. * * @hide */ -oneway interface IPrintResultCallback { - void onPrintStarted(in PrintAdapterInfo info, ICancellationSignal cancellationSignal); - void onPrintFinished(in List<PageRange> pages); - void onPrintFailed(CharSequence error); +oneway interface IWriteResultCallback { + void onWriteStarted(ICancellationSignal cancellationSignal); + void onWriteFinished(in List<PageRange> pages); + void onWriteFailed(CharSequence error); } diff --git a/core/java/android/print/PrintAdapter.java b/core/java/android/print/PrintAdapter.java deleted file mode 100644 index 6547c55..0000000 --- a/core/java/android/print/PrintAdapter.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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.CancellationSignal; - -import java.io.FileDescriptor; -import java.util.List; - -/** - * Base class that provides data to be printed. - * - * <h3>Lifecycle</h3> - * <p> - * <ul> - * <li> - * You will receive a call on {@link #onStart()} when printing starts. - * This callback can be used to allocate resources. - * </li> - * <li> - * Next you will get one or more calls to {@link #onPrintAttributesChanged( - * PrintAttributes) to informs you that the print attributes (page size, density, - * etc) changed giving you an opportunity to re-layout the content. - * </li> - * <li> - * After every {@link #onPrintAttributesChanged(PrintAttributes) you will receive - * one or more calls to {@link #onPrint(List, FileDescriptor, CancellationSignal, - * PrintResultCallback)} asking you to write a PDF file with the content for - * specific pages. - * </li> - * <li> - * Finally, you will receive a call on {@link #onFinish()} right after printing. - * You can use this callback to release resources. - * </li> - * <li> - * You can receive calls to {@link #getInfo()} at any point after a call to - * {@link #onPrintAttributesChanged(PrintAttributes)} which should return - * a {@link PrintAdapterInfo} describing your {@link PrintAdapter}. - * </li> - * </ul> - * </p> - * <p> - */ -public abstract class PrintAdapter { - - /** - * Called when printing started. You can use this callback to - * allocate resources. - * <p> - * <strong>Note:</strong> Invoked on the main thread. - * </p> - */ - public void onStart() { - /* do nothing - stub */ - } - - /** - * Called when the print job attributes (page size, density, etc) - * changed giving you a chance to re-layout the content such that - * it matches the new constraints. - * <p> - * <strong>Note:</strong> Invoked on the main thread. - * </p> - * - * @param attributes The print job attributes. - * @return Whether the content changed based on the provided attributes. - */ - public boolean onPrintAttributesChanged(PrintAttributes attributes) { - return false; - } - - /** - * Called when specific pages of the content have to be printed in the from of - * a PDF file to the given file descriptor. You should <strong>not</strong> - * close the file descriptor instead you have to invoke {@link PrintResultCallback - * #onPrintFinished()} or {@link PrintResultCallback#onPrintFailed(CharSequence)}. - * <p> - * <strong>Note:</strong> If the printed content is large, it is a good - * practice to schedule writing it on a dedicated thread and register a - * callback in the provided {@link CancellationSignal} upon invocation of - * which you should stop writing data. The cancellation callback will not - * be made on the main thread. - * </p> - * <p> - * <strong>Note:</strong> Invoked on the main thread. - * </p> - * - * @param pages The pages whose content to print. - * @param destination The destination file descriptor to which to start writing. - * @param cancellationSignal Signal for observing cancel print requests. - * @param progressListener Callback to inform the system with the write progress. - * - * @see CancellationSignal - */ - public abstract void onPrint(List<PageRange> pages, FileDescriptor destination, - CancellationSignal cancellationSignal, PrintResultCallback progressListener); - - /** - * Called when printing finished. You can use this callback to release - * resources. - * <p> - * <strong>Note:</strong> Invoked on the main thread. - * </p> - */ - public void onFinish() { - /* do nothing - stub */ - } - - /** - * Gets a {@link PrinterInfo} object that contains metadata about the - * printed content. - * <p> - * <strong>Note:</strong> Invoked on the main thread. - * </p> - * - * @return The info object for this {@link PrintAdapter}. - * - * @see PrintAdapterInfo - */ - public abstract PrintAdapterInfo getInfo(); - - /** - * Base class for implementing a listener for the print result - * of a {@link PrintAdapter}. - */ - public static abstract class PrintResultCallback { - - PrintResultCallback() { - /* do nothing - hide constructor */ - } - - /** - * Notifies that all the data was printed. - * - * @param pages The pages that were printed. - */ - public void onPrintFinished(List<PageRange> pages) { - /* do nothing - stub */ - } - - /** - * Notifies that an error occurred while printing the data. - * - * @param error Error message. May be null if error is unknown. - */ - public void onPrintFailed(CharSequence error) { - /* do nothing - stub */ - } - } -} diff --git a/core/java/android/print/PrintAdapterInfo.java b/core/java/android/print/PrintAdapterInfo.java deleted file mode 100644 index 06e6b10..0000000 --- a/core/java/android/print/PrintAdapterInfo.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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; - -/** - * This class encapsulates information about a {@link PrintAdapter} object. - */ -public final class PrintAdapterInfo implements Parcelable { - - /** - * Constant for unknown page count. - */ - public static final int PAGE_COUNT_UNKNOWN = -1; - - private int mPageCount; - private int mFlags; - - /** - * Creates a new instance. - */ - private PrintAdapterInfo() { - /* do nothing */ - } - - /** - * Creates a new instance. - * - * @param parcel Data from which to initialize. - */ - private PrintAdapterInfo(Parcel parcel) { - mPageCount = parcel.readInt(); - mFlags = parcel.readInt(); - } - - /** - * Gets the total number of pages. - * - * @return The number of pages. - */ - public int getPageCount() { - return mPageCount; - } - - /** - * @return The flags of this printable info. - * - * @see #FLAG_NOTIFY_FOR_ATTRIBUTES_CHANGE - */ - public int getFlags() { - return mFlags; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int flags) { - parcel.writeInt(mPageCount); - parcel.writeInt(mFlags); - } - - /** - * Builder for creating an {@link PrintAdapterInfo}. - */ - public static final class Builder { - private final PrintAdapterInfo mPrintableInfo = new PrintAdapterInfo(); - - /** - * Sets the total number of pages. - * - * @param pageCount The number of pages. Must be - * greater than zero. - */ - public Builder setPageCount(int pageCount) { - if (pageCount < 0) { - throw new IllegalArgumentException("pageCount" - + " must be greater than or euqal to zero!"); - } - mPrintableInfo.mPageCount = pageCount; - return this; - } - - /** - * Sets the flags of this printable info. - * - * @param flags The flags. - * - * @see #FLAG_NOTIFY_FOR_ATTRIBUTES_CHANGE - */ - public Builder setFlags(int flags) { - mPrintableInfo.mFlags = flags; - return this; - } - - /** - * Creates a new {@link PrintAdapterInfo} instance. - * - * @return The new instance. - */ - public PrintAdapterInfo create() { - return mPrintableInfo; - } - } - - public static final Parcelable.Creator<PrintAdapterInfo> CREATOR = - new Creator<PrintAdapterInfo>() { - @Override - public PrintAdapterInfo createFromParcel(Parcel parcel) { - return new PrintAdapterInfo(parcel); - } - - @Override - public PrintAdapterInfo[] newArray(int size) { - return new PrintAdapterInfo[size]; - } - }; -} diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java index 8511d0b..2a27a32 100644 --- a/core/java/android/print/PrintAttributes.java +++ b/core/java/android/print/PrintAttributes.java @@ -18,11 +18,10 @@ package android.print; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.Resources.NotFoundException; +import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; -import android.util.Log; import com.android.internal.R; @@ -388,196 +387,476 @@ public final class PrintAttributes implements Parcelable { * This class specifies a supported media size. */ public static final class MediaSize { - private static final String LOG_TAG = "MediaSize"; // TODO: Verify media sizes and add more standard ones. // ISO sizes - /** ISO A0 media size: 841mm x 1189mm (33.11" x 46.81") */ - public static final MediaSize ISO_A0 = - new MediaSize("ISO_A0", "android", R.string.mediaSize_iso_a0, 33110, 46810); - /** ISO A1 media size: 594mm x 841mm (23.39" x 33.11") */ - public static final MediaSize ISO_A1 = - new MediaSize("ISO_A1", "android", R.string.mediaSize_iso_a1, 23390, 33110); - /** ISO A2 media size: 420mm x 594mm (16.54" x 23.39") */ - public static final MediaSize ISO_A2 = - new MediaSize("ISO_A2", "android", R.string.mediaSize_iso_a2, 16540, 23390); - /** ISO A3 media size: 297mm x 420mm (11.69" x 16.54") */ - public static final MediaSize ISO_A3 = - new MediaSize("ISO_A3", "android", R.string.mediaSize_iso_a3, 11690, 16540); - /** ISO A4 media size: 210mm x 297mm (8.27" x 11.69") */ - public static final MediaSize ISO_A4 = - new MediaSize("ISO_A4", "android", R.string.mediaSize_iso_a4, 8270, 11690); - /** ISO A5 media size: 148mm x 210mm (5.83" x 8.27") */ - public static final MediaSize ISO_A5 = - new MediaSize("ISO_A5", "android", R.string.mediaSize_iso_a5, 5830, 8270); - /** ISO A6 media size: 105mm x 148mm (4.13" x 5.83") */ - public static final MediaSize ISO_A6 = - new MediaSize("ISO_A6", "android", R.string.mediaSize_iso_a6, 4130, 5830); - /** ISO A7 media size: 74mm x 105mm (2.91" x 4.13") */ - public static final MediaSize ISO_A7 = - new MediaSize("ISO_A7", "android", R.string.mediaSize_iso_a7, 2910, 4130); - /** ISO A8 media size: 52mm x 74mm (2.05" x 2.91") */ - public static final MediaSize ISO_A8 = - new MediaSize("ISO_A8", "android", R.string.mediaSize_iso_a8, 2050, 2910); - /** ISO A9 media size: 37mm x 52mm (1.46" x 2.05") */ - public static final MediaSize ISO_A9 = - new MediaSize("ISO_A9", "android", R.string.mediaSize_iso_a9, 1460, 2050); - /** ISO A10 media size: 26mm x 37mm (1.02" x 1.46") */ - public static final MediaSize ISO_A10 = - new MediaSize("ISO_A10", "android", R.string.mediaSize_iso_a10, 1020, 1460); - - /** ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67") */ - public static final MediaSize ISO_B0 = - new MediaSize("ISO_B0", "android", R.string.mediaSize_iso_b0, 39370, 55670); - /** ISO B1 media size: 707mm x 1000mm (27.83" x 39.37") */ - public static final MediaSize ISO_B1 = - new MediaSize("ISO_B1", "android", R.string.mediaSize_iso_b1, 27830, 39370); - /** ISO B2 media size: 500mm x 707mm (19.69" x 27.83") */ - public static final MediaSize ISO_B2 = - new MediaSize("ISO_B2", "android", R.string.mediaSize_iso_b2, 19690, 27830); - /** ISO B3 media size: 353mm x 500mm (13.90" x 19.69") */ - public static final MediaSize ISO_B3 = - new MediaSize("ISO_B3", "android", R.string.mediaSize_iso_b3, 13900, 19690); - /** ISO B4 media size: 250mm x 353mm (9.84" x 13.90") */ - public static final MediaSize ISO_B4 = - new MediaSize("ISO_B4", "android", R.string.mediaSize_iso_b4, 9840, 13900); - /** ISO B5 media size: 176mm x 250mm (6.93" x 9.84") */ - public static final MediaSize ISO_B5 = - new MediaSize("ISO_B5", "android", R.string.mediaSize_iso_b5, 6930, 9840); - /** ISO B6 media size: 125mm x 176mm (4.92" x 6.93") */ - public static final MediaSize ISO_B6 = - new MediaSize("ISO_B6", "android", R.string.mediaSize_iso_b6, 4920, 6930); - /** ISO B7 media size: 88mm x 125mm (3.46" x 4.92") */ - public static final MediaSize ISO_B7 = - new MediaSize("ISO_B7", "android", R.string.mediaSize_iso_b7, 3460, 4920); - /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46") */ - public static final MediaSize ISO_B8 = - new MediaSize("ISO_B8", "android", R.string.mediaSize_iso_b8, 2440, 3460); - /** ISO B9 media size: 44mm x 62mm (1.73" x 2.44") */ - public static final MediaSize ISO_B9 = - new MediaSize("ISO_B9", "android", R.string.mediaSize_iso_b9, 1730, 2440); - /** ISO B10 media size: 31mm x 44mm (1.22" x 1.73") */ - public static final MediaSize ISO_B10 = - new MediaSize("ISO_B10", "android", R.string.mediaSize_iso_b10, 1220, 1730); - - /** ISO C0 media size: 917mm x 1297mm (36.10" x 51.06") */ - public static final MediaSize ISO_C0 = - new MediaSize("ISO_C0", "android", R.string.mediaSize_iso_c0, 36100, 51060); - /** ISO C1 media size: 648mm x 917mm (25.51" x 36.10") */ - public static final MediaSize ISO_C1 = - new MediaSize("ISO_C1", "android", R.string.mediaSize_iso_c1, 25510, 36100); - /** ISO C2 media size: 458mm x 648mm (18.03" x 25.51") */ - public static final MediaSize ISO_C2 = - new MediaSize("ISO_C2", "android", R.string.mediaSize_iso_c2, 18030, 25510); - /** ISO C3 media size: 324mm x 458mm (12.76" x 18.03") */ - public static final MediaSize ISO_C3 = - new MediaSize("ISO_C3", "android", R.string.mediaSize_iso_c3, 12760, 18030); - /** ISO C4 media size: 229mm x 324mm (9.02" x 12.76") */ - public static final MediaSize ISO_C4 = - new MediaSize("ISO_C4", "android", R.string.mediaSize_iso_c4, 9020, 12760); - /** ISO C5 media size: 162mm x 229mm (6.38" x 9.02") */ - public static final MediaSize ISO_C5 = - new MediaSize("ISO_C5", "android", R.string.mediaSize_iso_c5, 6380, 9020); - /** ISO C6 media size: 114mm x 162mm (4.49" x 6.38") */ - public static final MediaSize ISO_C6 = - new MediaSize("ISO_C6", "android", R.string.mediaSize_iso_c6, 4490, 6380); - /** ISO C7 media size: 81mm x 114mm (3.19" x 4.49") */ - public static final MediaSize ISO_C7 = - new MediaSize("ISO_C7", "android", R.string.mediaSize_iso_c7, 3190, 4490); - /** ISO C8 media size: 57mm x 81mm (2.24" x 3.19") */ - public static final MediaSize ISO_C8 = - new MediaSize("ISO_C8", "android", R.string.mediaSize_iso_c8, 2240, 3190); - /** ISO C9 media size: 40mm x 57mm (1.57" x 2.24") */ - public static final MediaSize ISO_C9 = - new MediaSize("ISO_C9", "android", R.string.mediaSize_iso_c9, 1570, 2240); - /** ISO C10 media size: 28mm x 40mm (1.10" x 1.57") */ - public static final MediaSize ISO_C10 = - new MediaSize("ISO_C10", "android", R.string.mediaSize_iso_c10, 1100, 1570); + /** + * ISO A0 media size: 841mm x 1189mm (33.11" x 46.81") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A0 = 1; + + /** + * ISO A1 media size: 594mm x 841mm (23.39" x 33.11") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A1 = 2; + + /** + * + *ISO A2 media size: 420mm x 594mm (16.54" x 23.39") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A2 = 3; + + /** + * ISO A3 media size: 297mm x 420mm (11.69" x 16.54") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A3 = 4; + + /** + * ISO A4 media size: 210mm x 297mm (8.27" x 11.69") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A4 = 5; + + /** + * ISO A5 media size: 148mm x 210mm (5.83" x 8.27") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A5 = 6; + + /** + * ISO A6 media size: 105mm x 148mm (4.13" x 5.83") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A6 = 7; + + /** + * ISO A7 media size: 74mm x 105mm (2.91" x 4.13") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A7 = 8; + + /** + * ISO A8 media size: 52mm x 74mm (2.05" x 2.91") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A8 = 9; + + /** + * ISO A9 media size: 37mm x 52mm (1.46" x 2.05") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A9 = 10; + + /** + * ISO A10 media size: 26mm x 37mm (1.02" x 1.46") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_A10 = 11; + + + /** + * ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B0 = 100; + + /** + * ISO B1 media size: 707mm x 1000mm (27.83" x 39.37") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B1 = 101; + + /** + * ISO B2 media size: 500mm x 707mm (19.69" x 27.83") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B2 = 102; + + /** + * ISO B3 media size: 353mm x 500mm (13.90" x 19.69") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B3 = 103; + + /** + * ISO B4 media size: 250mm x 353mm (9.84" x 13.90") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B4 = 104; + + /** + * ISO B5 media size: 176mm x 250mm (6.93" x 9.84") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B5 = 105; + + /** + * ISO B6 media size: 125mm x 176mm (4.92" x 6.93") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B6 = 106; + + /** + * ISO B7 media size: 88mm x 125mm (3.46" x 4.92") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B7 = 107; + + /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B8 = 108; + + /** + * ISO B9 media size: 44mm x 62mm (1.73" x 2.44") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B9 = 109; + + /** + * ISO B10 media size: 31mm x 44mm (1.22" x 1.73") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_B10 = 110; + + + /** + * ISO C0 media size: 917mm x 1297mm (36.10" x 51.06") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C0 = 200; + + /** + * ISO C1 media size: 648mm x 917mm (25.51" x 36.10") + * + * @see #createMediaSize(PackageManager, int) + */ + + public static final int ISO_C1 = 201; + /** + * ISO C2 media size: 458mm x 648mm (18.03" x 25.51") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C2 = 202; + + /** + * ISO C3 media size: 324mm x 458mm (12.76" x 18.03") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C3 = 203; + + /** + * ISO C4 media size: 229mm x 324mm (9.02" x 12.76") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C4 = 204; + + /** + * ISO C5 media size: 162mm x 229mm (6.38" x 9.02") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C5 = 205; + + /** + * ISO C6 media size: 114mm x 162mm (4.49" x 6.38") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C6 = 206; + + /** + * ISO C7 media size: 81mm x 114mm (3.19" x 4.49") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C7 = 207; + + /** + * ISO C8 media size: 57mm x 81mm (2.24" x 3.19") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C8 = 208; + + /** + * ISO C9 media size: 40mm x 57mm (1.57" x 2.24") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C9 = 209; + + /** + * ISO C10 media size: 28mm x 40mm (1.10" x 1.57") + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int ISO_C10 = 210; + // North America - /** North America Letter media size: 8.5" x 11" */ - public static final MediaSize NA_LETTER = - new MediaSize("NA_LETTER", "android", R.string.mediaSize_na_letter, 8500, 11000); - /** North America Government-Letter media size: 8.0" x 10.5" */ - public static final MediaSize NA_GOVT_LETTER = - new MediaSize("NA_GOVT_LETTER", "android", - R.string.mediaSize_na_gvrnmt_letter, 8000, 10500); - /** North America Legal media size: 8.5" x 14" */ - public static final MediaSize NA_LEGAL = - new MediaSize("NA_LEGAL", "android", R.string.mediaSize_na_legal, 8500, 14000); - /** North America Junior Legal media size: 8.0" x 5.0" */ - public static final MediaSize NA_JUNIOR_LEGAL = - new MediaSize("NA_JUNIOR_LEGAL", "android", - R.string.mediaSize_na_junior_legal, 8000, 5000); - /** North America Ledger media size: 17" x 11" */ - public static final MediaSize NA_LEDGER = - new MediaSize("NA_LEDGER", "android", R.string.mediaSize_na_ledger, 17000, 11000); - /** North America Tabloid media size: 11" x 17" */ - public static final MediaSize NA_TBLOID = - new MediaSize("NA_TABLOID", "android", - R.string.mediaSize_na_tabloid, 11000, 17000); + /** + * North America Letter media size: 8.5" x 11" + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int NA_LETTER = 300; - private final String mId; - private final String mPackageName; - private final int mLabelResId; - private final int mWidthMils; - private final int mHeightMils; + /** + * North America Government-Letter media size: 8.0" x 10.5" + * + * @see #createMediaSize(PackageManager, int) + */ + public static final int NA_GOVT_LETTER = 301; /** - * Gets the unique media size id. + * North America Legal media size: 8.5" x 14" * - * @return The unique media size id. + * @see #createMediaSize(PackageManager, int) */ - public String getId() { - return mId; - } + public static final int NA_LEGAL = 302; /** - * Gets the human readable media size label. + * North America Junior Legal media size: 8.0" x 5.0" * - * @return The human readable label. + * @see #createMediaSize(PackageManager, int) */ - public CharSequence getLabel(PackageManager packageManager) { - try { - return packageManager.getResourcesForApplication( - mPackageName).getString(mLabelResId); - } catch (NotFoundException nfe) { - Log.w(LOG_TAG, "Could not load resouce" + mLabelResId - + " from package " + mPackageName); - } catch (NameNotFoundException nnfee) { - Log.w(LOG_TAG, "Could not load resouce" + mLabelResId - + " from package " + mPackageName); - } - return null; - } + public static final int NA_JUNIOR_LEGAL = 303; /** - * Gets the media width in mils (thousands of an inch). + * North America Ledger media size: 17" x 11" * - * @return The media width. + * @see #createMediaSize(PackageManager, int) */ - public int getWidthMils() { - return mWidthMils; - } + public static final int NA_LEDGER = 304; /** - * Gets the media height in mils (thousands of an inch). + * North America Tabloid media size: 11" x 17" * - * @return The media height. + * @see #createMediaSize(PackageManager, int) */ - public int getHeightMils() { - return mHeightMils; + public static final int NA_TBLOID = 305; + + /** + * Creates a standard media size with a localized label. + * + * @param pm Package manager used to load the label. + * @param mediaSize Media size constant. + * @return A {@link MediaSize} instance with a localized label. + */ + public static MediaSize createMediaSize(PackageManager pm, int mediaSize) { + final Resources resources; + try { + resources = pm.getResourcesForApplication("android"); + } catch (NameNotFoundException nnfe) { + return null; + } + switch (mediaSize) { + case ISO_A0: { + return new MediaSize("ISO_A0", resources + .getString(R.string.mediaSize_iso_a0), 33110, 46810); + } + case ISO_A1: { + return new MediaSize("ISO_A1", resources + .getString(R.string.mediaSize_iso_a1), 23390, 33110); + } + case ISO_A2: { + return new MediaSize("ISO_A2", resources + .getString(R.string.mediaSize_iso_a2), 16540, 23390); + } + case ISO_A3: { + return new MediaSize("ISO_A3", resources + .getString(R.string.mediaSize_iso_a3), 11690, 16540); + } + case ISO_A4: { + return new MediaSize("ISO_A4", resources + .getString(R.string.mediaSize_iso_a4), 8270, 11690); + } + case ISO_A5: { + return new MediaSize("ISO_A5", resources + .getString(R.string.mediaSize_iso_a5), 5830, 8270); + } + case ISO_A6: { + return new MediaSize("ISO_A6", resources + .getString(R.string.mediaSize_iso_a6), 4130, 5830); + } + case ISO_A7: { + return new MediaSize("ISO_A7", resources + .getString(R.string.mediaSize_iso_a7), 2910, 4130); + } + case ISO_A8: { + return new MediaSize("ISO_A8", resources + .getString(R.string.mediaSize_iso_a8), 2050, 2910); + } + case ISO_A9: { + return new MediaSize("ISO_A9", resources + .getString(R.string.mediaSize_iso_a9), 1460, 2050); + } + case ISO_A10: { + return new MediaSize("ISO_A10", resources + .getString(R.string.mediaSize_iso_a10), 1020, 1460); + } + case ISO_B0: { + return new MediaSize("ISO_B0", resources + .getString(R.string.mediaSize_iso_b0), 39370, 55670); + } + case ISO_B1: { + return new MediaSize("ISO_B1", resources + .getString(R.string.mediaSize_iso_b1), 27830, 39370); + } + case ISO_B2: { + return new MediaSize("ISO_B2", resources + .getString(R.string.mediaSize_iso_b2), 19690, 27830); + } + case ISO_B3: { + return new MediaSize("ISO_B3", resources + .getString(R.string.mediaSize_iso_b3), 13900, 19690); + } + case ISO_B4: { + return new MediaSize("ISO_B4", resources + .getString(R.string.mediaSize_iso_b4), 9840, 13900); + } + case ISO_B5: { + return new MediaSize("ISO_B5", resources + .getString(R.string.mediaSize_iso_b5), 6930, 9840); + } + case ISO_B6: { + return new MediaSize("ISO_B6", resources + .getString(R.string.mediaSize_iso_b6), 4920, 6930); + } + case ISO_B7: { + return new MediaSize("ISO_B7", resources + .getString(R.string.mediaSize_iso_b7), 3460, 4920); + } + case ISO_B8: { + return new MediaSize("ISO_B8", resources + .getString(R.string.mediaSize_iso_b8), 2440, 3460); + } + case ISO_B9: { + return new MediaSize("ISO_B9", resources + .getString(R.string.mediaSize_iso_b9), 1730, 2440); + } + case ISO_B10: { + return new MediaSize("ISO_B10", resources + .getString(R.string.mediaSize_iso_b10), 1220, 1730); + } + case ISO_C0: { + return new MediaSize("ISO_C0", resources + .getString(R.string.mediaSize_iso_c0), 36100, 51060); + } + case ISO_C1: { + return new MediaSize("ISO_C1", resources + .getString(R.string.mediaSize_iso_c1), 25510, 36100); + } + case ISO_C2: { + return new MediaSize("ISO_C2", resources + .getString(R.string.mediaSize_iso_c2), 18030, 25510); + } + case ISO_C3: { + return new MediaSize("ISO_C3", resources + .getString(R.string.mediaSize_iso_c3), 12760, 18030); + } + case ISO_C4: { + return new MediaSize("ISO_C4", resources + .getString(R.string.mediaSize_iso_c4), 9020, 12760); + } + case ISO_C5: { + return new MediaSize("ISO_C5", resources + .getString(R.string.mediaSize_iso_c5), 6380, 9020); + } + case ISO_C6: { + return new MediaSize("ISO_C6", resources + .getString(R.string.mediaSize_iso_c6), 4490, 6380); + } + case ISO_C7: { + return new MediaSize("ISO_C7", resources + .getString(R.string.mediaSize_iso_c7), 3190, 4490); + } + case ISO_C8: { + return new MediaSize("ISO_C8", resources + .getString(R.string.mediaSize_iso_c8), 2240, 3190); + } + case ISO_C9: { + return new MediaSize("ISO_C9", resources + .getString(R.string.mediaSize_iso_c9), 1570, 2240); + } + case ISO_C10: { + return new MediaSize("ISO_C10", resources + .getString(R.string.mediaSize_iso_c10), 1100, 1570); + } + case NA_LETTER: { + return new MediaSize("NA_LETTER", resources + .getString(R.string.mediaSize_na_letter), 8500, 11000); + } + case NA_GOVT_LETTER: { + return new MediaSize("NA_GOVT_LETTER", resources + .getString(R.string.mediaSize_na_gvrnmt_letter), 8000, 10500); + } + case NA_LEGAL: { + return new MediaSize("NA_LEGAL", resources + .getString(R.string.mediaSize_na_legal), 8500, 14000); + } + case NA_JUNIOR_LEGAL: { + return new MediaSize("NA_JUNIOR_LEGAL", resources + .getString(R.string.mediaSize_na_junior_legal), 8000, 5000); + } + case NA_LEDGER: { + return new MediaSize("NA_LEDGER", resources + .getString(R.string.mediaSize_na_ledger), 17000, 11000); + } + case NA_TBLOID: { + return new MediaSize("NA_TABLOID", resources + .getString(R.string.mediaSize_na_tabloid), 11000, 17000); + } + default: { + throw new IllegalArgumentException("Unknown media size."); + } + } } + private final String mId; + private final CharSequence mLabel; + private final int mWidthMils; + private final int mHeightMils; + /** * Creates a new instance. * * @param id The unique media size id. - * @param packageName The name of the creating package. - * @param labelResId The resource if of a human readable label. + * @param label The <strong>internationalized</strong> human readable label. * @param widthMils The width in mils (thousands of an inch). * @param heightMils The height in mils (thousands of an inch). * @@ -586,16 +865,12 @@ public final class PrintAttributes implements Parcelable { * @throws IllegalArgumentException If the widthMils is less than or equal to zero. * @throws IllegalArgumentException If the heightMils is less than or equal to zero. */ - public MediaSize(String id, String packageName, int labelResId, - int widthMils, int heightMils) { + public MediaSize(String id, CharSequence label, int widthMils, int heightMils) { if (TextUtils.isEmpty(id)) { throw new IllegalArgumentException("id cannot be empty."); } - if (TextUtils.isEmpty(packageName)) { - throw new IllegalArgumentException("packageName cannot be empty."); - } - if (labelResId <= 0) { - throw new IllegalArgumentException("labelResId must be greater than zero."); + if (TextUtils.isEmpty(label)) { + throw new IllegalArgumentException("label cannot be empty."); } if (widthMils <= 0) { throw new IllegalArgumentException("widthMils " @@ -605,17 +880,51 @@ public final class PrintAttributes implements Parcelable { throw new IllegalArgumentException("heightMils " + "cannot be less than or euqual to zero."); } - mPackageName = packageName; mId = id; - mLabelResId = labelResId; + mLabel = label; mWidthMils = widthMils; mHeightMils = heightMils; } + /** + * Gets the unique media size id. + * + * @return The unique media size id. + */ + public String getId() { + return mId; + } + + /** + * Gets the human readable media size label. + * + * @return The human readable label. + */ + public CharSequence getLabel() { + return mLabel; + } + + /** + * Gets the media width in mils (thousands of an inch). + * + * @return The media width. + */ + public int getWidthMils() { + return mWidthMils; + } + + /** + * Gets the media height in mils (thousands of an inch). + * + * @return The media height. + */ + public int getHeightMils() { + return mHeightMils; + } + void writeToParcel(Parcel parcel) { parcel.writeString(mId); - parcel.writeString(mPackageName); - parcel.writeInt(mLabelResId); + parcel.writeCharSequence(mLabel); parcel.writeInt(mWidthMils); parcel.writeInt(mHeightMils); } @@ -623,8 +932,7 @@ public final class PrintAttributes implements Parcelable { static MediaSize createFromParcel(Parcel parcel) { return new MediaSize( parcel.readString(), - parcel.readString(), - parcel.readInt(), + parcel.readCharSequence(), parcel.readInt(), parcel.readInt()); } @@ -634,8 +942,7 @@ public final class PrintAttributes implements Parcelable { StringBuilder builder = new StringBuilder(); builder.append("MediaSize{"); builder.append("id: ").append(mId); - builder.append(", packageName: ").append(mPackageName); - builder.append(", labelResId: ").append(mLabelResId); + builder.append(", label: ").append(mLabel); builder.append(", heightMils: ").append(mHeightMils); builder.append(", widthMils: ").append(mWidthMils); builder.append("}"); @@ -647,15 +954,46 @@ public final class PrintAttributes implements Parcelable { * This class specifies a supported resolution in dpi (dots per inch). */ public static final class Resolution { - private static final String LOG_TAG = "Resolution"; - private final String mId; - private final String mPackageName; - private final int mLabelResId; + private final CharSequence mLabel; private final int mHorizontalDpi; private final int mVerticalDpi; /** + * Creates a new instance. + * + * @param id The unique resolution id. + * @param label The <strong>internationalized</strong> human readable label. + * @param horizontalDpi The horizontal resolution in dpi. + * @param verticalDpi The vertical resolution in dpi. + * + * @throws IllegalArgumentException If the id is empty. + * @throws IllegalArgumentException If the label is empty. + * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero. + * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero. + */ + public Resolution(String id, CharSequence label, int horizontalDpi, int verticalDpi) { + if (TextUtils.isEmpty(id)) { + throw new IllegalArgumentException("id cannot be empty."); + } + if (TextUtils.isEmpty(label)) { + throw new IllegalArgumentException("label cannot be empty."); + } + if (horizontalDpi <= 0) { + throw new IllegalArgumentException("horizontalDpi " + + "cannot be less than or equal to zero."); + } + if (verticalDpi <= 0) { + throw new IllegalArgumentException("verticalDpi" + + " cannot be less than or equal to zero."); + } + mId = id; + mLabel = label; + mHorizontalDpi = horizontalDpi; + mVerticalDpi = verticalDpi; + } + + /** * Gets the unique resolution id. * * @return The unique resolution id. @@ -670,17 +1008,7 @@ public final class PrintAttributes implements Parcelable { * @return The human readable label. */ public CharSequence getLabel(PackageManager packageManager) { - try { - return packageManager.getResourcesForApplication( - mPackageName).getString(mLabelResId); - } catch (NotFoundException nfe) { - Log.w(LOG_TAG, "Could not load resouce" + mLabelResId - + " from package " + mPackageName); - } catch (NameNotFoundException nnfee) { - Log.w(LOG_TAG, "Could not load resouce" + mLabelResId - + " from package " + mPackageName); - } - return null; + return mLabel; } /** @@ -701,50 +1029,9 @@ public final class PrintAttributes implements Parcelable { return mVerticalDpi; } - /** - * Creates a new instance. - * - * @param id The unique resolution id. - * @param packageName The name of the creating package. - * @param labelResId The resource id of a human readable label. - * @param horizontalDpi The horizontal resolution in dpi. - * @param verticalDpi The vertical resolution in dpi. - * - * @throws IllegalArgumentException If the id is empty. - * @throws IllegalArgumentException If the label is empty. - * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero. - * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero. - */ - public Resolution(String id, String packageName, int labelResId, - int horizontalDpi, int verticalDpi) { - if (TextUtils.isEmpty(id)) { - throw new IllegalArgumentException("id cannot be empty."); - } - if (TextUtils.isEmpty(packageName)) { - throw new IllegalArgumentException("packageName cannot be empty."); - } - if (labelResId <= 0) { - throw new IllegalArgumentException("labelResId must be greater than zero."); - } - if (horizontalDpi <= 0) { - throw new IllegalArgumentException("horizontalDpi " - + "cannot be less than or equal to zero."); - } - if (verticalDpi <= 0) { - throw new IllegalArgumentException("verticalDpi" - + " cannot be less than or equal to zero."); - } - mId = id; - mPackageName = packageName; - mLabelResId = labelResId; - mHorizontalDpi = horizontalDpi; - mVerticalDpi = verticalDpi; - } - void writeToParcel(Parcel parcel) { parcel.writeString(mId); - parcel.writeString(mPackageName); - parcel.writeInt(mLabelResId); + parcel.writeCharSequence(mLabel); parcel.writeInt(mHorizontalDpi); parcel.writeInt(mVerticalDpi); } @@ -752,8 +1039,7 @@ public final class PrintAttributes implements Parcelable { static Resolution createFromParcel(Parcel parcel) { return new Resolution( parcel.readString(), - parcel.readString(), - parcel.readInt(), + parcel.readCharSequence(), parcel.readInt(), parcel.readInt()); } @@ -763,8 +1049,7 @@ public final class PrintAttributes implements Parcelable { StringBuilder builder = new StringBuilder(); builder.append("Resolution{"); builder.append("id: ").append(mId); - builder.append(", packageName: ").append(mPackageName); - builder.append(", labelResId: ").append(mLabelResId); + builder.append(", label: ").append(mLabel); builder.append(", horizontalDpi: ").append(mHorizontalDpi); builder.append(", verticalDpi: ").append(mVerticalDpi); builder.append("}"); @@ -782,6 +1067,38 @@ public final class PrintAttributes implements Parcelable { private final int mBottomMils; /** + * Creates a new instance. + * + * @param leftMils The left margin in mils (thousands of an inch). + * @param topMils The top margin in mils (thousands of an inch). + * @param rightMils The right margin in mils (thousands of an inch). + * @param bottomMils The bottom margin in mils (thousands of an inch). + * + * @throws IllegalArgumentException If the leftMils is less than zero. + * @throws IllegalArgumentException If the topMils is less than zero. + * @throws IllegalArgumentException If the rightMils is less than zero. + * @throws IllegalArgumentException If the bottomMils is less than zero. + */ + public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { + if (leftMils < 0) { + throw new IllegalArgumentException("leftMils cannot be less than zero."); + } + if (topMils < 0) { + throw new IllegalArgumentException("topMils cannot be less than zero."); + } + if (rightMils < 0) { + throw new IllegalArgumentException("rightMils cannot be less than zero."); + } + if (bottomMils < 0) { + throw new IllegalArgumentException("bottomMils cannot be less than zero."); + } + mTopMils = topMils; + mLeftMils = leftMils; + mRightMils = rightMils; + mBottomMils = bottomMils; + } + + /** * Gets the left margin in mils (thousands of an inch). * * @return The left margin. @@ -817,38 +1134,6 @@ public final class PrintAttributes implements Parcelable { return mBottomMils; } - /** - * Creates a new instance. - * - * @param leftMils The left margin in mils (thousands of an inch). - * @param topMils The top margin in mils (thousands of an inch). - * @param rightMils The right margin in mils (thousands of an inch). - * @param bottomMils The bottom margin in mils (thousands of an inch). - * - * @throws IllegalArgumentException If the leftMils is less than zero. - * @throws IllegalArgumentException If the topMils is less than zero. - * @throws IllegalArgumentException If the rightMils is less than zero. - * @throws IllegalArgumentException If the bottomMils is less than zero. - */ - public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { - if (leftMils < 0) { - throw new IllegalArgumentException("leftMils cannot be less than zero."); - } - if (topMils < 0) { - throw new IllegalArgumentException("topMils cannot be less than zero."); - } - if (rightMils < 0) { - throw new IllegalArgumentException("rightMils cannot be less than zero."); - } - if (bottomMils < 0) { - throw new IllegalArgumentException("bottomMils cannot be less than zero."); - } - mTopMils = topMils; - mLeftMils = leftMils; - mRightMils = rightMils; - mBottomMils = bottomMils; - } - void writeToParcel(Parcel parcel) { parcel.writeInt(mLeftMils); parcel.writeInt(mTopMils); @@ -881,11 +1166,28 @@ public final class PrintAttributes implements Parcelable { * Represents a printer tray. */ public static final class Tray { - private static final String LOG_TAG = "Tray"; - private final String mId; - private final String mPackageName; - private final int mLabelResId; + private final CharSequence mLabel; + + /** + * Creates a new instance. + * + * @param id The unique tray id. + * @param label The <strong>internationalized</strong> human readable label. + * + * @throws IllegalArgumentException If the id is empty. + * @throws IllegalArgumentException If the label is empty. + */ + public Tray(String id, CharSequence label) { + if (TextUtils.isEmpty(id)) { + throw new IllegalArgumentException("id cannot be empty."); + } + if (TextUtils.isEmpty(label)) { + throw new IllegalArgumentException("label cannot be empty."); + } + mId = id; + mLabel = label; + } /** * Gets the unique tray id. @@ -902,55 +1204,18 @@ public final class PrintAttributes implements Parcelable { * @return The human readable label. */ public CharSequence getLabel(PackageManager packageManager) { - try { - return packageManager.getResourcesForApplication( - mPackageName).getString(mLabelResId); - } catch (NotFoundException nfe) { - Log.w(LOG_TAG, "Could not load resouce" + mLabelResId - + " from package " + mPackageName); - } catch (NameNotFoundException nnfee) { - Log.w(LOG_TAG, "Could not load resouce" + mLabelResId - + " from package " + mPackageName); - } - return null; - } - - /** - * Creates a new instance. - * - * @param id The unique tray id. - * @param packageName The name of the creating package. - * @param labelResId The resource id of a human readable label. - * - * @throws IllegalArgumentException If the id is empty. - * @throws IllegalArgumentException If the label is empty. - */ - public Tray(String id, String packageName, int labelResId) { - if (TextUtils.isEmpty(id)) { - throw new IllegalArgumentException("id cannot be empty."); - } - if (TextUtils.isEmpty(packageName)) { - throw new IllegalArgumentException("packageName cannot be empty."); - } - if (labelResId <= 0) { - throw new IllegalArgumentException("label must be greater than zero."); - } - mId = id; - mPackageName = packageName; - mLabelResId = labelResId; + return mLabel; } void writeToParcel(Parcel parcel) { parcel.writeString(mId); - parcel.writeString(mPackageName); - parcel.writeInt(mLabelResId); + parcel.writeCharSequence(mLabel); } static Tray createFromParcel(Parcel parcel) { return new Tray( parcel.readString(), - parcel.readString(), - parcel.readInt()); + parcel.readCharSequence()); } @Override @@ -959,8 +1224,7 @@ public final class PrintAttributes implements Parcelable { builder.append("Tray{"); builder.append("id: ").append(mId); builder.append("id: ").append(mId); - builder.append(", packageName: ").append(mPackageName); - builder.append(", labelResId: ").append(mLabelResId); + builder.append(", label: ").append(mLabel); builder.append("}"); return builder.toString(); } diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java new file mode 100644 index 0000000..ef69400 --- /dev/null +++ b/core/java/android/print/PrintDocumentAdapter.java @@ -0,0 +1,200 @@ +/* + * 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.CancellationSignal; + +import java.io.FileDescriptor; +import java.util.List; + +/** + * Base class that provides the content of a document to be printed. + * + * <h3>Lifecycle</h3> + * <p> + * <ul> + * <li> + * Initially, you will receive a call to {@link #onStart()}. This callback + * can be used to allocate resources. + * </li> + * <li> + * Next, you will get one or more calls to {@link #onLayout(PrintAttributes, + * PrintAttributes, CancellationSignal, LayoutResultCallback)} to inform you + * that the print attributes (page size, density, etc) changed giving you an + * opportunity to layout the content to match the new constraints. + * </li> + * <li> + * After every call to {@link #onLayout(PrintAttributes, PrintAttributes, + * CancellationSignal, LayoutResultCallback)}, you may get a call to {@link + * #onWrite(List, FileDescriptor, CancellationSignal, WriteResultCallback)} + * asking you to write a PDF file with the content for specific pages. + * </li> + * <li> + * Finally, you will receive a call to {@link #onFinish()}. You can use this + * callback to release resources allocated in {@link #onStart()}. + * </li> + * </ul> + * </p> + */ +public abstract class PrintDocumentAdapter { + + /** + * Called when printing starts. You can use this callback to allocate + * resources. This method is invoked on the main thread. + */ + public void onStart() { + /* do nothing - stub */ + } + + /** + * Called when the print attributes (page size, density, etc) changed + * giving you a chance to layout the content such that it matches the + * new constraints. This method is invoked on the main thread. + * <p> + * After you are done laying out, you must invoke: {@link LayoutResultCallback + * #onLayoutFinished(PrintDocumentInfo, boolean)} with the last argument <code>true + * </code> or <code>false</code> depending on whether the layout changed the + * content or not, respectively; and {@link LayoutResultCallback#onLayoutFailed( + * CharSequence), if an error occurred. + * </p> + * <p> + * <strong>Note:</strong> If the content is large and a layout will be + * performed, it is a good practice to schedule the work on a dedicated + * thread and register an observer in the provided {@link + * CancellationSignal} upon invocation of which you should stop the + * layout. The cancellation callback will not be made on the main + * thread. + * </p> + * + * @param oldAttributes The old print attributes. + * @param newAttributes The new print attributes. + * @param cancellationSignal Signal for observing cancel layout requests. + * @param callback Callback to inform the system for the layout result. + * + * @see LayoutResultCallback + * @see CancellationSignal + */ + public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, + CancellationSignal cancellationSignal, LayoutResultCallback callback); + + /** + * Called when specific pages of the content should be written in the + * from of a PDF file to the given file descriptor. This method is invoked + * on the main thread. + *<p> + * After you are done writing, you should <strong>not</strong> close the + * file descriptor, rather you must invoke: {@link WriteResultCallback + * #onWriteFinished()}, if writing completed successfully; or {@link + * WriteResultCallback#onWriteFailed(CharSequence)}, if an error occurred. + * </p> + * <p> + * <strong>Note:</strong> If the printed content is large, it is a good + * practice to schedule writing it on a dedicated thread and register an + * observer in the provided {@link CancellationSignal} upon invocation of + * which you should stop writing. The cancellation callback will not be + * made on the main thread. + * </p> + * + * @param pages The pages whose content to print. + * @param destination The destination file descriptor to which to write. + * @param cancellationSignal Signal for observing cancel writing requests. + * @param callback Callback to inform the system for the write result. + * + * @see WriteResultCallback + * @see CancellationSignal + */ + public abstract void onWrite(List<PageRange> pages, FileDescriptor destination, + CancellationSignal cancellationSignal, WriteResultCallback callback); + + /** + * Called when printing finishes. You can use this callback to release + * resources acquired in {@link #onStart()}. This method is invoked on + * the main thread. + */ + public void onFinish() { + /* do nothing - stub */ + } + + /** + * Base class for implementing a callback for the result of {@link + * PrintDocumentAdapter#onWrite(List, FileDescriptor, CancellationSignal, + * WriteResultCallback)}. + */ + public static abstract class WriteResultCallback { + + /** + * @hide + */ + public WriteResultCallback() { + /* do nothing - hide constructor */ + } + + /** + * Notifies that all the data was written. + * + * @param pages The pages that were written. + */ + public void onWriteFinished(List<PageRange> pages) { + /* do nothing - stub */ + } + + /** + * Notifies that an error occurred while writing the data. + * + * @param error Error message. May be null if error is unknown. + */ + public void onWriteFailed(CharSequence error) { + /* do nothing - stub */ + } + } + + /** + * Base class for implementing a callback for the result of {@link + * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes, + * CancellationSignal, LayoutResultCallback)}. + */ + public static abstract class LayoutResultCallback { + + /** + * @hide + */ + public LayoutResultCallback() { + /* do nothing - hide constructor */ + } + + /** + * Notifies that the layout finished and whether the content changed. + * + * @param info An info object describing the document. + * @param changed Whether the layout changed. + * + * @see PrintDocumentInfo + */ + public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { + /* do nothing - stub */ + } + + /** + * Notifies that an error occurred while laying out the document. + * + * @param error Error message. May be null if error is unknown. + */ + public void onLayoutFailed(CharSequence error) { + /* do nothing - stub */ + } + } +} diff --git a/core/java/android/print/PrintAdapterInfo.aidl b/core/java/android/print/PrintDocumentInfo.aidl index 27bf717..831dcb7 100644 --- a/core/java/android/print/PrintAdapterInfo.aidl +++ b/core/java/android/print/PrintDocumentInfo.aidl @@ -16,4 +16,4 @@ package android.print; -parcelable PrintAdapterInfo; +parcelable PrintDocumentInfo; diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java new file mode 100644 index 0000000..7731deb --- /dev/null +++ b/core/java/android/print/PrintDocumentInfo.java @@ -0,0 +1,171 @@ +/* + * 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; + +/** + * This class encapsulates information about a printed document. + */ +public final class PrintDocumentInfo implements Parcelable { + + /** + * Constant for unknown page count (default). + */ + public static final int PAGE_COUNT_UNKNOWN = -1; + + /** + * Content type: unknown (default). + */ + public static final int CONTENT_TYPE_UNKNOWN = -1; + + /** + * Content type: document. + */ + public static final int CONTENT_TYPE_DOCUMENT = 0; + + /** + * Content type: photo. + */ + public static final int CONTENT_TYPE_PHOTO = 1; + + private int mPageCount; + private int mContentType; + + /** + * Creates a new instance. + */ + private PrintDocumentInfo() { + mPageCount = PAGE_COUNT_UNKNOWN; + mContentType = CONTENT_TYPE_UNKNOWN; + } + + /** + * Creates a new instance. + * + * @param Prototype from which to clone. + */ + private PrintDocumentInfo(PrintDocumentInfo prototype) { + mPageCount = prototype.mPageCount; + mContentType = prototype.mContentType; + } + + /** + * Creates a new instance. + * + * @param parcel Data from which to initialize. + */ + private PrintDocumentInfo(Parcel parcel) { + mPageCount = parcel.readInt(); + mContentType = parcel.readInt(); + } + + /** + * Gets the total number of pages. + * + * @return The number of pages. + * + * @see #PAGE_COUNT_UNKNOWN + */ + public int getPageCount() { + return mPageCount; + } + + /** + * Gets the content type. + * + * @return The content type. + * + * @see #CONTENT_TYPE_UNKNOWN + * @see #CONTENT_TYPE_DOCUMENT + * @see #CONTENT_TYPE_PHOTO + */ + public int getContentType() { + return mContentType; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeInt(mPageCount); + parcel.writeInt(mContentType); + } + + /** + * Builder for creating an {@link PrintDocumentInfo}. + */ + public static final class Builder { + private final PrintDocumentInfo mPrototype = new PrintDocumentInfo(); + + /** + * Sets the total number of pages. + * + * @param pageCount The number of pages. Must be greater than + * or equal to zero or {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}. + */ + public Builder setPageCount(int pageCount) { + if (pageCount < 0 && pageCount != PAGE_COUNT_UNKNOWN) { + throw new IllegalArgumentException("pageCount" + + " must be greater than or euqal to zero or" + + " DocumentInfo#PAGE_COUNT_UNKNOWN"); + } + mPrototype.mPageCount = pageCount; + return this; + } + + /** + * Sets the content type. + * + * @param type The content type. + * + * @see #CONTENT_TYPE_UNKNOWN + * @see #CONTENT_TYPE_DOCUMENT + * @see #CONTENT_TYPE_PHOTO + */ + public Builder setContentType(int type) { + mPrototype.mContentType = type; + return this; + } + + /** + * Creates a new {@link PrintDocumentInfo} instance. + * + * @return The new instance. + */ + public PrintDocumentInfo create() { + return new PrintDocumentInfo(mPrototype); + } + } + + public static final Parcelable.Creator<PrintDocumentInfo> CREATOR = + new Creator<PrintDocumentInfo>() { + @Override + public PrintDocumentInfo createFromParcel(Parcel parcel) { + return new PrintDocumentInfo(parcel); + } + + @Override + public PrintDocumentInfo[] newArray(int size) { + return new PrintDocumentInfo[size]; + } + }; +} diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java index f7cca87..a5e0b79 100644 --- a/core/java/android/print/PrintJob.java +++ b/core/java/android/print/PrintJob.java @@ -55,7 +55,7 @@ public final class PrintJob { * @return The print job info. */ public PrintJobInfo getInfo() { - PrintJobInfo info = mPrintManager.getPrintJob(mId); + PrintJobInfo info = mPrintManager.getPrintJobInfo(mId); if (info != null) { mCachedInfo = info; } diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java index 72d6057..6e613bc 100644 --- a/core/java/android/print/PrintJobInfo.java +++ b/core/java/android/print/PrintJobInfo.java @@ -116,6 +116,44 @@ public final class PrintJobInfo implements Parcelable { /** The print job attributes size. */ private PrintAttributes mAttributes; + /** Information about the printed document. */ + private PrintDocumentInfo mDocumentInfo; + + /** @hide*/ + public PrintJobInfo() { + /* do nothing */ + } + + /** @hide */ + public PrintJobInfo(PrintJobInfo other) { + mId = other.mId; + mLabel = other.mLabel; + mPrinterId = other.mPrinterId; + mState = other.mState; + mAppId = other.mAppId; + mUserId = other.mUserId; + mAttributes = other.mAttributes; + mDocumentInfo = other.mDocumentInfo; + } + + private PrintJobInfo(Parcel parcel) { + mId = parcel.readInt(); + mLabel = parcel.readCharSequence(); + mPrinterId = parcel.readParcelable(null); + mState = parcel.readInt(); + mAppId = parcel.readInt(); + mUserId = parcel.readInt(); + if (parcel.readInt() == 1) { + mPageRanges = (PageRange[]) parcel.readParcelableArray(null); + } + if (parcel.readInt() == 1) { + mAttributes = PrintAttributes.CREATOR.createFromParcel(parcel); + } + if (parcel.readInt() == 1) { + mDocumentInfo = PrintDocumentInfo.CREATOR.createFromParcel(parcel); + } + } + /** * Gets the unique print job id. * @@ -300,35 +338,26 @@ public final class PrintJobInfo implements Parcelable { mAttributes = attributes; } - /** @hide*/ - public PrintJobInfo() { - /* do nothing */ - } - - /** @hide */ - public PrintJobInfo(PrintJobInfo other) { - mId = other.mId; - mLabel = other.mLabel; - mPrinterId = other.mPrinterId; - mState = other.mState; - mAppId = other.mAppId; - mUserId = other.mUserId; - mAttributes = other.mAttributes; + /** + * Gets the info describing the printed document. + * + * @return The document info. + * + * @hide + */ + public PrintDocumentInfo getDocumentInfo() { + return mDocumentInfo; } - private PrintJobInfo(Parcel parcel) { - mId = parcel.readInt(); - mLabel = parcel.readCharSequence(); - mPrinterId = parcel.readParcelable(null); - mState = parcel.readInt(); - mAppId = parcel.readInt(); - mUserId = parcel.readInt(); - if (parcel.readInt() == 1) { - mPageRanges = (PageRange[]) parcel.readParcelableArray(null); - } - if (parcel.readInt() == 1) { - mAttributes = PrintAttributes.CREATOR.createFromParcel(parcel); - } + /** + * Sets the info describing the printed document. + * + * @param info The document info. + * + * @hide + */ + public void setDocumentInfo(PrintDocumentInfo info) { + mDocumentInfo = info; } @Override @@ -356,6 +385,12 @@ public final class PrintJobInfo implements Parcelable { } else { parcel.writeInt(0); } + if (mDocumentInfo != null) { + parcel.writeInt(1); + mDocumentInfo.writeToParcel(parcel, flags); + } else { + parcel.writeInt(0); + } } @Override @@ -366,7 +401,10 @@ public final class PrintJobInfo implements Parcelable { builder.append(", id: ").append(mId); builder.append(", status: ").append(stateToString(mState)); builder.append(", printer: " + mPrinterId); - builder.append(", attributes: " + (mAttributes != null ? mAttributes.toString() : null)); + builder.append(", attributes: " + (mAttributes != null + ? mAttributes.toString() : null)); + builder.append(", documentInfo: " + (mDocumentInfo != null + ? mDocumentInfo.toString() : null)); builder.append("}"); return builder.toString(); } diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index be9b596..5ca19d4 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -26,7 +26,8 @@ import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.print.PrintAdapter.PrintResultCallback; +import android.print.PrintDocumentAdapter.LayoutResultCallback; +import android.print.PrintDocumentAdapter.WriteResultCallback; import android.util.Log; import com.android.internal.os.SomeArgs; @@ -103,7 +104,7 @@ public final class PrintManager { * Creates an instance that can access all print jobs. * * @param userId The user id for which to get all print jobs. - * @return An instance of the caller has the permission to access + * @return An instance if the caller has the permission to access * all print jobs, null otherwise. * * @hide @@ -112,11 +113,11 @@ public final class PrintManager { return new PrintManager(mContext, mService, userId, APP_ID_ANY); } - PrintJobInfo getPrintJob(int printJobId) { + PrintJobInfo getPrintJobInfo(int printJobId) { try { - return mService.getPrintJob(printJobId, mAppId, mUserId); + return mService.getPrintJobInfo(printJobId, mAppId, mUserId); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error getting print job:" + printJobId, re); + Log.e(LOG_TAG, "Error getting a print job info:" + printJobId, re); } return null; } @@ -130,7 +131,7 @@ public final class PrintManager { */ public List<PrintJob> getPrintJobs() { try { - List<PrintJobInfo> printJobInfos = mService.getPrintJobs(mAppId, mUserId); + List<PrintJobInfo> printJobInfos = mService.getPrintJobInfos(mAppId, mUserId); if (printJobInfos == null) { return Collections.emptyList(); } @@ -141,18 +142,17 @@ public final class PrintManager { } return printJobs; } catch (RemoteException re) { - Log.e(LOG_TAG, "Error getting print jobs!", re); + Log.e(LOG_TAG, "Error getting print jobs", re); } return Collections.emptyList(); } - ICancellationSignal cancelPrintJob(int printJobId) { + void cancelPrintJob(int printJobId) { try { mService.cancelPrintJob(printJobId, mAppId, mUserId); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error cancleing a print job:" + printJobId, re); + Log.e(LOG_TAG, "Error cancleing a print job: " + printJobId, re); } - return null; } /** @@ -166,24 +166,24 @@ public final class PrintManager { * @see PrintJob */ public PrintJob print(String printJobName, File pdfFile, PrintAttributes attributes) { - PrintFileAdapter printable = new PrintFileAdapter(pdfFile); - return print(printJobName, printable, attributes); + FileDocumentAdapter documentAdapter = new FileDocumentAdapter(mContext, pdfFile); + return print(printJobName, documentAdapter, attributes); } /** - * Creates a print job for printing a {@link PrintAdapter} with default print + * Creates a print job for printing a {@link PrintDocumentAdapter} with default print * attributes. * * @param printJobName A name for the new print job. - * @param printAdapter The printable adapter to print. + * @param documentAdapter An adapter that emits the document to print. * @param attributes The default print job attributes. * @return The created print job. * * @see PrintJob */ - public PrintJob print(String printJobName, PrintAdapter printAdapter, + public PrintJob print(String printJobName, PrintDocumentAdapter documentAdapter, PrintAttributes attributes) { - PrintAdapterDelegate delegate = new PrintAdapterDelegate(printAdapter, + PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter, mContext.getMainLooper()); try { PrintJobInfo printJob = mService.print(printJobName, mPrintClient, delegate, @@ -217,145 +217,118 @@ public final class PrintManager { } } - private static final class PrintAdapterDelegate extends IPrintAdapter.Stub { - private final Object mLock = new Object(); - - private PrintAdapter mPrintAdapter; + private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub { + private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in finish() - private Handler mHandler; + private Handler mHandler; // Strong reference OK - cleared in finish() - public PrintAdapterDelegate(PrintAdapter printAdapter, Looper looper) { - mPrintAdapter = printAdapter; + public PrintDocumentAdapterDelegate(PrintDocumentAdapter documentAdapter, Looper looper) { + mDocumentAdapter = documentAdapter; mHandler = new MyHandler(looper); } @Override public void start() { - synchronized (mLock) { - if (isFinishedLocked()) { - return; - } - mHandler.obtainMessage(MyHandler.MESSAGE_START, - mPrintAdapter).sendToTarget(); - } + mHandler.sendEmptyMessage(MyHandler.MSG_START); } @Override - public void printAttributesChanged(PrintAttributes attributes) { - synchronized (mLock) { - if (isFinishedLocked()) { - return; - } - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mPrintAdapter; - args.arg2 = attributes; - mHandler.obtainMessage(MyHandler.MESSAGE_PRINT_ATTRIBUTES_CHANGED, - args).sendToTarget(); - } + public void layout(PrintAttributes oldAttributes, + PrintAttributes newAttributes, ILayoutResultCallback callback) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = oldAttributes; + args.arg2 = newAttributes; + args.arg3 = callback; + mHandler.obtainMessage(MyHandler.MSG_LAYOUT, args).sendToTarget(); } @Override - public void print(List<PageRange> pages, ParcelFileDescriptor fd, - IPrintResultCallback callback) { - synchronized (mLock) { - if (isFinishedLocked()) { - return; - } - SomeArgs args = SomeArgs.obtain(); - args.arg1 = mPrintAdapter; - args.arg2 = pages; - args.arg3 = fd.getFileDescriptor(); - args.arg4 = callback; - mHandler.obtainMessage(MyHandler.MESSAGE_PRINT, args).sendToTarget(); - } + public void write(List<PageRange> pages, ParcelFileDescriptor fd, + IWriteResultCallback callback) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = pages; + args.arg2 = fd.getFileDescriptor(); + args.arg3 = callback; + mHandler.obtainMessage(MyHandler.MSG_WRITE, args).sendToTarget(); } @Override public void finish() { - synchronized (mLock) { - if (isFinishedLocked()) { - return; - } - mHandler.obtainMessage(MyHandler.MESSAGE_FINIS, - mPrintAdapter).sendToTarget(); - } + mHandler.sendEmptyMessage(MyHandler.MSG_FINISH); } - private boolean isFinishedLocked() { - return mPrintAdapter == null; + private boolean isFinished() { + return mDocumentAdapter == null; } - private void finishLocked() { - mPrintAdapter = null; + private void doFinish() { + mDocumentAdapter = null; mHandler = null; } private final class MyHandler extends Handler { - public static final int MESSAGE_START = 1; - public static final int MESSAGE_PRINT_ATTRIBUTES_CHANGED = 2; - public static final int MESSAGE_PRINT = 3; - public static final int MESSAGE_FINIS = 4; + public static final int MSG_START = 1; + public static final int MSG_LAYOUT = 2; + public static final int MSG_WRITE = 3; + public static final int MSG_FINISH = 4; public MyHandler(Looper looper) { super(looper, null, true); } @Override + @SuppressWarnings("unchecked") public void handleMessage(Message message) { + if (isFinished()) { + return; + } switch (message.what) { - case MESSAGE_START: { - PrintAdapter adapter = (PrintAdapter) message.obj; - adapter.onStart(); + case MSG_START: { + mDocumentAdapter.onStart(); } break; - case MESSAGE_PRINT_ATTRIBUTES_CHANGED: { + case MSG_LAYOUT: { SomeArgs args = (SomeArgs) message.obj; - PrintAdapter adapter = (PrintAdapter) args.arg1; - PrintAttributes attributes = (PrintAttributes) args.arg2; + PrintAttributes oldAttributes = (PrintAttributes) args.arg1; + PrintAttributes newAttributes = (PrintAttributes) args.arg2; + ILayoutResultCallback callback = (ILayoutResultCallback) args.arg3; args.recycle(); - adapter.onPrintAttributesChanged(attributes); + + try { + ICancellationSignal remoteSignal = CancellationSignal.createTransport(); + callback.onLayoutStarted(remoteSignal); + + mDocumentAdapter.onLayout(oldAttributes, newAttributes, + CancellationSignal.fromTransport(remoteSignal), + new LayoutResultCallbackWrapper(callback)); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error printing", re); + } } break; - case MESSAGE_PRINT: { + case MSG_WRITE: { SomeArgs args = (SomeArgs) message.obj; - PrintAdapter adapter = (PrintAdapter) args.arg1; - @SuppressWarnings("unchecked") - List<PageRange> pages = (List<PageRange>) args.arg2; - final FileDescriptor fd = (FileDescriptor) args.arg3; - IPrintResultCallback callback = (IPrintResultCallback) args.arg4; + List<PageRange> pages = (List<PageRange>) args.arg1; + FileDescriptor fd = (FileDescriptor) args.arg2; + IWriteResultCallback callback = (IWriteResultCallback) args.arg3; args.recycle(); + try { ICancellationSignal remoteSignal = CancellationSignal.createTransport(); - callback.onPrintStarted(adapter.getInfo(), remoteSignal); - - CancellationSignal localSignal = CancellationSignal.fromTransport( - remoteSignal); - adapter.onPrint(pages, fd, localSignal, - new PrintResultCallbackWrapper(callback) { - @Override - public void onPrintFinished(List<PageRange> pages) { - IoUtils.closeQuietly(fd); - super.onPrintFinished(pages); - } - - @Override - public void onPrintFailed(CharSequence error) { - IoUtils.closeQuietly(fd); - super.onPrintFailed(error); - } - }); + callback.onWriteStarted(remoteSignal); + + mDocumentAdapter.onWrite(pages, fd, + CancellationSignal.fromTransport(remoteSignal), + new WriteResultCallbackWrapper(callback, fd)); } catch (RemoteException re) { Log.e(LOG_TAG, "Error printing", re); IoUtils.closeQuietly(fd); } } break; - case MESSAGE_FINIS: { - PrintAdapter adapter = (PrintAdapter) message.obj; - adapter.onFinish(); - synchronized (mLock) { - finishLocked(); - } + case MSG_FINISH: { + mDocumentAdapter.onFinish(); + doFinish(); } break; default: { @@ -367,29 +340,65 @@ public final class PrintManager { } } - private static abstract class PrintResultCallbackWrapper extends PrintResultCallback { + private static final class WriteResultCallbackWrapper extends WriteResultCallback { + + private final IWriteResultCallback mWrappedCallback; + private final FileDescriptor mFd; + + public WriteResultCallbackWrapper(IWriteResultCallback callback, + FileDescriptor fd) { + mWrappedCallback = callback; + mFd = fd; + } + + @Override + public void onWriteFinished(List<PageRange> pages) { + try { + // Close before notifying the other end. We want + // to be ready by the time we announce it. + IoUtils.closeQuietly(mFd); + mWrappedCallback.onWriteFinished(pages); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling onWriteFinished", re); + } + } + + @Override + public void onWriteFailed(CharSequence error) { + try { + // Close before notifying the other end. We want + // to be ready by the time we announce it. + IoUtils.closeQuietly(mFd); + mWrappedCallback.onWriteFailed(error); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling onWriteFailed", re); + } + } + } + + private static final class LayoutResultCallbackWrapper extends LayoutResultCallback { - private final IPrintResultCallback mWrappedCallback; + private final ILayoutResultCallback mWrappedCallback; - public PrintResultCallbackWrapper(IPrintResultCallback callback) { + public LayoutResultCallbackWrapper(ILayoutResultCallback callback) { mWrappedCallback = callback; } @Override - public void onPrintFinished(List<PageRange> pages) { + public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { try { - mWrappedCallback.onPrintFinished(pages); + mWrappedCallback.onLayoutFinished(info, changed); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling onPrintFinished", re); + Log.e(LOG_TAG, "Error calling onLayoutFinished", re); } } @Override - public void onPrintFailed(CharSequence error) { + public void onLayoutFailed(CharSequence error) { try { - mWrappedCallback.onPrintFailed(error); + mWrappedCallback.onLayoutFailed(error); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling onPrintFailed", re); + Log.e(LOG_TAG, "Error calling onLayoutFailed", re); } } } diff --git a/core/java/android/print/PrinterId.java b/core/java/android/print/PrinterId.java index b853eb0..8a3148c 100644 --- a/core/java/android/print/PrinterId.java +++ b/core/java/android/print/PrinterId.java @@ -54,7 +54,7 @@ public final class PrinterId implements Parcelable { * * @hide */ - public ComponentName getServiceComponentName() { + public ComponentName getService() { return mServiceComponentName; } diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java index 9283472..da3b6bc 100644 --- a/core/java/android/print/PrinterInfo.java +++ b/core/java/android/print/PrinterInfo.java @@ -86,6 +86,31 @@ public final class PrinterInfo implements Parcelable { mDefaults.put(PROPERTY_ORIENTATION, DEFAULT_UNDEFINED); } + private PrinterInfo(PrinterInfo prototype) { + mId = prototype.mId; + mLabel = prototype.mLabel; + mStatus = prototype.mStatus; + + mMinMargins = prototype.mMinMargins; + mMediaSizes.addAll(prototype.mMediaSizes); + mResolutions.addAll(prototype.mResolutions); + mInputTrays = (prototype.mInputTrays != null) + ? new ArrayList<Tray>(prototype.mInputTrays) : null; + mOutputTrays = (prototype.mOutputTrays != null) + ? new ArrayList<Tray>(prototype.mOutputTrays) : null; + + mDuplexModes = prototype.mDuplexModes; + mColorModes = prototype.mColorModes; + mFittingModes = prototype.mFittingModes; + mOrientations = prototype.mOrientations; + + final int defaultCount = prototype.mDefaults.size(); + for (int i = 0; i < defaultCount; i++) { + mDefaults.put(prototype.mDefaults.keyAt(i), prototype.mDefaults.valueAt(i)); + } + mDefaultMargins = prototype.mDefaultMargins; + } + /** * Get the globally unique printer id. * @@ -437,7 +462,7 @@ public final class PrinterInfo implements Parcelable { * </p> */ public static final class Builder { - private final PrinterInfo mPrinterInfo; + private final PrinterInfo mPrototype; /** * Creates a new instance. @@ -455,9 +480,9 @@ public final class PrinterInfo implements Parcelable { if (TextUtils.isEmpty(label)) { throw new IllegalArgumentException("label cannot be empty."); } - mPrinterInfo = new PrinterInfo(); - mPrinterInfo.mLabel = label; - mPrinterInfo.mId = printerId; + mPrototype = new PrinterInfo(); + mPrototype.mLabel = label; + mPrototype.mId = printerId; } /** @@ -470,7 +495,7 @@ public final class PrinterInfo implements Parcelable { * @return This builder. */ public Builder setStatus(int status) { - mPrinterInfo.mStatus = status; + mPrototype.mStatus = status; return this; } @@ -489,11 +514,11 @@ public final class PrinterInfo implements Parcelable { * @see PrintAttributes.MediaSize */ public Builder addMediaSize(MediaSize mediaSize, boolean isDefault) { - final int insertionIndex = mPrinterInfo.mMediaSizes.size(); - mPrinterInfo.mMediaSizes.add(mediaSize); + final int insertionIndex = mPrototype.mMediaSizes.size(); + mPrototype.mMediaSizes.add(mediaSize); if (isDefault) { throwIfDefaultAlreadySpecified(PROPERTY_MEDIA_SIZE); - mPrinterInfo.mDefaults.put(PROPERTY_MEDIA_SIZE, insertionIndex); + mPrototype.mDefaults.put(PROPERTY_MEDIA_SIZE, insertionIndex); } return this; } @@ -514,11 +539,11 @@ public final class PrinterInfo implements Parcelable { * @see PrintAttributes.Resolution */ public Builder addResolution(Resolution resolution, boolean isDefault) { - final int insertionIndex = mPrinterInfo.mResolutions.size(); - mPrinterInfo.mResolutions.add(resolution); + final int insertionIndex = mPrototype.mResolutions.size(); + mPrototype.mResolutions.add(resolution); if (isDefault) { throwIfDefaultAlreadySpecified(PROPERTY_RESOLUTION); - mPrinterInfo.mDefaults.put(PROPERTY_RESOLUTION, insertionIndex); + mPrototype.mDefaults.put(PROPERTY_RESOLUTION, insertionIndex); } return this; } @@ -543,8 +568,8 @@ public final class PrinterInfo implements Parcelable { throw new IllegalArgumentException("Default margins" + " cannot be outside of the min margins."); } - mPrinterInfo.mMinMargins = margins; - mPrinterInfo.mDefaultMargins = defaultMargins; + mPrototype.mMinMargins = margins; + mPrototype.mDefaultMargins = defaultMargins; return this; } @@ -564,14 +589,14 @@ public final class PrinterInfo implements Parcelable { * @see PrintAttributes.Tray */ public Builder addInputTray(Tray inputTray, boolean isDefault) { - if (mPrinterInfo.mInputTrays == null) { - mPrinterInfo.mInputTrays = new ArrayList<Tray>(); + if (mPrototype.mInputTrays == null) { + mPrototype.mInputTrays = new ArrayList<Tray>(); } - final int insertionIndex = mPrinterInfo.mInputTrays.size(); - mPrinterInfo.mInputTrays.add(inputTray); + final int insertionIndex = mPrototype.mInputTrays.size(); + mPrototype.mInputTrays.add(inputTray); if (isDefault) { throwIfDefaultAlreadySpecified(PROPERTY_INPUT_TRAY); - mPrinterInfo.mDefaults.put(PROPERTY_INPUT_TRAY, insertionIndex); + mPrototype.mDefaults.put(PROPERTY_INPUT_TRAY, insertionIndex); } return this; } @@ -592,14 +617,14 @@ public final class PrinterInfo implements Parcelable { * @see PrintAttributes.Tray */ public Builder addOutputTray(Tray outputTray, boolean isDefault) { - if (mPrinterInfo.mOutputTrays == null) { - mPrinterInfo.mOutputTrays = new ArrayList<Tray>(); + if (mPrototype.mOutputTrays == null) { + mPrototype.mOutputTrays = new ArrayList<Tray>(); } - final int insertionIndex = mPrinterInfo.mOutputTrays.size(); - mPrinterInfo.mOutputTrays.add(outputTray); + final int insertionIndex = mPrototype.mOutputTrays.size(); + mPrototype.mOutputTrays.add(outputTray); if (isDefault) { throwIfDefaultAlreadySpecified(PROPERTY_OUTPUT_TRAY); - mPrinterInfo.mDefaults.put(PROPERTY_OUTPUT_TRAY, insertionIndex); + mPrototype.mDefaults.put(PROPERTY_OUTPUT_TRAY, insertionIndex); } return this; } @@ -631,8 +656,8 @@ public final class PrinterInfo implements Parcelable { throw new IllegalArgumentException("Default color mode not in color modes."); } PrintAttributes.enforceValidColorMode(colorModes); - mPrinterInfo.mColorModes = colorModes; - mPrinterInfo.mDefaults.put(PROPERTY_COLOR_MODE, defaultColorMode); + mPrototype.mColorModes = colorModes; + mPrototype.mDefaults.put(PROPERTY_COLOR_MODE, defaultColorMode); return this; } @@ -664,8 +689,8 @@ public final class PrinterInfo implements Parcelable { throw new IllegalArgumentException("Default duplex mode not in duplex modes."); } PrintAttributes.enforceValidDuplexMode(defaultDuplexMode); - mPrinterInfo.mDuplexModes = duplexModes; - mPrinterInfo.mDefaults.put(PROPERTY_DUPLEX_MODE, defaultDuplexMode); + mPrototype.mDuplexModes = duplexModes; + mPrototype.mDefaults.put(PROPERTY_DUPLEX_MODE, defaultDuplexMode); return this; } @@ -696,8 +721,8 @@ public final class PrinterInfo implements Parcelable { throw new IllegalArgumentException("Default fitting mode not in fiting modes."); } PrintAttributes.enfoceValidFittingMode(defaultFittingMode); - mPrinterInfo.mFittingModes = fittingModes; - mPrinterInfo.mDefaults.put(PROPERTY_FITTING_MODE, defaultFittingMode); + mPrototype.mFittingModes = fittingModes; + mPrototype.mDefaults.put(PROPERTY_FITTING_MODE, defaultFittingMode); return this; } @@ -728,8 +753,8 @@ public final class PrinterInfo implements Parcelable { throw new IllegalArgumentException("Default orientation not in orientations."); } PrintAttributes.enforceValidOrientation(defaultOrientation); - mPrinterInfo.mOrientations = orientations; - mPrinterInfo.mDefaults.put(PROPERTY_ORIENTATION, defaultOrientation); + mPrototype.mOrientations = orientations; + mPrototype.mDefaults.put(PROPERTY_ORIENTATION, defaultOrientation); return this; } @@ -743,41 +768,41 @@ public final class PrinterInfo implements Parcelable { * @throws IllegalStateException If a required attribute was not specified. */ public PrinterInfo create() { - if (mPrinterInfo.mMediaSizes == null || mPrinterInfo.mMediaSizes.isEmpty()) { + if (mPrototype.mMediaSizes == null || mPrototype.mMediaSizes.isEmpty()) { throw new IllegalStateException("No media size specified."); } - if (mPrinterInfo.mDefaults.valueAt(PROPERTY_MEDIA_SIZE) == DEFAULT_UNDEFINED) { + if (mPrototype.mDefaults.valueAt(PROPERTY_MEDIA_SIZE) == DEFAULT_UNDEFINED) { throw new IllegalStateException("No default media size specified."); } - if (mPrinterInfo.mResolutions == null || mPrinterInfo.mResolutions.isEmpty()) { + if (mPrototype.mResolutions == null || mPrototype.mResolutions.isEmpty()) { throw new IllegalStateException("No resolution specified."); } - if (mPrinterInfo.mDefaults.valueAt(PROPERTY_RESOLUTION) == DEFAULT_UNDEFINED) { + if (mPrototype.mDefaults.valueAt(PROPERTY_RESOLUTION) == DEFAULT_UNDEFINED) { throw new IllegalStateException("No default resolution specified."); } - if (mPrinterInfo.mColorModes == 0) { + if (mPrototype.mColorModes == 0) { throw new IllegalStateException("No color mode specified."); } - if (mPrinterInfo.mDefaults.valueAt(PROPERTY_COLOR_MODE) == DEFAULT_UNDEFINED) { + if (mPrototype.mDefaults.valueAt(PROPERTY_COLOR_MODE) == DEFAULT_UNDEFINED) { throw new IllegalStateException("No default color mode specified."); } - if (mPrinterInfo.mOrientations == 0) { + if (mPrototype.mOrientations == 0) { throw new IllegalStateException("No oprientation specified."); } - if (mPrinterInfo.mDefaults.valueAt(PROPERTY_ORIENTATION) == DEFAULT_UNDEFINED) { + if (mPrototype.mDefaults.valueAt(PROPERTY_ORIENTATION) == DEFAULT_UNDEFINED) { throw new IllegalStateException("No default orientation specified."); } - if (mPrinterInfo.mMinMargins == null) { - mPrinterInfo.mMinMargins = new Margins(0, 0, 0, 0); + if (mPrototype.mMinMargins == null) { + mPrototype.mMinMargins = new Margins(0, 0, 0, 0); } - if (mPrinterInfo.mDefaultMargins == null) { - mPrinterInfo.mDefaultMargins = mPrinterInfo.mMinMargins; + if (mPrototype.mDefaultMargins == null) { + mPrototype.mDefaultMargins = mPrototype.mMinMargins; } - return mPrinterInfo; + return new PrinterInfo(mPrototype); } private void throwIfDefaultAlreadySpecified(int propertyIndex) { - if (mPrinterInfo.mDefaults.get(propertyIndex) != DEFAULT_UNDEFINED) { + if (mPrototype.mDefaults.get(propertyIndex) != DEFAULT_UNDEFINED) { throw new IllegalArgumentException("Default already specified."); } } diff --git a/core/java/android/printservice/IPrintService.aidl b/core/java/android/printservice/IPrintService.aidl index eabd96d..c72385a 100644 --- a/core/java/android/printservice/IPrintService.aidl +++ b/core/java/android/printservice/IPrintService.aidl @@ -17,6 +17,7 @@ package android.printservice; import android.os.ICancellationSignal; +import android.print.IPrinterDiscoveryObserver; import android.print.PrintJobInfo; import android.print.PrinterId; import android.printservice.IPrintServiceClient; @@ -28,8 +29,8 @@ import android.printservice.IPrintServiceClient; */ oneway interface IPrintService { void setClient(IPrintServiceClient client); - void requestCancelPrintJob(in PrintJobInfo printJob); - void onPrintJobQueued(in PrintJobInfo printJob); - void startPrinterDiscovery(); + void requestCancelPrintJob(in PrintJobInfo printJobInfo); + void onPrintJobQueued(in PrintJobInfo printJobInfo); + void startPrinterDiscovery(IPrinterDiscoveryObserver observer); void stopPrinterDiscovery(); } diff --git a/core/java/android/printservice/IPrintServiceClient.aidl b/core/java/android/printservice/IPrintServiceClient.aidl index cff8c02..cdde4d8 100644 --- a/core/java/android/printservice/IPrintServiceClient.aidl +++ b/core/java/android/printservice/IPrintServiceClient.aidl @@ -27,11 +27,9 @@ import android.print.PrinterInfo; * @hide */ interface IPrintServiceClient { - List<PrintJobInfo> getPrintJobs(); - PrintJobInfo getPrintJob(int printJobId); + List<PrintJobInfo> getPrintJobInfos(); + PrintJobInfo getPrintJobInfo(int printJobId); boolean setPrintJobState(int printJobId, int status); boolean setPrintJobTag(int printJobId, String tag); oneway void writePrintJobData(in ParcelFileDescriptor fd, int printJobId); - oneway void addDiscoveredPrinters(in List<PrinterInfo> printers); - oneway void removeDiscoveredPrinters(in List<PrinterId> printers); } diff --git a/core/java/android/printservice/PrintDocument.java b/core/java/android/printservice/PrintDocument.java new file mode 100644 index 0000000..2a1581a --- /dev/null +++ b/core/java/android/printservice/PrintDocument.java @@ -0,0 +1,91 @@ +/* + * 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.printservice; + +import android.os.ParcelFileDescriptor; +import android.os.RemoteException; +import android.print.PrintDocumentInfo; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.IOException; + +/** + * This class represents a printed document from the perspective of a print + * service. It exposes APIs to query the document and obtain its data. + */ +public final class PrintDocument { + + private static final String LOG_TAG = "PrintDocument"; + + private final int mPrintJobId; + + private final IPrintServiceClient mPrintServiceClient; + + private final PrintDocumentInfo mInfo; + + PrintDocument(int printJobId, IPrintServiceClient printServiceClient, + PrintDocumentInfo info) { + mPrintJobId = printJobId; + mPrintServiceClient = printServiceClient; + mInfo = info; + } + + /** + * Gets the {@link PrintDocumentInfo} that describes this document. + * + * @return The document info. + */ + public PrintDocumentInfo getInfo() { + return mInfo; + } + + /** + * Gets the data associated with this document. It is a responsibility of the + * client to open a stream to the returned file descriptor and fully read the + * data. + * <p> + * <strong>Note:</strong> It is your responsibility to close the file descriptor. + * </p> + * + * @return A file descriptor for reading the data or <code>null</code>. + */ + public FileDescriptor getData() { + ParcelFileDescriptor source = null; + ParcelFileDescriptor sink = null; + try { + ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe(); + source = fds[0]; + sink = fds[1]; + mPrintServiceClient.writePrintJobData(sink, mPrintJobId); + return source.getFileDescriptor(); + } catch (IOException ioe) { + Log.e(LOG_TAG, "Error calling getting print job data!", ioe); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling getting print job data!", re); + } finally { + if (sink != null) { + try { + sink.close(); + } catch (IOException ioe) { + /* ignore */ + } + } + } + return null; + } +} diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java index f490f91..80530a7 100644 --- a/core/java/android/printservice/PrintJob.java +++ b/core/java/android/printservice/PrintJob.java @@ -16,10 +16,6 @@ package android.printservice; -import java.io.FileDescriptor; -import java.io.IOException; - -import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.print.PrintJobInfo; import android.util.Log; @@ -33,19 +29,16 @@ public final class PrintJob { private static final String LOG_TAG = "PrintJob"; - private final int mId; - private final IPrintServiceClient mPrintServiceClient; + private final PrintDocument mDocument; + private PrintJobInfo mCachedInfo; - PrintJob(PrintJobInfo info, IPrintServiceClient client) { - if (client == null) { - throw new IllegalStateException("Print serivice not connected!"); - } - mCachedInfo = info; - mId = info.getId(); + PrintJob(PrintJobInfo jobInfo, IPrintServiceClient client) { + mCachedInfo = jobInfo; mPrintServiceClient = client; + mDocument = new PrintDocument(mCachedInfo.getId(), client, jobInfo.getDocumentInfo()); } /** @@ -54,7 +47,7 @@ public final class PrintJob { * @return The id. */ public int getId() { - return mId; + return mCachedInfo.getId(); } /** @@ -70,9 +63,9 @@ public final class PrintJob { public PrintJobInfo getInfo() { PrintJobInfo info = null; try { - info = mPrintServiceClient.getPrintJob(mId); + info = mPrintServiceClient.getPrintJobInfo(mCachedInfo.getId()); } catch (RemoteException re) { - Log.e(LOG_TAG, "Couldn't get info for job: " + mId, re); + Log.e(LOG_TAG, "Couldn't get info for job: " + mCachedInfo.getId(), re); } if (info != null) { mCachedInfo = info; @@ -81,6 +74,15 @@ public final class PrintJob { } /** + * Gets the document of this print job. + * + * @return The document. + */ + public PrintDocument getDocument() { + return mDocument; + } + + /** * Gets whether this print job is queued. Such a print job is * ready to be printed and can be started. * @@ -103,7 +105,7 @@ public final class PrintJob { * @see #fail(CharSequence) */ public boolean isStarted() { - return getInfo().getState() == PrintJobInfo.STATE_STARTED; + return getInfo().getState() == PrintJobInfo.STATE_STARTED; } /** @@ -181,48 +183,13 @@ public final class PrintJob { */ public boolean setTag(String tag) { try { - return mPrintServiceClient.setPrintJobTag(mId, tag); + return mPrintServiceClient.setPrintJobTag(mCachedInfo.getId(), tag); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error setting tag for job:" + mId, re); + Log.e(LOG_TAG, "Error setting tag for job: " + mCachedInfo.getId(), re); } return false; } - /** - * Gets the data associated with this print job. It is a responsibility of - * the print service to open a stream to the returned file descriptor - * and fully read the content. - * <p> - * <strong>Note:</strong> It is your responsibility to close the file descriptor. - * </p> - * - * @return A file descriptor for reading the data or <code>null</code>. - */ - public final FileDescriptor getData() { - ParcelFileDescriptor source = null; - ParcelFileDescriptor sink = null; - try { - ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe(); - source = fds[0]; - sink = fds[1]; - mPrintServiceClient.writePrintJobData(sink, mId); - return source.getFileDescriptor(); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error calling getting print job data!", ioe); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling getting print job data!", re); - } finally { - if (sink != null) { - try { - sink.close(); - } catch (IOException ioe) { - /* ignore */ - } - } - } - return null; - } - @Override public boolean equals(Object obj) { if (this == obj) { @@ -235,23 +202,25 @@ public final class PrintJob { return false; } PrintJob other = (PrintJob) obj; - return (mId == other.mId); + return (mCachedInfo.getId() == other.mCachedInfo.getId()); } @Override public int hashCode() { - return mId; + return mCachedInfo.getId(); } private boolean setState(int state) { - // Best effort - update the state of the cached info since - // we may not be able to re-fetch it later if the job gets - // removed from the spooler. - mCachedInfo.setState(state); try { - return mPrintServiceClient.setPrintJobState(mId, state); + if (mPrintServiceClient.setPrintJobState(mCachedInfo.getId(), state)) { + // Best effort - update the state of the cached info since + // we may not be able to re-fetch it later if the job gets + // removed from the spooler as a result of the state change. + mCachedInfo.setState(state); + return true; + } } catch (RemoteException re) { - Log.e(LOG_TAG, "Error setting the state of job:" + mId, re); + Log.e(LOG_TAG, "Error setting the state of job: " + mCachedInfo.getId(), re); } return false; } diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java index 9256966..820c2d8 100644 --- a/core/java/android/printservice/PrintService.java +++ b/core/java/android/printservice/PrintService.java @@ -25,6 +25,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; +import android.print.IPrinterDiscoveryObserver; import android.print.PrintJobInfo; import android.print.PrinterId; import android.print.PrinterInfo; @@ -47,7 +48,7 @@ import java.util.List; * {@link #onStartPrinterDiscovery()} and ends with a call to * {@link #onStopPrinterDiscovery()}. During a printer discovery * period the print service reports newly discovered printers by - * calling {@link #addDiscoveredPrinters(List)} and added printers + * calling {@link #addDiscoveredPrinters(List)} and reports added printers * that disappeared by calling {@link #removeDiscoveredPrinters(List)}. * Calls to {@link #addDiscoveredPrinters(List)} and * {@link #removeDiscoveredPrinters(List)} before a call to @@ -67,26 +68,30 @@ import java.util.List; * a call to {@link #onPrintJobQueued(PrintJob)} is made and the print * service may handle it immediately or schedule that for an appropriate * time in the future. The list of all print jobs for this service - * are be available by calling {@link #getPrintJobs()}. A queued print - * job is one whose {@link PrintJob#isQueued()} return true. + * are be available by calling {@link #getPrintJobs()}. * </p> * <p> * A print service is responsible for setting the print job state as * appropriate while processing it. Initially, a print job is in a * {@link PrintJobInfo#STATE_QUEUED} state which means that the data to * be printed is spooled by the system and the print service can obtain - * that data by calling {@link PrintJob#getData()}. After the print - * service starts printing the data it should set the print job state - * to {@link PrintJobInfo#STATE_STARTED}. Upon successful completion, the - * print job state has to be set to {@link PrintJobInfo#STATE_COMPLETED}. - * In a case of a failure, the print job state should be set to - * {@link PrintJobInfo#STATE_FAILED}. If a print job is in a - * {@link PrintJobInfo#STATE_STARTED} state and the user requests to - * cancel it, the print service will receive a call to - * {@link #onRequestCancelPrintJob(PrintJob)} which requests from the - * service to do a best effort in canceling the job. In case the job - * is successfully canceled, its state has to be set to - * {@link PrintJobInfo#STATE_CANCELED}. + * that data by calling {@link PrintJob#getDocument()}. A queued print + * job's {@link PrintJob#isQueued()} method returns true. + * </p> + * <p> + * After the print service starts printing the data it should set the + * print job state to {@link PrintJobInfo#STATE_STARTED} by calling + * {@link PrintJob#start()}. Upon successful completion, the print job + * state has to be set to {@link PrintJobInfo#STATE_COMPLETED} by calling + * {@link PrintJob#complete()}. In case of a failure, the print job + * state should be set to {@link PrintJobInfo#STATE_FAILED} by calling + * {@link PrintJob#fail(CharSequence)}. If a print job is in a + * {@link PrintJobInfo#STATE_STARTED} state, i.e. {@link PrintJob#isStarted()} + * return true, and the user requests to cancel it, the print service will + * receive a call to {@link #onRequestCancelPrintJob(PrintJob)} which + * requests from the service to do a best effort in canceling the job. In + * case the job is successfully canceled, its state has to be set to + * {@link PrintJobInfo#STATE_CANCELED}. by calling {@link PrintJob#cancel()}. * </p> * <h3>Lifecycle</h3> * <p> @@ -124,9 +129,9 @@ import java.util.List; * <p> * A print service can be configured by specifying an optional settings * activity which exposes service specific options, an optional add - * prints activity which is used for manual addition of printers, etc. - * It is a responsibility of the system to launch the settings and add - * printers activities when appropriate. + * prints activity which is used for manual addition of printers, vendor + * name ,etc. It is a responsibility of the system to launch the settings + * and add printers activities when appropriate. * </p> * <p> * A print service is configured by providing a @@ -148,7 +153,7 @@ import java.util.List; */ public abstract class PrintService extends Service { - private static final String LOG_TAG = PrintService.class.getSimpleName(); + private static final String LOG_TAG = "PrintService"; /** * The {@link Intent} action that must be declared as handled by a service @@ -162,6 +167,7 @@ public abstract class PrintService extends Service { * <code><{@link android.R.styleable#PrintService print-service}></code> * tag. This is a a sample XML file configuring a print service: * <pre> <print-service + * android:vendor="SomeVendor" * android:settingsActivity="foo.bar.MySettingsActivity" * andorid:addPrintersActivity="foo.bar.MyAddPrintersActivity." * . . . @@ -175,7 +181,7 @@ public abstract class PrintService extends Service { private IPrintServiceClient mClient; - private boolean mDiscoveringPrinters; + private IPrinterDiscoveryObserver mDiscoveryObserver; @Override protected void attachBaseContext(Context base) { @@ -230,29 +236,29 @@ public abstract class PrintService extends Service { * printers have to be added. You can call this method as many times as * necessary during the discovery period but should not pass in already * added printers. If a printer is already added in the same printer - * discovery period, it will be ignored. + * discovery period, it will be ignored. If you want to update an already + * added printer, you should removed it and then re-add it. * </p> * * @param printers A list with discovered printers. * - * @throws IllegalStateException If this service is not connected. - * * @see #removeDiscoveredPrinters(List) * @see #onStartPrinterDiscovery() * @see #onStopPrinterDiscovery() + * + * @throws IllegalStateException If this service is not connected. */ public final void addDiscoveredPrinters(List<PrinterInfo> printers) { + final IPrinterDiscoveryObserver observer; synchronized (mLock) { - if (mClient == null) { - throw new IllegalStateException("Print serivice not connected!"); - } - if (mDiscoveringPrinters) { - try { - // Calling with a lock into the system is fine. - mClient.addDiscoveredPrinters(printers); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error adding discovered printers!", re); - } + throwIfNotConnectedLocked(); + observer = mDiscoveryObserver; + } + if (observer != null) { + try { + observer.addDiscoveredPrinters(printers); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error adding discovered printers", re); } } } @@ -269,37 +275,38 @@ public abstract class PrintService extends Service { * this method as many times as necessary during the discovery period * but should not pass in already removed printer ids. If a printer with * a given id is already removed in the same discovery period, it will - * be ignored. + * be ignored. If you want to update an already added printer, you should + * removed it and then re-add it. * </p> * * @param printerIds A list with disappeared printer ids. * - * @throws IllegalStateException If this service is not connected. - * * @see #addDiscoveredPrinters(List) * @see #onStartPrinterDiscovery() * @see #onStopPrinterDiscovery() + * + * @throws IllegalStateException If this service is not connected. */ public final void removeDiscoveredPrinters(List<PrinterId> printerIds) { + final IPrinterDiscoveryObserver observer; synchronized (mLock) { - if (mClient == null) { - throw new IllegalStateException("Print serivice not connected!"); - } - if (mDiscoveringPrinters) { - try { - // Calling with a lock into the system is fine. - mClient.removeDiscoveredPrinters(printerIds); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error removing discovered printers!", re); - } + throwIfNotConnectedLocked(); + observer = mDiscoveryObserver; + } + if (observer != null) { + try { + observer.removeDiscoveredPrinters(printerIds); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error removing discovered printers", re); } } } /** * Called when canceling of a print job is requested. The service - * should do best effort to fulfill the request. After the print - * job is canceled by calling {@link PrintJob#cancel()}. + * should do best effort to fulfill the request. After the cancellation + * is performed, the print job should be set to a cancelled state by + * calling {@link PrintJob#cancel()}. * * @param printJob The print job to be canceled. */ @@ -310,11 +317,12 @@ public abstract class PrintService extends Service { * Called when there is a queued print job for one of the printers * managed by this print service. A queued print job is ready for * processing by a print service which can get the data to be printed - * by calling {@link PrintJob#getData()}. This service may start + * by calling {@link PrintJob#getDocument()}. This service may start * processing the passed in print job or schedule handling of queued * print jobs at a convenient time. The service can get the print * jobs by a call to {@link #getPrintJobs()} and examine their state - * to find the ones with state {@link PrintJobInfo#STATE_QUEUED}. + * to find the ones with state {@link PrintJobInfo#STATE_QUEUED} by + * calling {@link PrintJob#isQueued()}. * * @param printJob The new queued print job. * @@ -330,28 +338,31 @@ public abstract class PrintService extends Service { * @throws IllegalStateException If this service is not connected. */ public final List<PrintJob> getPrintJobs() { + final IPrintServiceClient client; synchronized (mLock) { - if (mClient == null) { - throw new IllegalStateException("Print serivice not connected!"); - } - try { - List<PrintJob> printJobs = null; - List<PrintJobInfo> printJobInfos = mClient.getPrintJobs(); - if (printJobInfos != null) { - final int printJobInfoCount = printJobInfos.size(); - printJobs = new ArrayList<PrintJob>(printJobInfoCount); - for (int i = 0; i < printJobInfoCount; i++) { - printJobs.add(new PrintJob(printJobInfos.get(i), mClient)); - } - } - if (printJobs != null) { - return printJobs; + throwIfNotConnectedLocked(); + client = mClient; + } + if (client == null) { + return Collections.emptyList(); + } + try { + List<PrintJob> printJobs = null; + List<PrintJobInfo> printJobInfos = client.getPrintJobInfos(); + if (printJobInfos != null) { + final int printJobInfoCount = printJobInfos.size(); + printJobs = new ArrayList<PrintJob>(printJobInfoCount); + for (int i = 0; i < printJobInfoCount; i++) { + printJobs.add(new PrintJob(printJobInfos.get(i), client)); } - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling getPrintJobs()", re); } - return Collections.emptyList(); + if (printJobs != null) { + return printJobs; + } + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling getPrintJobs()", re); } + return Collections.emptyList(); } /** @@ -375,8 +386,9 @@ public abstract class PrintService extends Service { } @Override - public void startPrinterDiscovery() { - mHandler.sendEmptyMessage(MyHandler.MESSAGE_START_PRINTER_DISCOVERY); + public void startPrinterDiscovery(IPrinterDiscoveryObserver observer) { + mHandler.obtainMessage(MyHandler.MESSAGE_START_PRINTER_DISCOVERY, + observer).sendToTarget(); } @Override @@ -385,18 +397,25 @@ public abstract class PrintService extends Service { } @Override - public void requestCancelPrintJob(PrintJobInfo printJob) { - mHandler.obtainMessage(MyHandler.MESSAGE_CANCEL_PRINTJOB, printJob).sendToTarget(); + public void requestCancelPrintJob(PrintJobInfo printJobInfo) { + mHandler.obtainMessage(MyHandler.MESSAGE_CANCEL_PRINTJOB, + printJobInfo).sendToTarget(); } @Override - public void onPrintJobQueued(PrintJobInfo printJob) { + public void onPrintJobQueued(PrintJobInfo printJobInfo) { mHandler.obtainMessage(MyHandler.MESSAGE_ON_PRINTJOB_QUEUED, - printJob).sendToTarget(); + printJobInfo).sendToTarget(); } }; } + private void throwIfNotConnectedLocked() { + if (mClient == null) { + throw new IllegalStateException("Print serivice not connected"); + } + } + private final class MyHandler extends Handler { public static final int MESSAGE_START_PRINTER_DISCOVERY = 1; public static final int MESSAGE_STOP_PRINTER_DISCOVERY = 2; @@ -414,26 +433,26 @@ public abstract class PrintService extends Service { switch (action) { case MESSAGE_START_PRINTER_DISCOVERY: { synchronized (mLock) { - mDiscoveringPrinters = true; + mDiscoveryObserver = (IPrinterDiscoveryObserver) message.obj; } onStartPrinterDiscovery(); } break; case MESSAGE_STOP_PRINTER_DISCOVERY: { synchronized (mLock) { - mDiscoveringPrinters = false; + mDiscoveryObserver = null; } onStopPrinterDiscovery(); } break; case MESSAGE_CANCEL_PRINTJOB: { - PrintJobInfo printJob = (PrintJobInfo) message.obj; - onRequestCancelPrintJob(new PrintJob(printJob, mClient)); + PrintJobInfo printJobInfo = (PrintJobInfo) message.obj; + onRequestCancelPrintJob(new PrintJob(printJobInfo, mClient)); } break; case MESSAGE_ON_PRINTJOB_QUEUED: { - PrintJobInfo printJob = (PrintJobInfo) message.obj; - onPrintJobQueued(new PrintJob(printJob, mClient)); + PrintJobInfo printJobInfo = (PrintJobInfo) message.obj; + onPrintJobQueued(new PrintJob(printJobInfo, mClient)); } break; case MESSAGE_SET_CLEINT: { @@ -441,13 +460,12 @@ public abstract class PrintService extends Service { synchronized (mLock) { mClient = client; if (client == null) { - mDiscoveringPrinters = false; + mDiscoveryObserver = null; } } if (client != null) { onConnected(); } else { - onStopPrinterDiscovery(); onDisconnected(); } } break; diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java index 0370a25..43dd1b6 100644 --- a/core/java/android/printservice/PrintServiceInfo.java +++ b/core/java/android/printservice/PrintServiceInfo.java @@ -48,8 +48,6 @@ import java.io.IOException; */ public final class PrintServiceInfo implements Parcelable { - private static final boolean DEBUG = false; - private static final String LOG_TAG = PrintServiceInfo.class.getSimpleName(); private static final String TAG_PRINT_SERVICE = "print-service"; @@ -97,7 +95,6 @@ public final class PrintServiceInfo implements Parcelable { * @param context Context for accessing resources. * @throws XmlPullParserException If a XML parsing error occurs. * @throws IOException If a I/O error occurs. - * @hide */ public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) { String settingsActivityName = null; @@ -117,7 +114,7 @@ public final class PrintServiceInfo implements Parcelable { String nodeName = parser.getName(); if (!TAG_PRINT_SERVICE.equals(nodeName)) { throw new XmlPullParserException( - "Meta-data does not start with" + TAG_PRINT_SERVICE + " tag"); + "Meta-data does not start with " + TAG_PRINT_SERVICE + " tag"); } Resources resources = packageManager.getResourcesForApplication( @@ -213,7 +210,7 @@ public final class PrintServiceInfo implements Parcelable { @Override public int hashCode() { - return 31 * 1 + ((mId == null) ? 0 : mId.hashCode()); + return 31 + ((mId == null) ? 0 : mId.hashCode()); } @Override @@ -244,12 +241,8 @@ public final class PrintServiceInfo implements Parcelable { builder.append("PrintServiceInfo{"); builder.append("id:").append(mId).append(", "); builder.append("resolveInfo:").append(mResolveInfo).append(", "); - if (DEBUG) { - builder.append("settingsActivityName:").append(mSettingsActivityName); - builder.append("addPrintersActivityName:").append(mAddPrintersActivityName); - } else if (mSettingsActivityName != null || mAddPrintersActivityName != null) { - builder.append("<has meta-data>"); - } + builder.append("settingsActivityName:").append(mSettingsActivityName); + builder.append("addPrintersActivityName:").append(mAddPrintersActivityName); builder.append("}"); return builder.toString(); } diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 4adee14..d2d1f1b 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -621,7 +621,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void concat(Matrix matrix) { - nConcatMatrix(mRenderer, matrix.native_instance); + if (matrix != null) nConcatMatrix(mRenderer, matrix.native_instance); } private static native void nConcatMatrix(int renderer, int matrix); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1c0e73d..f8aef88 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -52,6 +52,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; +import android.util.LongSparseLongArray; import android.util.Pools.SynchronizedPool; import android.util.Property; import android.util.SparseArray; @@ -2199,6 +2200,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG3_HAS_LAYOUT = 0x4; + /** + * Flag indicating that a call to measure() was skipped and should be done + * instead when layout() is invoked. + */ + static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8; + /* End of masks for mPrivateFlags3 */ @@ -2979,6 +2986,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ int mOldHeightMeasureSpec = Integer.MIN_VALUE; + private LongSparseLongArray mMeasureCache; + @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_") private Drawable mBackground; @@ -14401,12 +14410,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @SuppressWarnings({"unchecked"}) public void layout(int l, int t, int r, int b) { + if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) { + onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec); + mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; + } + int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; + boolean changed = isLayoutModeOptical(mParent) ? setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b); + if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) { onLayout(changed, l, t, r, b); mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED; @@ -14421,6 +14437,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } + mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; mPrivateFlags3 |= PFLAG3_HAS_LAYOUT; } @@ -15898,6 +15915,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * handle possible request-during-layout errors correctly.</p> */ public void requestLayout() { + if (mMeasureCache != null) mMeasureCache.clear(); + if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) { // Only trigger request-during-layout logic if this is the view requesting it, // not the views in its parent hierarchy @@ -15927,6 +15946,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * on the parent. */ public void forceLayout() { + if (mMeasureCache != null) mMeasureCache.clear(); + mPrivateFlags |= PFLAG_FORCE_LAYOUT; mPrivateFlags |= PFLAG_INVALIDATED; } @@ -15960,6 +15981,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, widthMeasureSpec = MeasureSpec.adjust(widthMeasureSpec, optical ? -oWidth : oWidth); heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight); } + + // Suppress sign extension for the low bytes + long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL; + if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2); + if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT || widthMeasureSpec != mOldWidthMeasureSpec || heightMeasureSpec != mOldHeightMeasureSpec) { @@ -15969,8 +15995,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, resolveRtlPropertiesIfNeeded(); - // measure ourselves, this should set the measured dimension flag back - onMeasure(widthMeasureSpec, heightMeasureSpec); + int cacheIndex = mMeasureCache.indexOfKey(key); + if (cacheIndex < 0) { + // measure ourselves, this should set the measured dimension flag back + onMeasure(widthMeasureSpec, heightMeasureSpec); + mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; + } else { + long value = mMeasureCache.valueAt(cacheIndex); + // Casting a long to int drops the high 32 bits, no mask needed + setMeasuredDimension((int) (value >> 32), (int) value); + mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT; + } // flag not set, setMeasuredDimension() was not invoked, we raise // an exception to warn the developer @@ -15985,6 +16020,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mOldWidthMeasureSpec = widthMeasureSpec; mOldHeightMeasureSpec = heightMeasureSpec; + + mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 | + (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension } /** diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java index c2aa90b..4fd60c1 100644 --- a/core/java/android/view/transition/Fade.java +++ b/core/java/android/view/transition/Fade.java @@ -32,6 +32,8 @@ import android.view.ViewGroup; */ public class Fade extends Visibility { + private static boolean DBG = Transition.DBG && false; + private static final String LOG_TAG = "Fade"; private static final String PROPNAME_SCREEN_X = "android:fade:screenX"; private static final String PROPNAME_SCREEN_Y = "android:fade:screenY"; @@ -121,7 +123,7 @@ public class Fade extends Visibility { View view; View startView = (startValues != null) ? startValues.view : null; View endView = (endValues != null) ? endValues.view : null; - if (Transition.DBG) { + if (DBG) { Log.d(LOG_TAG, "Fade.predisappear: startView, startVis, endView, endVis = " + startView + ", " + startVisibility + ", " + endView + ", " + endVisibility); } diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java index 6d5e61a..f99ddc0 100644 --- a/core/java/android/view/transition/Transition.java +++ b/core/java/android/view/transition/Transition.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.TimeInterpolator; import android.util.ArrayMap; +import android.util.Log; import android.util.LongSparseArray; import android.util.Pair; import android.util.SparseArray; @@ -84,11 +85,14 @@ public abstract class Transition implements Cloneable { int mNumInstances = 0; - /** - * The set of listeners to be sent transition lifecycle events. - */ + + // The set of listeners to be sent transition lifecycle events. ArrayList<TransitionListener> mListeners = null; + // The set of animators collected from calls to play(), to be run in runAnimations() + ArrayMap<Pair<TransitionValues, TransitionValues>, Animator> mAnimatorMap = + new ArrayMap<Pair<TransitionValues, TransitionValues>, Animator>(); + /** * Constructs a Transition object with no target objects. A transition with * no targets defaults to running on all target objects in the scene hierarchy @@ -203,6 +207,9 @@ public abstract class Transition implements Cloneable { */ protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues, TransitionValuesMaps endValues) { + if (DBG) { + Log.d(LOG_TAG, "play() for " + this); + } mPlayStartValuesList.clear(); mPlayEndValuesList.clear(); ArrayMap<View, TransitionValues> endCopy = @@ -312,20 +319,45 @@ public abstract class Transition implements Cloneable { for (int i = 0; i < startValuesList.size(); ++i) { TransitionValues start = startValuesList.get(i); TransitionValues end = endValuesList.get(i); - // TODO: what to do about targetIds and itemIds? - Animator animator = play(sceneRoot, start, end); - if (animator != null) { - mAnimatorMap.put(new Pair(start, end), animator); - // Note: we've already done the check against targetIDs in these lists - mPlayStartValuesList.add(start); - mPlayEndValuesList.add(end); + // Only bother trying to animate with values that differ between start/end + if (start != null || end != null) { + if (start == null || !start.equals(end)) { + if (DBG) { + View view = (end != null) ? end.view : start.view; + Log.d(LOG_TAG, " differing start/end values for view " + + view); + if (start == null || end == null) { + if (start == null) { + Log.d(LOG_TAG, " " + ((start == null) ? + "start null, end non-null" : "start non-null, end null")); + } + } else { + for (String key : start.values.keySet()) { + Object startValue = start.values.get(key); + Object endValue = end.values.get(key); + if (startValue != endValue && !startValue.equals(endValue)) { + Log.d(LOG_TAG, " " + key + ": start(" + startValue + + "), end(" + endValue +")"); + } + } + } + } + // TODO: what to do about targetIds and itemIds? + Animator animator = play(sceneRoot, start, end); + if (animator != null) { + mAnimatorMap.put(new Pair(start, end), animator); + // Note: we've already done the check against targetIDs in these lists + mPlayStartValuesList.add(start); + mPlayEndValuesList.add(end); + } + } else if (DBG) { + View view = (end != null) ? end.view : start.view; + Log.d(LOG_TAG, " No change for view " + view); + } } } } - ArrayMap<Pair<TransitionValues, TransitionValues>, Animator> mAnimatorMap = - new ArrayMap<Pair<TransitionValues, TransitionValues>, Animator>(); - /** * Internal utility method for checking whether a given view/id * is valid for this transition, where "valid" means that either @@ -364,14 +396,20 @@ public abstract class Transition implements Cloneable { * @hide */ protected void runAnimations() { - + if (DBG && mPlayStartValuesList.size() > 0) { + Log.d(LOG_TAG, "runAnimations (" + mPlayStartValuesList.size() + ") on " + this); + } startTransition(); // Now walk the list of TransitionValues, calling play for each pair for (int i = 0; i < mPlayStartValuesList.size(); ++i) { TransitionValues start = mPlayStartValuesList.get(i); TransitionValues end = mPlayEndValuesList.get(i); + Animator anim = mAnimatorMap.get(new Pair(start, end)); + if (DBG) { + Log.d(LOG_TAG, " anim: " + anim); + } startTransition(); - runAnimator(mAnimatorMap.get(new Pair(start, end))); + runAnimator(anim); } mPlayStartValuesList.clear(); mPlayEndValuesList.clear(); @@ -871,27 +909,35 @@ public abstract class Transition implements Cloneable { String toString(String indent) { String result = indent + getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + ": "; - result += "dur(" + mDuration + ") "; - result += "dly(" + mStartDelay + ") "; - result += "interp(" + mInterpolator + ") "; - result += "tgts("; - if (mTargetIds != null) { - for (int i = 0; i < mTargetIds.length; ++i) { - if (i > 0) { - result += ", "; + if (mDuration != -1) { + result += "dur(" + mDuration + ") "; + } + if (mStartDelay != -1) { + result += "dly(" + mStartDelay + ") "; + } + if (mInterpolator != null) { + result += "interp(" + mInterpolator + ") "; + } + if (mTargetIds != null || mTargets != null) { + result += "tgts("; + if (mTargetIds != null) { + for (int i = 0; i < mTargetIds.length; ++i) { + if (i > 0) { + result += ", "; + } + result += mTargetIds[i]; } - result += mTargetIds[i]; } - } - if (mTargets != null) { - for (int i = 0; i < mTargets.length; ++i) { - if (i > 0) { - result += ", "; + if (mTargets != null) { + for (int i = 0; i < mTargets.length; ++i) { + if (i > 0) { + result += ", "; + } + result += mTargets[i]; } - result += mTargets[i]; } + result += ")"; } - result += ")"; return result; } diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java index b200a6d..7a3d9e2 100644 --- a/core/java/android/view/transition/TransitionManager.java +++ b/core/java/android/view/transition/TransitionManager.java @@ -17,6 +17,7 @@ package android.view.transition; import android.util.ArrayMap; +import android.util.Log; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -36,6 +37,8 @@ import java.util.ArrayList; public class TransitionManager { // TODO: how to handle enter/exit? + private static String LOG_TAG = "TransitionManager"; + private static final Transition sDefaultTransition = new AutoTransition(); private Transition mDefaultTransition = new AutoTransition(); @@ -164,6 +167,7 @@ public class TransitionManager { observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this); + sPendingTransitions.remove(sceneRoot); // Add to running list, handle end to remove it sRunningTransitions.put(sceneRoot, transition); transition.addListener(new Transition.TransitionListenerAdapter() { @@ -316,8 +320,11 @@ public class TransitionManager { * value of null causes the TransitionManager to use the default transition. */ public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) { - - if (!sPendingTransitions.contains(sceneRoot)) { + if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.hasLayout()) { + if (Transition.DBG) { + Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " + + sceneRoot + ", " + transition); + } sPendingTransitions.add(sceneRoot); if (transition == null) { transition = sDefaultTransition; @@ -325,13 +332,7 @@ public class TransitionManager { final Transition finalTransition = transition.clone(); sceneChangeSetup(sceneRoot, transition); sceneRoot.setCurrentScene(null); - sceneRoot.postOnAnimation(new Runnable() { - @Override - public void run() { - sPendingTransitions.remove(sceneRoot); - sceneChangeRunTransition(sceneRoot, finalTransition); - } - }); + sceneChangeRunTransition(sceneRoot, finalTransition); } } } diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/view/transition/TransitionValues.java index f361666..6e5d3d3 100644 --- a/core/java/android/view/transition/TransitionValues.java +++ b/core/java/android/view/transition/TransitionValues.java @@ -53,6 +53,23 @@ public class TransitionValues { public final Map<String, Object> values = new ArrayMap<String, Object>(); @Override + public boolean equals(Object other) { + if (other instanceof TransitionValues) { + if (view == ((TransitionValues) other).view) { + if (values.equals(((TransitionValues) other).values)) { + return true; + } + } + } + return false; + } + + @Override + public int hashCode() { + return 31*view.hashCode() + values.hashCode(); + } + + @Override public String toString() { String returnValue = "TransitionValues@" + Integer.toHexString(hashCode()) + ":\n"; returnValue += " view = " + view + "\n"; diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index f1c3139..40747f0 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -242,7 +242,7 @@ public class CheckedTextView extends TextView implements Checkable { right = width - mBasePadding; left = right - mCheckMarkWidth; } - checkMarkDrawable.setBounds( left, top, right, bottom); + checkMarkDrawable.setBounds(mScrollX + left, top, mScrollX + right, bottom); checkMarkDrawable.draw(canvas); } } |