1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.printing; 6 7import android.print.PrintDocumentAdapter; 8import android.util.SparseArray; 9 10import org.chromium.base.CalledByNative; 11import org.chromium.base.JNINamespace; 12import org.chromium.base.ThreadUtils; 13 14/** 15 * This class is responsible for communicating with its native counterpart through JNI to handle 16 * the generation of PDF. On the Java side, it works with a {@link PrintingController} 17 * to talk to the framework. 18 */ 19@JNINamespace("printing") 20public class PrintingContext implements PrintingContextInterface { 21 22 /** 23 * Mapping from a file descriptor (as originally provided from 24 * {@link PrintDocumentAdapter#onWrite}) to a PrintingContext. 25 * 26 * This is static because a static method of the native code (inside PrintingContextAndroid) 27 * needs to find Java PrintingContext class corresponding to a file descriptor. 28 **/ 29 private static final SparseArray<PrintingContext> PRINTING_CONTEXT_MAP = 30 new SparseArray<PrintingContext>(); 31 32 /** The controller this object interacts with, which in turn communicates with the framework. */ 33 private final PrintingController mController; 34 35 /** The pointer to the native PrintingContextAndroid object. */ 36 private final long mNativeObject; 37 38 private PrintingContext(long ptr) { 39 mController = PrintingControllerImpl.getInstance(); 40 mNativeObject = ptr; 41 } 42 43 /** 44 * Updates PRINTING_CONTEXT_MAP to map from the file descriptor to this object. 45 * @param fileDescriptor The file descriptor passed down from 46 * {@link PrintDocumentAdapter#onWrite}. 47 * @param delete If true, delete the entry (if it exists). If false, add it to the map. 48 */ 49 @Override 50 public void updatePrintingContextMap(int fileDescriptor, boolean delete) { 51 ThreadUtils.assertOnUiThread(); 52 if (delete) { 53 PRINTING_CONTEXT_MAP.remove(fileDescriptor); 54 } else { 55 PRINTING_CONTEXT_MAP.put(fileDescriptor, this); 56 } 57 } 58 59 /** 60 * Notifies the native side that the user just chose a new set of printing settings. 61 * @param success True if the user has chosen printing settings necessary for the 62 * generation of PDF, false if there has been a problem. 63 */ 64 @Override 65 public void askUserForSettingsReply(boolean success) { 66 nativeAskUserForSettingsReply(mNativeObject, success); 67 } 68 69 @CalledByNative 70 public static PrintingContext create(int nativeObjectPointer) { 71 ThreadUtils.assertOnUiThread(); 72 return new PrintingContext(nativeObjectPointer); 73 } 74 75 @CalledByNative 76 public int getFileDescriptor() { 77 ThreadUtils.assertOnUiThread(); 78 return mController.getFileDescriptor(); 79 } 80 81 @CalledByNative 82 public int getDpi() { 83 ThreadUtils.assertOnUiThread(); 84 return mController.getDpi(); 85 } 86 87 @CalledByNative 88 public int getWidth() { 89 ThreadUtils.assertOnUiThread(); 90 return mController.getPageWidth(); 91 } 92 93 @CalledByNative 94 public int getHeight() { 95 ThreadUtils.assertOnUiThread(); 96 return mController.getPageHeight(); 97 } 98 99 @CalledByNative 100 public static void pdfWritingDone(int fd, boolean success) { 101 ThreadUtils.assertOnUiThread(); 102 // TODO(cimamoglu): Do something when fd == -1. 103 if (PRINTING_CONTEXT_MAP.get(fd) != null) { 104 ThreadUtils.assertOnUiThread(); 105 PrintingContext printingContext = PRINTING_CONTEXT_MAP.get(fd); 106 printingContext.mController.pdfWritingDone(success); 107 PRINTING_CONTEXT_MAP.remove(fd); 108 } 109 } 110 111 @CalledByNative 112 public int[] getPages() { 113 ThreadUtils.assertOnUiThread(); 114 return mController.getPageNumbers(); 115 } 116 117 @CalledByNative 118 public void pageCountEstimationDone(final int maxPages) { 119 ThreadUtils.assertOnUiThread(); 120 // If the printing dialog has already finished, tell Chromium that operation is cancelled. 121 if (mController.hasPrintingFinished()) { 122 // NOTE: We don't call nativeAskUserForSettingsReply (hence Chromium callback in 123 // AskUserForSettings callback) twice. See {@link PrintingControllerImpl#onFinish} 124 // for more explanation. 125 nativeAskUserForSettingsReply(mNativeObject, false); 126 } else { 127 mController.setPrintingContext(this); 128 mController.pageCountEstimationDone(maxPages); 129 } 130 } 131 132 private native void nativeAskUserForSettingsReply( 133 long nativePrintingContextAndroid, 134 boolean success); 135}