1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v4.print;
18
19import android.content.Context;
20import android.graphics.Bitmap;
21import android.os.Build;
22import android.net.Uri;
23
24import java.io.FileNotFoundException;
25
26/**
27 * Helper for printing bitmaps.
28 */
29public final class PrintHelper {
30    /**
31     * image will be scaled but leave white space
32     */
33    public static final int SCALE_MODE_FIT = 1;
34
35    /**
36     * image will fill the paper and be cropped (default)
37     */
38    public static final int SCALE_MODE_FILL = 2;
39
40    /**
41     * this is a black and white image
42     */
43    public static final int COLOR_MODE_MONOCHROME = 1;
44
45    /**
46     * this is a color image (default)
47     */
48    public static final int COLOR_MODE_COLOR = 2;
49
50    /**
51     * Print the image in landscape orientation (default).
52     */
53    public static final int ORIENTATION_LANDSCAPE = 1;
54
55    /**
56     * Print the image in  portrait orientation.
57     */
58    public static final int ORIENTATION_PORTRAIT = 2;
59
60    /**
61     * Callback for observing when a print operation is completed.
62     * When print is finished either the system acquired the
63     * document to print or printing was cancelled.
64     */
65    public interface OnPrintFinishCallback {
66
67        /**
68         * Called when a print operation is finished.
69         */
70        public void onFinish();
71    }
72
73    PrintHelperVersionImpl mImpl;
74
75    /**
76     * Gets whether the system supports printing.
77     *
78     * @return True if printing is supported.
79     */
80    public static boolean systemSupportsPrint() {
81        if (Build.VERSION.SDK_INT >= 19) {
82            // Supported on Android 4.4 or later.
83            return true;
84        }
85        return false;
86    }
87
88    /**
89     * Interface implemented by classes that support printing
90     */
91    static interface PrintHelperVersionImpl {
92
93        public void setScaleMode(int scaleMode);
94
95        public int getScaleMode();
96
97        public void setColorMode(int colorMode);
98
99        public int getColorMode();
100
101        public void setOrientation(int orientation);
102
103        public int getOrientation();
104
105        public void printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback);
106
107        public void printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)
108                throws FileNotFoundException;
109    }
110
111    /**
112     * Implementation used when we do not support printing
113     */
114    private static final class PrintHelperStubImpl implements PrintHelperVersionImpl {
115        int mScaleMode = SCALE_MODE_FILL;
116        int mColorMode = COLOR_MODE_COLOR;
117        int mOrientation = ORIENTATION_LANDSCAPE;
118        @Override
119        public void setScaleMode(int scaleMode) {
120            mScaleMode = scaleMode;
121        }
122
123        @Override
124        public int getColorMode() {
125            return mColorMode;
126        }
127
128        @Override
129        public void setColorMode(int colorMode) {
130            mColorMode = colorMode;
131        }
132
133        @Override
134        public void setOrientation(int orientation) { mOrientation = orientation; }
135
136        @Override
137        public int getOrientation() { return mOrientation; }
138
139        @Override
140        public int getScaleMode() {
141            return mScaleMode;
142        }
143
144        @Override
145        public void printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback) {
146        }
147
148        @Override
149        public void printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback) {
150        }
151    }
152
153    /**
154     * Implementation used on KitKat (and above)
155     */
156    private static final class PrintHelperKitkatImpl implements PrintHelperVersionImpl {
157        private final PrintHelperKitkat mPrintHelper;
158
159        PrintHelperKitkatImpl(Context context) {
160            mPrintHelper = new PrintHelperKitkat(context);
161        }
162
163        @Override
164        public void setScaleMode(int scaleMode) {
165            mPrintHelper.setScaleMode(scaleMode);
166        }
167
168        @Override
169        public int getScaleMode() {
170            return mPrintHelper.getScaleMode();
171        }
172
173        @Override
174        public void setColorMode(int colorMode) {
175            mPrintHelper.setColorMode(colorMode);
176        }
177
178        @Override
179        public int getColorMode() {
180            return mPrintHelper.getColorMode();
181        }
182
183        @Override
184        public void setOrientation(int orientation) {
185            mPrintHelper.setOrientation(orientation);
186        }
187
188        @Override
189        public int getOrientation() {
190            return mPrintHelper.getOrientation();
191        }
192
193        @Override
194        public void printBitmap(String jobName, Bitmap bitmap,
195                final OnPrintFinishCallback callback) {
196            PrintHelperKitkat.OnPrintFinishCallback delegateCallback = null;
197            if (callback != null) {
198                delegateCallback = new PrintHelperKitkat.OnPrintFinishCallback() {
199                    @Override
200                    public void onFinish() {
201                        callback.onFinish();
202                    }
203                };
204            }
205            mPrintHelper.printBitmap(jobName, bitmap, delegateCallback);
206        }
207
208        @Override
209        public void printBitmap(String jobName, Uri imageFile,
210                final OnPrintFinishCallback callback) throws FileNotFoundException {
211            PrintHelperKitkat.OnPrintFinishCallback delegateCallback = null;
212            if (callback != null) {
213                delegateCallback = new PrintHelperKitkat.OnPrintFinishCallback() {
214                    @Override
215                    public void onFinish() {
216                        callback.onFinish();
217                    }
218                };
219            }
220            mPrintHelper.printBitmap(jobName, imageFile, delegateCallback);
221        }
222    }
223
224    /**
225     * Returns the PrintHelper that can be used to print images.
226     *
227     * @param context A context for accessing system resources.
228     * @return the <code>PrintHelper</code> to support printing images.
229     */
230    public PrintHelper(Context context) {
231        if (systemSupportsPrint()) {
232            mImpl = new PrintHelperKitkatImpl(context);
233        } else {
234            mImpl = new PrintHelperStubImpl();
235        }
236    }
237
238    /**
239     * Selects whether the image will fill the paper and be cropped
240     * {@link #SCALE_MODE_FIT}
241     * or whether the image will be scaled but leave white space
242     * {@link #SCALE_MODE_FILL}.
243     *
244     * @param scaleMode {@link #SCALE_MODE_FIT} or
245     *                  {@link #SCALE_MODE_FILL}
246     */
247    public void setScaleMode(int scaleMode) {
248        mImpl.setScaleMode(scaleMode);
249    }
250
251    /**
252     * Returns the scale mode with which the image will fill the paper.
253     *
254     * @return The scale Mode: {@link #SCALE_MODE_FIT} or
255     * {@link #SCALE_MODE_FILL}
256     */
257    public int getScaleMode() {
258        return mImpl.getScaleMode();
259    }
260
261    /**
262     * Sets whether the image will be printed in color (default)
263     * {@link #COLOR_MODE_COLOR} or in back and white
264     * {@link #COLOR_MODE_MONOCHROME}.
265     *
266     * @param colorMode The color mode which is one of
267     * {@link #COLOR_MODE_COLOR} and {@link #COLOR_MODE_MONOCHROME}.
268     */
269    public void setColorMode(int colorMode) {
270        mImpl.setColorMode(colorMode);
271    }
272
273    /**
274     * Gets the color mode with which the image will be printed.
275     *
276     * @return The color mode which is one of {@link #COLOR_MODE_COLOR}
277     * and {@link #COLOR_MODE_MONOCHROME}.
278     */
279    public int getColorMode() {
280        return mImpl.getColorMode();
281    }
282
283    /**
284     * Sets whether the image will be printed in landscape {@link #ORIENTATION_LANDSCAPE} (default)
285     * or portrait {@link #ORIENTATION_PORTRAIT}.
286     *
287     * @param orientation The page orientation which is one of
288     *                    {@link #ORIENTATION_LANDSCAPE} or {@link #ORIENTATION_PORTRAIT}.
289     */
290    public void setOrientation(int orientation) {
291        mImpl.setOrientation(orientation);
292    }
293
294    /**
295     * Gets whether the image will be printed in landscape or portrait.
296     *
297     * @return The page orientation which is one of
298     * {@link #ORIENTATION_LANDSCAPE} or {@link #ORIENTATION_PORTRAIT}.
299     */
300    public int getOrientation() {
301        return mImpl.getOrientation();
302    }
303
304
305    /**
306     * Prints a bitmap.
307     *
308     * @param jobName The print job name.
309     * @param bitmap  The bitmap to print.
310     */
311    public void printBitmap(String jobName, Bitmap bitmap) {
312        mImpl.printBitmap(jobName, bitmap, null);
313    }
314
315    /**
316     * Prints a bitmap.
317     *
318     * @param jobName The print job name.
319     * @param bitmap  The bitmap to print.
320     * @param callback Optional callback to observe when printing is finished.
321     */
322    public void printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback) {
323        mImpl.printBitmap(jobName, bitmap, callback);
324    }
325
326    /**
327     * Prints an image located at the Uri. Image types supported are those of
328     * {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
329     * android.graphics.BitmapFactory.decodeStream(java.io.InputStream)}
330     *
331     * @param jobName   The print job name.
332     * @param imageFile The <code>Uri</code> pointing to an image to print.
333     * @throws FileNotFoundException if <code>Uri</code> is not pointing to a valid image.
334     */
335    public void printBitmap(String jobName, Uri imageFile) throws FileNotFoundException {
336        mImpl.printBitmap(jobName, imageFile, null);
337    }
338
339    /**
340     * Prints an image located at the Uri. Image types supported are those of
341     * {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
342     * android.graphics.BitmapFactory.decodeStream(java.io.InputStream)}
343     *
344     * @param jobName   The print job name.
345     * @param imageFile The <code>Uri</code> pointing to an image to print.
346     * @throws FileNotFoundException if <code>Uri</code> is not pointing to a valid image.
347     * @param callback Optional callback to observe when printing is finished.
348     */
349    public void printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)
350            throws FileNotFoundException {
351        mImpl.printBitmap(jobName, imageFile, callback);
352    }
353}