blob: 298d48f5b4ef32429f7dc16fbf4ae737421e7ced [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.print.cts;
import static android.print.test.Utils.eventually;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Resolution;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentAdapter.LayoutResultCallback;
import android.print.PrintDocumentAdapter.WriteResultCallback;
import android.print.PrintDocumentInfo;
import android.print.PrinterCapabilitiesInfo;
import android.print.PrinterId;
import android.print.PrinterInfo;
import android.print.test.BasePrintTest;
import android.print.test.services.FirstPrintService;
import android.print.test.services.PrintServiceCallbacks;
import android.print.test.services.PrinterDiscoverySessionCallbacks;
import android.print.test.services.SecondPrintService;
import android.print.test.services.StubbablePrinterDiscoverySession;
import android.printservice.PrintJob;
import android.printservice.PrintService;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
/**
* This test verifies that the system respects the {@link PrintDocumentAdapter}
* contract and invokes all callbacks as expected.
*/
@RunWith(AndroidJUnit4.class)
public class PrintDocumentInfoTest extends BasePrintTest {
private static boolean sIsDefaultPrinterSet;
@Before
public void setDefaultPrinter() throws Exception {
if (!sIsDefaultPrinterSet) {
// Create a callback for the target print service.
FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
// Create a mock print adapter.
final PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
makeDefaultPrinter(adapter, "First printer");
resetCounters();
sIsDefaultPrinterSet = true;
}
}
/**
* Executes a print process with a given print document info
*
* @param name The name of the document info
* @param contentType The content type of the document
* @param pageCount The number of pages in the document
*/
private void printDocumentBaseTest(String name, Integer contentType, Integer pageCount)
throws Throwable {
FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
PrintDocumentInfo.Builder b = new PrintDocumentInfo.Builder(name);
if (contentType != null) {
b.setContentType(contentType);
}
if (pageCount != null) {
b.setPageCount(pageCount);
}
PrintDocumentInfo info = b.build();
PrintDocumentInfo queuedInfo[] = new PrintDocumentInfo[1];
ParcelFileDescriptor queuedData[] = new ParcelFileDescriptor[1];
PrinterDiscoverySessionCallbacks printerDiscoverySessionCallbacks =
createFirstMockDiscoverySessionCallbacks();
PrintServiceCallbacks printServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> printerDiscoverySessionCallbacks,
invocation -> {
PrintJob printJob = (PrintJob) invocation.getArguments()[0];
queuedInfo[0] = printJob.getDocument().getInfo();
queuedData[0] = printJob.getDocument().getData();
printJob.complete();
return null;
}, null);
FirstPrintService.setCallbacks(printServiceCallbacks);
final PrintAttributes[] printAttributes = new PrintAttributes[1];
// Create a mock print adapter.
final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
invocation -> {
printAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
LayoutResultCallback callback = (LayoutResultCallback) invocation
.getArguments()[3];
callback.onLayoutFinished(info, false);
return null;
}, invocation -> {
Object[] args = invocation.getArguments();
PageRange[] pages = (PageRange[]) args[0];
ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
WriteResultCallback callback = (WriteResultCallback) args[3];
writeBlankPages(printAttributes[0], fd, 0, 1);
fd.close();
callback.onWriteFinished(pages);
onWriteCalled();
return null;
}, invocation -> null);
// Start printing.
print(adapter);
// Wait for layout.
waitForWriteAdapterCallback(1);
// Click the print button.
clickPrintButton();
// Wait for the session to be destroyed to isolate tests.
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
// Check that the document name was carried over 1:1
eventually(() -> assertEquals(name, queuedInfo[0].getName()));
// Content type is set to document by default, but is otherwise unrestricted
if (contentType != null) {
assertEquals(contentType, Integer.valueOf(queuedInfo[0].getContentType()));
} else {
assertEquals(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT, queuedInfo[0].getContentType());
}
// Page count is set to the real value if unknown, 0 or unset.
// Otherwise the set value is used
if (pageCount != null && pageCount != PrintDocumentInfo.PAGE_COUNT_UNKNOWN
&& pageCount != 0) {
assertEquals(pageCount, Integer.valueOf(queuedInfo[0].getPageCount()));
} else {
assertEquals(2, queuedInfo[0].getPageCount());
}
// Verify data (== pdf file) size
assertTrue(queuedInfo[0].getDataSize() > 0);
long bytesRead = 0;
try (FileInputStream is = new FileInputStream(queuedData[0].getFileDescriptor())) {
while (true) {
int ret = is.read();
if (ret == -1) {
break;
}
bytesRead++;
}
}
assertEquals(queuedInfo[0].getDataSize(), bytesRead);
}
/**
* Test that the default values of the PrintDocumentInfo are fine.
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoNothingSet() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, null, null);
}
/**
* Test that a unknown page count is handled correctly.
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoUnknownPageCount() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, null, PrintDocumentInfo.PAGE_COUNT_UNKNOWN);
}
/**
* Test that zero page count is handled correctly.
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoZeroPageCount() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, null, 0);
}
/**
* Test that page count one is handled correctly. (The document has two pages)
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoOnePageCount() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, null, 1);
}
/**
* Test that page count three is handled correctly. (The document has two pages)
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoThreePageCount() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, null, 3);
}
/**
* Test that a photo content type is handled correctly.
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoContentTypePhoto() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, PrintDocumentInfo.CONTENT_TYPE_PHOTO, null);
}
/**
* Test that a unknown content type is handled correctly.
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoContentTypeUnknown() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, PrintDocumentInfo.CONTENT_TYPE_UNKNOWN, null);
}
/**
* Test that a undefined content type is handled correctly.
*
* @throws Exception If anything unexpected happens
*/
@Test
public void documentInfoContentTypeNonDefined() throws Throwable {
printDocumentBaseTest(PRINT_JOB_NAME, -23, null);
}
private PrinterDiscoverySessionCallbacks createFirstMockDiscoverySessionCallbacks() {
return createMockPrinterDiscoverySessionCallbacks(invocation -> {
PrinterDiscoverySessionCallbacks mock = (PrinterDiscoverySessionCallbacks)
invocation.getMock();
StubbablePrinterDiscoverySession session = mock.getSession();
PrintService service = session.getService();
if (session.getPrinters().isEmpty()) {
List<PrinterInfo> printers = new ArrayList<>();
// Add the first printer.
PrinterId firstPrinterId = service.generatePrinterId("first_printer");
PrinterCapabilitiesInfo firstCapabilities =
new PrinterCapabilitiesInfo.Builder(firstPrinterId)
.setMinMargins(new Margins(200, 200, 200, 200))
.addMediaSize(MediaSize.ISO_A0, true)
.addMediaSize(MediaSize.ISO_A5, false)
.addResolution(new Resolution("300x300", "300x300", 300, 300), true)
.setColorModes(PrintAttributes.COLOR_MODE_COLOR,
PrintAttributes.COLOR_MODE_COLOR)
.build();
PrinterInfo firstPrinter = new PrinterInfo.Builder(firstPrinterId,
"First printer", PrinterInfo.STATUS_IDLE)
.setCapabilities(firstCapabilities)
.build();
printers.add(firstPrinter);
session.addPrinters(printers);
}
return null;
}, null, null, null, null, null, invocation -> {
// Take a note onDestroy was called.
onPrinterDiscoverySessionDestroyCalled();
return null;
});
}
private PrintServiceCallbacks createFirstMockPrintServiceCallbacks() {
final PrinterDiscoverySessionCallbacks callbacks =
createFirstMockDiscoverySessionCallbacks();
return createMockPrintServiceCallbacks(invocation -> callbacks, invocation -> {
PrintJob printJob = (PrintJob) invocation.getArguments()[0];
printJob.complete();
return null;
}, null);
}
private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
return createMockPrintServiceCallbacks(null, null, null);
}
}