Add checks for android printing
Adds a null check for the WebContent used to set up renderer initiated print jobs and some warnings to be able to follow failures in the process. BUG=528909 Review URL: https://codereview.chromium.org/1338333002 Cr-Commit-Position: refs/heads/master@{#349121}
This commit is contained in:
chrome
android
java
src
org
chromium
chrome
browser
printing
javatests
src
org
chromium
chrome
browser
printing
browser
printing
printing/android/java/src/org/chromium/printing
@ -6,6 +6,7 @@ package org.chromium.chrome.browser.printing;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.printing.Printable;
|
||||
|
||||
@ -19,6 +20,7 @@ import java.lang.ref.WeakReference;
|
||||
*/
|
||||
public class TabPrinter implements Printable {
|
||||
private static String sDefaultTitle;
|
||||
private static final String TAG = "cr.printing";
|
||||
|
||||
private final WeakReference<Tab> mTab;
|
||||
|
||||
@ -33,7 +35,11 @@ public class TabPrinter implements Printable {
|
||||
@Override
|
||||
public boolean print() {
|
||||
Tab tab = mTab.get();
|
||||
return tab != null && tab.isInitialized() && tab.print();
|
||||
if (tab == null || !tab.isInitialized()) {
|
||||
Log.d(TAG, "Tab not ready, unable to start printing.");
|
||||
return false;
|
||||
}
|
||||
return tab.print();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,14 +13,19 @@ import android.print.PrintAttributes;
|
||||
import android.print.PrintDocumentAdapter;
|
||||
import android.print.PrintDocumentInfo;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import org.chromium.base.ApiCompatibilityUtils;
|
||||
import org.chromium.base.test.util.CommandLineFlags;
|
||||
import org.chromium.base.test.util.Feature;
|
||||
import org.chromium.base.test.util.TestFileUtil;
|
||||
import org.chromium.base.test.util.UrlUtils;
|
||||
import org.chromium.chrome.browser.ChromeActivity;
|
||||
import org.chromium.chrome.browser.ChromeSwitches;
|
||||
import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.chrome.test.ChromeActivityTestCaseBase;
|
||||
import org.chromium.chrome.test.util.browser.TabTitleObserver;
|
||||
import org.chromium.content.common.ContentSwitches;
|
||||
import org.chromium.printing.PrintDocumentAdapterWrapper;
|
||||
import org.chromium.printing.PrintManagerDelegate;
|
||||
import org.chromium.printing.PrintingControllerImpl;
|
||||
@ -150,6 +155,31 @@ public class PrintingControllerTest extends ChromeActivityTestCaseBase<ChromeAct
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for http://crbug.com/528909
|
||||
*/
|
||||
@CommandLineFlags.Add(
|
||||
{ContentSwitches.DISABLE_POPUP_BLOCKING, ChromeSwitches.DISABLE_DOCUMENT_MODE})
|
||||
@SmallTest
|
||||
@Feature({"Printing"})
|
||||
public void testPrintClosedWindow() throws Throwable {
|
||||
String html = "<html><head><title>printwindowclose</title></head><body><script>"
|
||||
+ "function printClosedWindow() {"
|
||||
+ " w = window.open(); w.close();"
|
||||
+ " setTimeout(()=>{w.print(); document.title='completed'}, 0);"
|
||||
+ "}</script></body></html>";
|
||||
|
||||
startMainActivityWithURL("data:text/html;charset=utf-8," + html);
|
||||
|
||||
Tab mTab = getActivity().getActivityTab();
|
||||
assertEquals("title does not match initial title", "printwindowclose", mTab.getTitle());
|
||||
|
||||
TabTitleObserver mOnTitleUpdatedHelper = new TabTitleObserver(mTab, "completed");
|
||||
runJavaScriptCodeInCurrentTab("printClosedWindow();");
|
||||
mOnTitleUpdatedHelper.waitForTitleUpdate(2);
|
||||
assertEquals("JS did not finish running", "completed", mTab.getTitle());
|
||||
}
|
||||
|
||||
private PrintingControllerImpl createControllerOnUiThread() {
|
||||
try {
|
||||
final FutureTask<PrintingControllerImpl> task =
|
||||
|
@ -219,7 +219,8 @@ void PrintJobWorker::GetSettingsWithUI(
|
||||
static_cast<PrintingContextDelegate*>(printing_context_delegate_.get());
|
||||
content::WebContents* web_contents =
|
||||
printing_context_delegate->GetWebContents();
|
||||
TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
|
||||
TabAndroid* tab =
|
||||
web_contents ? TabAndroid::FromWebContents(web_contents) : nullptr;
|
||||
|
||||
// Regardless of whether the following call fails or not, the javascript
|
||||
// call will return since startPendingPrint will make it return immediately
|
||||
|
@ -9,13 +9,22 @@ import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintDocumentAdapter;
|
||||
import android.print.PrintJob;
|
||||
import android.print.PrintJobInfo;
|
||||
import android.print.PrintManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.base.annotations.RemovableInRelease;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An implementation of {@link PrintManagerDelegate} using the Android framework print manager.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
public class PrintManagerDelegateImpl implements PrintManagerDelegate {
|
||||
private static final String TAG = "cr.printing";
|
||||
private final PrintManager mPrintManager;
|
||||
|
||||
public PrintManagerDelegateImpl(Context context) {
|
||||
@ -25,7 +34,45 @@ public class PrintManagerDelegateImpl implements PrintManagerDelegate {
|
||||
@Override
|
||||
public void print(String printJobName, PrintDocumentAdapter documentAdapter,
|
||||
PrintAttributes attributes) {
|
||||
dumpJobStatesForDebug();
|
||||
mPrintManager.print(printJobName, documentAdapter, attributes);
|
||||
}
|
||||
|
||||
@RemovableInRelease
|
||||
private void dumpJobStatesForDebug() {
|
||||
List<PrintJob> printJobs = mPrintManager.getPrintJobs();
|
||||
String[] states = new String[printJobs.size()];
|
||||
|
||||
for (int i = 0; i < printJobs.size(); i++) {
|
||||
String stateString;
|
||||
switch (printJobs.get(i).getInfo().getState()) {
|
||||
case PrintJobInfo.STATE_CREATED:
|
||||
stateString = "STATE_CREATED";
|
||||
break;
|
||||
case PrintJobInfo.STATE_QUEUED:
|
||||
stateString = "STATE_QUEUED";
|
||||
break;
|
||||
case PrintJobInfo.STATE_STARTED:
|
||||
stateString = "STATE_STARTED";
|
||||
break;
|
||||
case PrintJobInfo.STATE_BLOCKED:
|
||||
stateString = "STATE_BLOCKED";
|
||||
break;
|
||||
case PrintJobInfo.STATE_FAILED:
|
||||
stateString = "STATE_FAILED";
|
||||
break;
|
||||
case PrintJobInfo.STATE_COMPLETED:
|
||||
stateString = "STATE_COMPLETED";
|
||||
break;
|
||||
case PrintJobInfo.STATE_CANCELED:
|
||||
stateString = "STATE_CANCELED";
|
||||
break;
|
||||
default:
|
||||
stateString = "STATE_UNKNOWN";
|
||||
break;
|
||||
}
|
||||
states[i] = stateString;
|
||||
}
|
||||
Log.v(TAG, "Initiating new print with states in queue: {%s}", TextUtils.join(", ", states));
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package org.chromium.printing;
|
||||
import android.print.PrintDocumentAdapter;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.base.ThreadUtils;
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
@ -18,7 +19,7 @@ import org.chromium.base.annotations.JNINamespace;
|
||||
*/
|
||||
@JNINamespace("printing")
|
||||
public class PrintingContext implements PrintingContextInterface {
|
||||
|
||||
private static final String TAG = "cr.printing";
|
||||
/**
|
||||
* Mapping from a file descriptor (as originally provided from
|
||||
* {@link PrintDocumentAdapter#onWrite}) to a PrintingContext.
|
||||
@ -102,6 +103,7 @@ public class PrintingContext implements PrintingContextInterface {
|
||||
if (mController != null) { // The native side doesn't check if printing is enabled
|
||||
mController.startPendingPrint(this);
|
||||
} else {
|
||||
Log.d(TAG, "Unable to start printing, feature not available.");
|
||||
// Printing disabled. Notify the native side to stop waiting.
|
||||
showSystemDialogDone();
|
||||
}
|
||||
@ -116,6 +118,8 @@ public class PrintingContext implements PrintingContextInterface {
|
||||
PrintingContext printingContext = PRINTING_CONTEXT_MAP.get(fd);
|
||||
printingContext.mController.pdfWritingDone(success);
|
||||
PRINTING_CONTEXT_MAP.remove(fd);
|
||||
} else {
|
||||
Log.d(TAG, "No PrintingContext found for fd %d, can't notify print completion.", fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.print.PageRange;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintDocumentInfo;
|
||||
import android.util.Log;
|
||||
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.base.ThreadUtils;
|
||||
import org.chromium.printing.PrintDocumentAdapterWrapper.PdfGenerator;
|
||||
|
||||
@ -31,8 +31,7 @@ import java.util.Iterator;
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
public class PrintingControllerImpl implements PrintingController, PdfGenerator {
|
||||
|
||||
private static final String LOG_TAG = "PrintingControllerImpl";
|
||||
private static final String TAG = "cr.printing";
|
||||
|
||||
/**
|
||||
* This is used for both initial state and a completed state (i.e. starting from either
|
||||
@ -181,7 +180,10 @@ public class PrintingControllerImpl implements PrintingController, PdfGenerator
|
||||
|
||||
@Override
|
||||
public void setPendingPrint(final Printable printable, PrintManagerDelegate printManager) {
|
||||
if (mIsBusy) return;
|
||||
if (mIsBusy) {
|
||||
Log.d(TAG, "Pending print can't be set. PrintingController is busy.");
|
||||
return;
|
||||
}
|
||||
mPrintable = printable;
|
||||
mPrintManager = printManager;
|
||||
}
|
||||
@ -189,7 +191,9 @@ public class PrintingControllerImpl implements PrintingController, PdfGenerator
|
||||
@Override
|
||||
public void startPendingPrint(PrintingContextInterface printingContext) {
|
||||
if (mIsBusy || mPrintManager == null) {
|
||||
Log.w(LOG_TAG, "Pending print can't be started. Is might be busy or not initialized.");
|
||||
if (mIsBusy) Log.d(TAG, "Pending print can't be started. PrintingController is busy.");
|
||||
else Log.d(TAG, "Pending print can't be started. No PrintManager provided.");
|
||||
|
||||
if (printingContext != null) printingContext.showSystemDialogDone();
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user