10fb6959ad364ee84e83c435d671228fb365f2084Svetoslav/*
20fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * Copyright (C) 2013 The Android Open Source Project
30fb6959ad364ee84e83c435d671228fb365f2084Svetoslav *
40fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * Licensed under the Apache License, Version 2.0 (the "License");
50fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * you may not use this file except in compliance with the License.
60fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * You may obtain a copy of the License at
70fb6959ad364ee84e83c435d671228fb365f2084Svetoslav *
80fb6959ad364ee84e83c435d671228fb365f2084Svetoslav *      http://www.apache.org/licenses/LICENSE-2.0
90fb6959ad364ee84e83c435d671228fb365f2084Svetoslav *
100fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * Unless required by applicable law or agreed to in writing, software
110fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * distributed under the License is distributed on an "AS IS" BASIS,
120fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * See the License for the specific language governing permissions and
140fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * limitations under the License.
150fb6959ad364ee84e83c435d671228fb365f2084Svetoslav */
160fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
170fb6959ad364ee84e83c435d671228fb365f2084Svetoslavpackage foo.bar.print;
180fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
19cc797117a2b06f23b52027845c0a6f6700d76368Svetoslavimport java.io.FileOutputStream;
20cc797117a2b06f23b52027845c0a6f6700d76368Svetoslavimport java.io.IOException;
21cc797117a2b06f23b52027845c0a6f6700d76368Svetoslavimport java.util.ArrayList;
22cc797117a2b06f23b52027845c0a6f6700d76368Svetoslavimport java.util.List;
23cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav
240fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.app.Activity;
250fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.content.Context;
26e0f2c75acb900962dca7ac7c6a325ee845e22ccaSvetoslavimport android.graphics.pdf.PdfDocument.Page;
270fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.AsyncTask;
280fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.Bundle;
290fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.CancellationSignal;
300fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.os.CancellationSignal.OnCancelListener;
313bb4d60425207dad4241d0565ff0c4a20dca119dSvetoslav Ganovimport android.os.ParcelFileDescriptor;
320fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PageRange;
330fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintAttributes;
34fe27b10597f34fa002c1311da1e1720c33e23355Svetoslavimport android.print.PrintDocumentAdapter;
35fe27b10597f34fa002c1311da1e1720c33e23355Svetoslavimport android.print.PrintDocumentInfo;
360fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.print.PrintManager;
37a3eee78c0e6d279a2c1d91742960549864d17d03Svetoslav Ganovimport android.print.pdf.PrintedPdfDocument;
38ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganovimport android.util.SparseIntArray;
390fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.view.Menu;
400fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.view.MenuItem;
410fb6959ad364ee84e83c435d671228fb365f2084Svetoslavimport android.view.View;
420fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
430fb6959ad364ee84e83c435d671228fb365f2084Svetoslav/**
440fb6959ad364ee84e83c435d671228fb365f2084Svetoslav * Simple sample of how to use the print APIs.
450fb6959ad364ee84e83c435d671228fb365f2084Svetoslav */
460fb6959ad364ee84e83c435d671228fb365f2084Svetoslavpublic class PrintActivity extends Activity {
470fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
480fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    public static final String LOG_TAG = "PrintActivity";
490fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
50482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov    private static final int PAGE_COUNT = 5;
51ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
520fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    @Override
530fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    protected void onCreate(Bundle savedInstanceState) {
540fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        super.onCreate(savedInstanceState);
550fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        setContentView(R.layout.activity_main);
560fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
570fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
580fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    @Override
590fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    public boolean onCreateOptionsMenu(Menu menu) {
600fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        super.onCreateOptionsMenu(menu);
610fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        getMenuInflater().inflate(R.menu.activity_main, menu);
620fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        return true;
630fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
640fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
650fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    @Override
660fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    public boolean onOptionsItemSelected(MenuItem item) {
67482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov        if (item.getItemId() == R.id.menu_print) {
68482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov            printView();
69482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov            return true;
700fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        }
71482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov        return super.onOptionsItemSelected(item);
720fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
730fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
740fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    private void printView() {
750fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
760fb6959ad364ee84e83c435d671228fb365f2084Svetoslav        final View view = findViewById(R.id.content);
770fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
78cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav        printManager.print("Print_View",
79fe27b10597f34fa002c1311da1e1720c33e23355Svetoslav            new PrintDocumentAdapter() {
80482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                private static final int RESULT_LAYOUT_FAILED = 1;
81482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                private static final int RESULT_LAYOUT_FINISHED = 2;
82482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
83482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                private PrintAttributes mPrintAttributes;
840fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
850fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                @Override
86482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                public void onLayout(final PrintAttributes oldAttributes,
87482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        final PrintAttributes newAttributes,
88482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        final CancellationSignal cancellationSignal,
89482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        final LayoutResultCallback callback,
90482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        final Bundle metadata) {
91482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
92482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                    new AsyncTask<Void, Void, Integer>() {
93482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        @Override
94482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected void onPreExecute() {
95cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // First register for cancellation requests.
96482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            cancellationSignal.setOnCancelListener(new OnCancelListener() {
97482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                @Override
98482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                public void onCancel() {
99482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    cancel(true);
100482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                }
101482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            });
102482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            mPrintAttributes = newAttributes;
103482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
104ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
105482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        @Override
106482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected Integer doInBackground(Void... params) {
107482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            try {
108cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                // Pretend we do some layout work.
109482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                for (int i = 0; i < PAGE_COUNT; i++) {
110cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    // Be nice and respond to cancellation.
111482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    if (isCancelled()) {
112482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                        return null;
113482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    }
114482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    pretendDoingLayoutWork();
115482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                }
116482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                return RESULT_LAYOUT_FINISHED;
117482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            } catch (Exception e) {
118482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                return RESULT_LAYOUT_FAILED;
119482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            }
120482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
121ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
122ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                        @Override
123482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected void onPostExecute(Integer result) {
124cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // The task was not cancelled, so handle the layout result.
125482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            switch (result) {
126482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                case RESULT_LAYOUT_FINISHED: {
127482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    PrintDocumentInfo info = new PrintDocumentInfo
128482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                            .Builder("print_view.pdf")
129482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                            .setContentType(PrintDocumentInfo
130482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                                    .CONTENT_TYPE_DOCUMENT)
131482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                            .setPageCount(PAGE_COUNT)
132482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                            .build();
133482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    callback.onLayoutFinished(info, false);
134482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                } break;
135cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav
136cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                case RESULT_LAYOUT_FAILED: {
137cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    callback.onLayoutFailed(null);
138cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                } break;
139ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                            }
140482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
141482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
142482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        @Override
143482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected void onCancelled(Integer result) {
144cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // Task was cancelled, report that.
145482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            callback.onLayoutCancelled();
146482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
147482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
148482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        private void pretendDoingLayoutWork() throws Exception {
149cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav
150482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
151482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
1520fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                }
1530fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
1540fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                @Override
1553bb4d60425207dad4241d0565ff0c4a20dca119dSvetoslav Ganov                public void onWrite(final PageRange[] pages,
1563bb4d60425207dad4241d0565ff0c4a20dca119dSvetoslav Ganov                        final ParcelFileDescriptor destination,
1570fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        final CancellationSignal canclleationSignal,
158fe27b10597f34fa002c1311da1e1720c33e23355Svetoslav                        final WriteResultCallback callback) {
159482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
160482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                    new AsyncTask<Void, Void, Integer>() {
161482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        private static final int RESULT_WRITE_FAILED = 1;
162482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        private static final int RESULT_WRITE_FINISHED = 2;
163482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
164cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        private final SparseIntArray mWrittenPages = new SparseIntArray();
165cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        private final PrintedPdfDocument mPdfDocument = new PrintedPdfDocument(
166cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                PrintActivity.this, mPrintAttributes);
167cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav
168cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        @Override
169ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                        protected void onPreExecute() {
170cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // First register for cancellation requests.
171482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            canclleationSignal.setOnCancelListener(new OnCancelListener() {
172482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                @Override
173482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                public void onCancel() {
174482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    cancel(true);
175482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                }
176482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            });
177482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
178482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            for (int i = 0; i < PAGE_COUNT; i++) {
179cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                // Be nice and respond to cancellation.
180482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                if (isCancelled()) {
181482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    return;
182482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                }
183482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
184cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                // Write the page only if it was requested.
185482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                if (containsPage(pages, i)) {
186cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    mWrittenPages.append(mWrittenPages.size(), i);
187cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    Page page = mPdfDocument.startPage(i);
188cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    // The page of the PDF backed canvas size is in pixels (1/72") and
189cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    // smaller that the view. We scale down the drawn content and to
190cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    // fit. This does not lead to losing data as PDF is a vector format.
191cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    final float scale = (float) Math.min(mPdfDocument.getPageWidth(),
192cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                            mPdfDocument.getPageHeight()) / Math.max(view.getWidth(), view.getHeight());
193cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    page.getCanvas().scale(scale, scale);
194482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                    view.draw(page.getCanvas());
195cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    mPdfDocument.finishPage(page);
196ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                                }
1970fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                            }
1980fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        }
1990fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
2000fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        @Override
201482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected Integer doInBackground(Void... params) {
202cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // Write the data and return success or failure.
203e0f2c75acb900962dca7ac7c6a325ee845e22ccaSvetoslav                            try {
204cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                mPdfDocument.writeTo(new FileOutputStream(
205e0f2c75acb900962dca7ac7c6a325ee845e22ccaSvetoslav                                        destination.getFileDescriptor()));
206482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                return RESULT_WRITE_FINISHED;
207e0f2c75acb900962dca7ac7c6a325ee845e22ccaSvetoslav                            } catch (IOException ioe) {
208482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                return RESULT_WRITE_FAILED;
209e0f2c75acb900962dca7ac7c6a325ee845e22ccaSvetoslav                            }
210482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
211e0f2c75acb900962dca7ac7c6a325ee845e22ccaSvetoslav
212482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        @Override
213482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected void onPostExecute(Integer result) {
214cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // The task was not cancelled, so handle the write result.
215482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            switch (result) {
216482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                case RESULT_WRITE_FINISHED: {
217cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    PageRange[] pageRanges = computePageRanges(mWrittenPages);
218cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    callback.onWriteFinished(pageRanges);
219cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                } break;
220ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
221cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                case RESULT_WRITE_FAILED: {
222cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                                    callback.onWriteFailed(null);
223482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                                } break;
224ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                            }
2250fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
226cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            mPdfDocument.close();
227482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        }
228482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov
2290fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                        @Override
230482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                        protected void onCancelled(Integer result) {
231cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            // Task was cancelled, report that.
232482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                            callback.onWriteCancelled();
233cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            mPdfDocument.close();
234f11598332008fd706ed17be975a0ff73ba7f6a21Svetoslav Ganov                        }
235482f8b86361308b90af05c2a3b16eebb0e778882Svetoslav Ganov                    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
2360fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                }
2370fb6959ad364ee84e83c435d671228fb365f2084Svetoslav
238cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                private PageRange[] computePageRanges(SparseIntArray writtenPages) {
239cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    List<PageRange> pageRanges = new ArrayList<PageRange>();
240cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav
241cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    int start = -1;
242cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    int end = -1;
243cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    final int writtenPageCount = writtenPages.size();
244cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    for (int i = 0; i < writtenPageCount; i++) {
245cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        if (start < 0) {
246cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            start = writtenPages.valueAt(i);
247cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        }
248cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        int oldEnd = end = start;
249cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        while (i < writtenPageCount && (end - oldEnd) <= 1) {
250cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            oldEnd = end;
251cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            end = writtenPages.valueAt(i);
252cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                            i++;
253cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        }
254cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        PageRange pageRange = new PageRange(start, end);
255cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        pageRanges.add(pageRange);
256cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                        start = end = -1;
257cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    }
258cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav
259cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    PageRange[] pageRangesArray = new PageRange[pageRanges.size()];
260cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    pageRanges.toArray(pageRangesArray);
261cc797117a2b06f23b52027845c0a6f6700d76368Svetoslav                    return pageRangesArray;
2620fb6959ad364ee84e83c435d671228fb365f2084Svetoslav                }
263ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov
264ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                private boolean containsPage(PageRange[] pageRanges, int page) {
265ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                    final int pageRangeCount = pageRanges.length;
266ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                    for (int i = 0; i < pageRangeCount; i++) {
267ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                        if (pageRanges[i].getStart() <= page
268ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                                && pageRanges[i].getEnd() >= page) {
269ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                            return true;
270ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                        }
271ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                    }
272ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                    return false;
273ecaec06dfbaa011676c37f5f6170b984da5c6a5eSvetoslav Ganov                }
274f11598332008fd706ed17be975a0ff73ba7f6a21Svetoslav Ganov        }, null);
2750fb6959ad364ee84e83c435d671228fb365f2084Svetoslav    }
2760fb6959ad364ee84e83c435d671228fb365f2084Svetoslav}
277