MyPrintService.java revision 7ae2878f5219d55e842348eb44ffb5070b9d708d
17ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov/*
27ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project
37ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov *
47ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
57ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * you may not use this file except in compliance with the License.
67ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * You may obtain a copy of the License at
77ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov *
87ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
97ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov *
107ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
117ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
127ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * See the License for the specific language governing permissions and
147ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov * limitations under the License.
157ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov */
167ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov
170fb6959ad364ee84e83c435d671228fb365f2084Svetoslavpackage foo.bar.printservice;
180fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
190fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.content.Intent;
200fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.net.Uri;
210fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.AsyncTask;
220fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.Handler;
230fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.Looper;
240fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.Message;
250fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintAttributes;
260fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintAttributes.Margins;
27c6c630d5c2b70440d433aa19bcf50c115d9cf39aSvetoslav Ganovimport android.print.PrintAttributes.MediaSize;
280fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintAttributes.Resolution;
290fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintAttributes.Tray;
300fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintJobInfo;
311274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganovimport android.print.PrinterCapabilitiesInfo;
320fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrinterId;
330fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrinterInfo;
340fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.printservice.PrintJob;
350fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.printservice.PrintService;
361274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganovimport android.printservice.PrinterDiscoverySession;
370fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.util.Log;
386fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslavimport android.util.SparseArray;
39ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
400fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.BufferedInputStream;
410fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.BufferedOutputStream;
420fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.File;
437ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganovimport java.io.FileDescriptor;
440fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.FileInputStream;
450fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.FileOutputStream;
460fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.IOException;
470fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.InputStream;
480fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.io.OutputStream;
490fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.util.ArrayList;
500fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport java.util.List;
510fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
526fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslavimport libcore.io.IoUtils;
536fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
540fb6959ad364ee84e83c435d671228fb365f2084Svetoslavpublic class MyPrintService extends PrintService {
550fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
568dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov    private static final String LOG_TAG = "MyPrintService";
570fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
586fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    private static final long STANDARD_DELAY_MILLIS = 10000;
596fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
606fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    static final String INTENT_EXTRA_ACTION_TYPE = "INTENT_EXTRA_ACTION_TYPE";
616fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    static final String INTENT_EXTRA_PRINT_JOB_ID = "INTENT_EXTRA_PRINT_JOB_ID";
626fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
636fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    static final int ACTION_TYPE_ON_PRINT_JOB_PENDING = 1;
646fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    static final int ACTION_TYPE_ON_REQUEST_CANCEL_PRINT_JOB = 2;
656fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
666fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    private static final Object sLock = new Object();
676fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
686fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    private static MyPrintService sInstance;
696fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
700fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    private Handler mHandler;
710fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
727ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov    private AsyncTask<FileDescriptor, Void, Void> mFakePrintTask;
738dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov
747ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov    private FakePrinterDiscoverySession mSession;
756fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
766fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    private final SparseArray<PrintJob> mProcessedPrintJobs = new SparseArray<PrintJob>();
776fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
786fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    public static MyPrintService peekInstance() {
796fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        synchronized (sLock) {
806fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            return sInstance;
816fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
826fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    }
831274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
84282209e42c32d712fd5685f283047d84e813297eSvetoslav Ganov    @Override
850fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    protected void onConnected() {
860fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        Log.i(LOG_TAG, "#onConnected()");
871274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        mHandler = new MyHandler(getMainLooper());
886fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        synchronized (sLock) {
896fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            sInstance = this;
906fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
910fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
920fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
930fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    @Override
940fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    protected void onDisconnected() {
950fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        Log.i(LOG_TAG, "#onDisconnected()");
961274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        if (mSession != null) {
971274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            mSession.cancellAddingFakePrinters();
981274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
996fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        synchronized (sLock) {
1006fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            sInstance = null;
1016fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
1020fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
1030fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
1040fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    @Override
1051274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov    protected PrinterDiscoverySession onCreatePrinterDiscoverySession() {
1067ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        Log.i(LOG_TAG, "#onCreatePrinterDiscoverySession()");
1077ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        return new FakePrinterDiscoverySession();
1080fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
1090fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
1100fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    @Override
1116fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    protected void onRequestCancelPrintJob(final PrintJob printJob) {
1126fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        Log.i(LOG_TAG, "#onRequestCancelPrintJob()");
1136fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        mProcessedPrintJobs.put(printJob.getId(), printJob);
1146fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        Intent intent = new Intent(this, MyDialogActivity.class);
1156fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1166fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        intent.putExtra(INTENT_EXTRA_PRINT_JOB_ID, printJob.getId());
1176fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        intent.putExtra(INTENT_EXTRA_ACTION_TYPE, ACTION_TYPE_ON_REQUEST_CANCEL_PRINT_JOB);
1186fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        startActivity(intent);
1198dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov    }
1208dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov
1218dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov    @Override
1220fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    public void onPrintJobQueued(final PrintJob printJob) {
123c6c630d5c2b70440d433aa19bcf50c115d9cf39aSvetoslav Ganov        Log.i(LOG_TAG, "#onPrintJobQueued()");
1246fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        mProcessedPrintJobs.put(printJob.getId(), printJob);
1256fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        Intent intent = new Intent(this, MyDialogActivity.class);
1266fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1276fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        intent.putExtra(INTENT_EXTRA_PRINT_JOB_ID, printJob.getId());
1286fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        intent.putExtra(INTENT_EXTRA_ACTION_TYPE, ACTION_TYPE_ON_PRINT_JOB_PENDING);
1296fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        startActivity(intent);
1308dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov    }
1318dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov
1326fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    void handleRequestCancelPrintJob(int printJobId) {
1336fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        PrintJob printJob = mProcessedPrintJobs.get(printJobId);
1346fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        if (printJob == null) {
1356fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            return;
1366fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
1376fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        mProcessedPrintJobs.remove(printJobId);
1386fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        if (printJob.isQueued() || printJob.isStarted()) {
1396fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            mHandler.removeMessages(MyHandler.MSG_HANDLE_DO_PRINT_JOB);
1406fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            mHandler.removeMessages(MyHandler.MSG_HANDLE_FAIL_PRINT_JOB);
1416fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            printJob.cancel();
1426fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
1436fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    }
1446fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
1456fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    void handleFailPrintJobDelayed(int printJobId) {
1466fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        Message message = mHandler.obtainMessage(
1476fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                MyHandler.MSG_HANDLE_FAIL_PRINT_JOB, printJobId, 0);
1486fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        mHandler.sendMessageDelayed(message, STANDARD_DELAY_MILLIS);
1496fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    }
1506fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
1516fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    void handleFailPrintJob(int printJobId) {
1526fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        PrintJob printJob = mProcessedPrintJobs.get(printJobId);
1536fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        if (printJob == null) {
1546fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            return;
1556fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
1566fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        mProcessedPrintJobs.remove(printJobId);
1576fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        if (printJob.isQueued() || printJob.isStarted()) {
1586fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            printJob.fail(getString(R.string.fail_reason));
1596fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
1606fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    }
1616fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
1626fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    void handleQueuedPrintJobDelayed(int printJobId) {
1636fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        Message message = mHandler.obtainMessage(
1646fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                MyHandler.MSG_HANDLE_DO_PRINT_JOB, printJobId, 0);
1656fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        mHandler.sendMessageDelayed(message, STANDARD_DELAY_MILLIS);
1666fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    }
1676fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
1686fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav    void handleQueuedPrintJob(int printJobId) {
1696fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        final PrintJob printJob = mProcessedPrintJobs.get(printJobId);
1706fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        if (printJob == null) {
1716fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav            return;
1726fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        }
1736fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
1748dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov        if (printJob.isQueued()) {
1758dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov            printJob.start();
1760fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        }
1778dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov
1788dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov        final PrintJobInfo info = printJob.getInfo();
1798dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov        final File file = new File(getFilesDir(), info.getLabel() + ".pdf");
1808dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov
1817ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        mFakePrintTask = new AsyncTask<FileDescriptor, Void, Void>() {
1820fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            @Override
1837ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            protected Void doInBackground(FileDescriptor... params) {
1847ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                InputStream in = new BufferedInputStream(new FileInputStream(params[0]));
1850fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                OutputStream out = null;
1860fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                try {
1870fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                    out = new BufferedOutputStream(new FileOutputStream(file));
1880fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                    final byte[] buffer = new byte[8192];
1890fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                    while (true) {
1908dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                        if (isCancelled()) {
1918dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                            break;
1928dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                        }
1930fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        final int readByteCount = in.read(buffer);
1940fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        if (readByteCount < 0) {
1950fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                            break;
1960fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        }
1970fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        out.write(buffer, 0, readByteCount);
1980fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                    }
1990fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                } catch (IOException ioe) {
2007ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    throw new RuntimeException(ioe);
2010fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                } finally {
202ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                    IoUtils.closeQuietly(in);
203ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                    IoUtils.closeQuietly(out);
2048dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                    if (isCancelled()) {
2058dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                        file.delete();
2068dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                    }
2070fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                }
2080fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                return null;
2090fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            }
2100fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2110fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            @Override
2120fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            protected void onPostExecute(Void result) {
2138dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                if (printJob.isStarted()) {
2148dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                    printJob.complete();
2150fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                }
2160fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2178dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                file.setReadable(true, false);
218ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
2196fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                // Quick and dirty to show the file - use a content provider instead.
2208dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                Intent intent = new Intent(Intent.ACTION_VIEW);
2218dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                intent.setDataAndType(Uri.fromFile(file), "application/pdf");
2228dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2238dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                startActivity(intent, null);
2240fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2258dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                mFakePrintTask = null;
2260fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            }
2277ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov
2287ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            @Override
2297ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            protected void onCancelled(Void result) {
2307ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                if (printJob.isStarted()) {
2317ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    printJob.cancel();
2327ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                }
2337ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            }
2340fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        };
2357ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        mFakePrintTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
2367ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                printJob.getDocument().getData());
2370fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
2380fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2390fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    private final class MyHandler extends Handler {
2406fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        public static final int MSG_HANDLE_DO_PRINT_JOB = 1;
2416fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav        public static final int MSG_HANDLE_FAIL_PRINT_JOB = 2;
2420fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2430fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        public MyHandler(Looper looper) {
2440fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            super(looper, null, true);
2450fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        }
2460fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2470fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        @Override
2480fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        public void handleMessage(Message message) {
2490fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            switch (message.what) {
2506fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                case MSG_HANDLE_DO_PRINT_JOB: {
2516fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                    final int printJobId = message.arg1;
2526fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                    handleQueuedPrintJob(printJobId);
2536fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                } break;
2546fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav
2556fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                case MSG_HANDLE_FAIL_PRINT_JOB: {
2566fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                    final int printJobId = message.arg1;
2576fc52023a04fe45b6f59212fc716cbbcf76f35fcSvetoslav                    handleFailPrintJob(printJobId);
2588dea95de32a43b110a10a445a6dfd8fba4232073Svetoslav Ganov                } break;
2590fb6959ad364ee84e83c435d671228fb365f2084Svetoslav            }
2600fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        }
2610fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
2621274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
2637ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov    private final class FakePrinterDiscoverySession extends  PrinterDiscoverySession {
2641274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        private final Handler mSesionHandler = new SessionHandler(getMainLooper());
2651274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
2667ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        private final List<PrinterInfo> mFakePrinters = new ArrayList<PrinterInfo>();
2677ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov
2687ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        public FakePrinterDiscoverySession() {
2697ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            for (int i = 0; i < 1000; i++) {
2707ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                String printerName = "Printer " + i;
2717ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                PrinterInfo printer = new PrinterInfo.Builder(generatePrinterId(printerName),
2727ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                        printerName, PrinterInfo.STATUS_READY).create();
2737ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                mFakePrinters.add(printer);
2747ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            }
2757ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        }
2767ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov
2777ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        @Override
2787ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        public void onDestroy() {
2797ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            Log.i(LOG_TAG, "FakePrinterDiscoverySession#onDestroy()");
2807ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            mSesionHandler.removeMessages(SessionHandler.MSG_ADD_FIRST_BATCH_FAKE_PRINTERS);
2817ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            mSesionHandler.removeMessages(SessionHandler.MSG_ADD_SECOND_BATCH_FAKE_PRINTERS);
2821274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
2831274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
2841274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        @Override
2857ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
2867ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            Log.i(LOG_TAG, "FakePrinterDiscoverySession#onStartPrinterDiscovery()");
2871274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            Message message1 = mSesionHandler.obtainMessage(
2887ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    SessionHandler.MSG_ADD_FIRST_BATCH_FAKE_PRINTERS, this);
2891274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            mSesionHandler.sendMessageDelayed(message1, 0);
2901274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
2911274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            Message message2 = mSesionHandler.obtainMessage(
2927ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    SessionHandler.MSG_ADD_SECOND_BATCH_FAKE_PRINTERS, this);
2931274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            mSesionHandler.sendMessageDelayed(message2, 10000);
2941274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
2951274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
2961274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        @Override
2977ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        public void onStopPrinterDiscovery() {
2987ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            Log.i(LOG_TAG, "FakePrinterDiscoverySession#onStopPrinterDiscovery()");
2991274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            cancellAddingFakePrinters();
3001274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
3011274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3021274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        @Override
3031274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        public void onRequestPrinterUpdate(PrinterId printerId) {
3047ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            Log.i(LOG_TAG, "FakePrinterDiscoverySession#onRequestPrinterUpdate()");
3057ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            PrinterInfo printer = findPrinterInfo(printerId);
3067ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            if (printer != null) {
3071274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                PrinterCapabilitiesInfo capabilities =
3081274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                        new PrinterCapabilitiesInfo.Builder(printerId)
3091274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .setMinMargins(new Margins(0, 0, 0, 0), new Margins(0, 0, 0, 0))
3101274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
3111274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            MediaSize.ISO_A4), true)
3121274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
3131274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            MediaSize.ISO_A5), false)
3141274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addResolution(new Resolution("R1", getString(
3151274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            R.string.resolution_200x200), 200, 200), true)
3161274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addResolution(new Resolution("R2", getString(
3171274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            R.string.resolution_300x300), 300, 300), false)
3181274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addInputTray(new Tray("FirstInputTray", getString(
3191274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            R.string.input_tray_first)), false)
3201274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addInputTray(new Tray("SecondInputTray", getString(
3211274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            R.string.input_tray_second)), true)
3221274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addOutputTray(new Tray("FirstOutputTray", getString(
3231274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            R.string.output_tray_first)), false)
3241274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .addOutputTray(new Tray("SecondOutputTray",  getString(
3251274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            R.string.output_tray_second)), true)
3261274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .setDuplexModes(PrintAttributes.DUPLEX_MODE_NONE
3271274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            | PrintAttributes.DUPLEX_MODE_LONG_EDGE
3281274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            | PrintAttributes.DUPLEX_MODE_SHORT_EDGE,
3291274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            PrintAttributes.DUPLEX_MODE_SHORT_EDGE)
3301274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .setColorModes(PrintAttributes.COLOR_MODE_COLOR
3311274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            | PrintAttributes.COLOR_MODE_MONOCHROME,
3321274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            PrintAttributes.COLOR_MODE_MONOCHROME)
3331274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .setFittingModes(PrintAttributes.FITTING_MODE_FIT_TO_PAGE
3341274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            | PrintAttributes.FITTING_MODE_NONE,
3351274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            PrintAttributes.FITTING_MODE_FIT_TO_PAGE)
3361274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .setOrientations(PrintAttributes.ORIENTATION_PORTRAIT
3371274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            | PrintAttributes.ORIENTATION_LANDSCAPE,
3381274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                            PrintAttributes.ORIENTATION_LANDSCAPE)
3391274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .create();
3401274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3417ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                printer = new PrinterInfo.Builder(printer)
3421274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .setCapabilities(capabilities)
3431274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    .create();
3441274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3451274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
3461274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                printers.add(printer);
3471274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                updatePrinters(printers);
3481274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            }
3491274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
3501274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3517ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        private void addFirstBatchFakePrinters() {
3527ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            List<PrinterInfo> printers = mFakePrinters.subList(0, mFakePrinters.size() / 2);
3537ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            addPrinters(printers);
3547ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        }
3557ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov
3567ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        private void addSecondBatchFakePrinters() {
3577ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            List<PrinterInfo> printers = mFakePrinters.subList(mFakePrinters.size() / 2,
3587ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    mFakePrinters.size());
3597ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            addPrinters(printers);
3601274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
3611274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3627ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov        private PrinterInfo findPrinterInfo(PrinterId printerId) {
3637ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            List<PrinterInfo> printers = getPrinters();
3647ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            final int printerCount = getPrinters().size();
3657ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            for (int i = 0; i < printerCount; i++) {
3667ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                PrinterInfo printer = printers.get(i);
3677ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                if (printer.getId().equals(printerId)) {
3687ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    return printer;
3697ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                }
3707ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            }
3717ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            return null;
3721274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
3731274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3741274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        private void cancellAddingFakePrinters() {
3757ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            mSesionHandler.removeMessages(SessionHandler.MSG_ADD_FIRST_BATCH_FAKE_PRINTERS);
3767ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            mSesionHandler.removeMessages(SessionHandler.MSG_ADD_SECOND_BATCH_FAKE_PRINTERS);
3771274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
3781274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3791274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        final class SessionHandler extends Handler {
3807ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            public static final int MSG_ADD_FIRST_BATCH_FAKE_PRINTERS = 1;
3817ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov            public static final int MSG_ADD_SECOND_BATCH_FAKE_PRINTERS = 2;
3821274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3831274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            public SessionHandler(Looper looper) {
3841274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                super(looper, null, true);
3851274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            }
3861274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3871274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            @Override
3881274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            public void handleMessage(Message message) {
3891274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                switch (message.what) {
3907ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    case MSG_ADD_FIRST_BATCH_FAKE_PRINTERS: {
3917ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                        addFirstBatchFakePrinters();
3921274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    } break;
3931274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov
3947ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                    case MSG_ADD_SECOND_BATCH_FAKE_PRINTERS: {
3957ae2878f5219d55e842348eb44ffb5070b9d708dSvetoslav Ganov                        addSecondBatchFakePrinters();
3961274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                    } break;
3971274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov                }
3981274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov            }
3991274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov        }
4001274de1ce4243d6ebb3e12b12b75daf8b466c39cSvetoslav Ganov    }
4010fb6959ad364ee84e83c435d671228fb365f2084Svetoslav}
402