blob: 433b32d481783a875bd8a25f1fd2f1df7240e047 [file] [log] [blame]
/*
* Copyright (C) 2016 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.assertException;
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 androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* This test verifies changes to the printer capabilities are applied correctly.
*/
@RunWith(AndroidJUnit4.class)
public class PrinterCapabilitiesTest extends BasePrintTest {
private static final String PRINTER_NAME = "Test printer";
private static final Margins DEFAULT_MARGINS = new Margins(0, 0, 0, 0);
private static final PrintAttributes.Resolution RESOLUTION_300 =
new PrintAttributes.Resolution("300", "300", 300, 300);
private static final PrintAttributes.Resolution RESOLUTION_600 =
new PrintAttributes.Resolution("600", "600", 600, 600);
private static boolean sDefaultPrinterBeenSet;
/**
* That that you cannot create illegal PrinterCapabilityInfos.
*
* @throws Exception If anything is unexpected
*/
@Test
public void illegalPrinterCapabilityInfos() throws Exception {
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createMockPrinterDiscoverySessionCallbacks(invocation -> {
StubbablePrinterDiscoverySession session =
((PrinterDiscoverySessionCallbacks)
invocation.getMock()).getSession();
PrinterId printerId = session.getService().generatePrinterId(PRINTER_NAME);
// printerId need to be set
assertException(() -> new PrinterCapabilitiesInfo.Builder(null),
IllegalArgumentException.class);
// All capability fields (beside duplex) need to be initialized:
// Test no color
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setMinMargins(DEFAULT_MARGINS)
.addMediaSize(MediaSize.ISO_A4, true)
.addResolution(RESOLUTION_300, true).build(),
IllegalStateException.class);
// Test bad colors
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setColorModes(0xffff,
PrintAttributes.COLOR_MODE_MONOCHROME),
IllegalArgumentException.class);
// Test bad duplex mode
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setDuplexModes(0xffff,
PrintAttributes.DUPLEX_MODE_NONE),
IllegalArgumentException.class);
// Test no mediasize
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setColorModes(PrintAttributes.COLOR_MODE_COLOR,
PrintAttributes.COLOR_MODE_COLOR)
.setMinMargins(DEFAULT_MARGINS)
.addResolution(RESOLUTION_300, true).build(),
IllegalStateException.class);
// Test no default mediasize
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setColorModes(PrintAttributes.COLOR_MODE_COLOR,
PrintAttributes.COLOR_MODE_COLOR)
.setMinMargins(DEFAULT_MARGINS)
.addMediaSize(MediaSize.ISO_A4, false)
.addResolution(RESOLUTION_300, true).build(),
IllegalStateException.class);
// Test two default mediasizes
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.addMediaSize(MediaSize.ISO_A4, true)
.addMediaSize(MediaSize.ISO_A5, true),
IllegalArgumentException.class);
// Test no resolution
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setColorModes(PrintAttributes.COLOR_MODE_COLOR,
PrintAttributes.COLOR_MODE_COLOR)
.setMinMargins(DEFAULT_MARGINS)
.addMediaSize(MediaSize.ISO_A4, true).build(),
IllegalStateException.class);
// Test no default resolution
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.setColorModes(PrintAttributes.COLOR_MODE_COLOR,
PrintAttributes.COLOR_MODE_COLOR)
.setMinMargins(DEFAULT_MARGINS)
.addMediaSize(MediaSize.ISO_A4, true)
.addResolution(RESOLUTION_300, false).build(),
IllegalStateException.class);
// Test two default resolutions
assertException(() ->
(new PrinterCapabilitiesInfo.Builder(printerId))
.addResolution(RESOLUTION_300, true)
.addResolution(RESOLUTION_600, true),
IllegalArgumentException.class);
onPrinterDiscoverySessionCreateCalled();
return null;
}, null, null, null, null, null, invocation -> {
onPrinterDiscoverySessionDestroyCalled();
return null;
});
// Create the service callbacks for the first print service.
PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> firstSessionCallbacks, null, null);
// Configure the print services.
FirstPrintService.setCallbacks(firstServiceCallbacks);
SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(null, null, null);
// Start printing.
print(adapter);
waitForPrinterDiscoverySessionCreateCallbackCalled();
getActivity().finish();
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
}
/**
* That that you can use all sane legal PrinterCapabilityInfos.
*
* @throws Exception If anything is unexpected
*/
@Test
public void sanePrinterCapabilityInfos() throws Exception {
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createMockPrinterDiscoverySessionCallbacks(invocation -> {
StubbablePrinterDiscoverySession session =
((PrinterDiscoverySessionCallbacks)
invocation.getMock()).getSession();
MediaSize[] mediaSizes = {MediaSize.ISO_A0, MediaSize.ISO_A0,
MediaSize.ISO_A1};
Resolution[] resolutions = {RESOLUTION_300, RESOLUTION_300,
RESOLUTION_600};
int[] colorModes = {PrintAttributes.COLOR_MODE_MONOCHROME,
PrintAttributes.COLOR_MODE_COLOR};
int[] duplexModes = {PrintAttributes.DUPLEX_MODE_NONE,
PrintAttributes.DUPLEX_MODE_LONG_EDGE,
PrintAttributes.DUPLEX_MODE_SHORT_EDGE};
ArrayList<PrinterInfo> printers = new ArrayList<>();
for (int mediaSizeIndex = 1; mediaSizeIndex < mediaSizes.length;
mediaSizeIndex++) {
for (int resolutionIndex = 1; resolutionIndex < mediaSizes.length;
resolutionIndex++) {
for (int colorIndex = 1; colorIndex < colorModes.length;
colorIndex++) {
for (int duplexIndex = 1; duplexIndex < duplexModes.length;
duplexIndex++) {
PrinterId printerId = session.getService()
.generatePrinterId(Integer.valueOf(printers.size())
.toString());
// Setup capabilities
PrinterCapabilitiesInfo.Builder b =
new PrinterCapabilitiesInfo.Builder(printerId);
for (int i = 0; i < mediaSizeIndex; i++) {
b.addMediaSize(mediaSizes[i], i == mediaSizeIndex - 1);
}
for (int i = 0; i < resolutionIndex; i++) {
b.addResolution(resolutions[i],
i == resolutionIndex - 1);
}
int allColors = 0;
for (int i = 0; i < colorIndex; i++) {
allColors |= colorModes[i];
}
b.setColorModes(allColors, colorModes[colorIndex - 1]);
int allDuplexModes = 0;
for (int i = 0; i < duplexIndex; i++) {
allDuplexModes |= duplexModes[i];
}
b.setDuplexModes(allDuplexModes,
duplexModes[duplexIndex - 1]);
b.setMinMargins(DEFAULT_MARGINS);
// Create printer
PrinterInfo printer = (new PrinterInfo.Builder(printerId,
Integer.valueOf(printers.size()).toString(),
PrinterInfo.STATUS_IDLE)).setCapabilities(b.build())
.build();
// Verify capabilities
PrinterCapabilitiesInfo cap = printer.getCapabilities();
assertEquals(mediaSizeIndex, cap.getMediaSizes().size());
assertEquals(mediaSizes[mediaSizeIndex - 1],
cap.getDefaults().getMediaSize());
for (int i = 0; i < mediaSizeIndex; i++) {
assertTrue(cap.getMediaSizes().contains(mediaSizes[i]));
}
assertEquals(resolutionIndex, cap.getResolutions().size());
assertEquals(resolutions[resolutionIndex - 1],
cap.getDefaults().getResolution());
for (int i = 0; i < resolutionIndex; i++) {
assertTrue(cap.getResolutions().contains(resolutions[i]));
}
assertEquals(allColors, cap.getColorModes());
assertEquals(colorModes[colorIndex - 1],
cap.getDefaults().getColorMode());
assertEquals(allDuplexModes, cap.getDuplexModes());
assertEquals(duplexModes[duplexIndex - 1],
cap.getDefaults().getDuplexMode());
assertEquals(DEFAULT_MARGINS, cap.getMinMargins());
// Add printer
printers.add(printer);
}
}
}
}
session.addPrinters(printers);
onPrinterDiscoverySessionCreateCalled();
return null;
}, null, null, null, null, null, invocation -> {
onPrinterDiscoverySessionDestroyCalled();
return null;
});
// Create the service callbacks for the first print service.
PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> firstSessionCallbacks, null, null);
// Configure the print services.
FirstPrintService.setCallbacks(firstServiceCallbacks);
SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(null, null, null);
// Start printing.
print(adapter);
waitForPrinterDiscoverySessionCreateCallbackCalled();
getUiDevice().pressBack();
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
}
/**
* Base test that performs a print operation with a give PrinterCapabilityInfo and run a test
* function before finishing.
*
* @throws Exception
*/
private void testPrinterCapabilityInfo(final Function<PrinterId, PrinterCapabilitiesInfo>
capBuilder, Consumer<PrintAttributes> test) throws Exception {
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createMockPrinterDiscoverySessionCallbacks(invocation -> {
StubbablePrinterDiscoverySession session =
((PrinterDiscoverySessionCallbacks)
invocation.getMock()).getSession();
PrinterId printerId = session.getService()
.generatePrinterId(PRINTER_NAME);
ArrayList<PrinterInfo> printers = new ArrayList<>();
printers.add((new PrinterInfo.Builder(printerId, PRINTER_NAME,
PrinterInfo.STATUS_IDLE))
.setCapabilities(capBuilder.apply(printerId)).build());
session.addPrinters(printers);
onPrinterDiscoverySessionCreateCalled();
return null;
}, null, null, null, null, null, invocation -> {
onPrinterDiscoverySessionDestroyCalled();
return null;
});
// Create the service callbacks for the first print service.
PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> firstSessionCallbacks, null, null);
// Configure the print services.
FirstPrintService.setCallbacks(firstServiceCallbacks);
SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
final PrintAttributes[] layoutAttributes = new PrintAttributes[1];
PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
invocation -> {
LayoutResultCallback callback = (LayoutResultCallback) invocation
.getArguments()[3];
PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
.setPageCount(1)
.build();
layoutAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
callback.onLayoutFinished(info, true);
return null;
},
invocation -> {
Object[] args = invocation.getArguments();
PageRange[] pages = (PageRange[]) args[0];
ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
WriteResultCallback callback = (WriteResultCallback) args[3];
writeBlankPages(layoutAttributes[0], fd, pages[0].getStart(),
pages[0].getEnd());
fd.close();
callback.onWriteFinished(pages);
return null;
}, null);
// Start printing.
print(adapter);
// make sure that options does not crash
openPrintOptions();
if (!sDefaultPrinterBeenSet) {
// Select printer under test
selectPrinter(PRINTER_NAME);
}
clickPrintButton();
if (!sDefaultPrinterBeenSet) {
answerPrintServicesWarning(true);
sDefaultPrinterBeenSet = true;
}
test.accept(layoutAttributes[0]);
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
}
/**
* That that you use a default color that is not in the allowed colors. This is allowed because
* of historical reasons.
*
* @throws Exception If anything is unexpected
*/
@Test
public void invalidDefaultColor() throws Exception {
testPrinterCapabilityInfo(
(printerId) -> (new PrinterCapabilitiesInfo.Builder(printerId))
.addMediaSize(MediaSize.ISO_A4, true)
.addResolution(RESOLUTION_300, true)
.setColorModes(PrintAttributes.COLOR_MODE_MONOCHROME,
PrintAttributes.COLOR_MODE_COLOR).build(),
(layoutAttributes) -> assertEquals(layoutAttributes.getColorMode(),
PrintAttributes.COLOR_MODE_MONOCHROME));
}
/**
* That that you use a default duplex mode that is not in the allowed duplex modes. This is
* allowed because of historical reasons.
*
* @throws Exception If anything is unexpected
*/
@Test
public void invalidDefaultDuplexMode() throws Exception {
testPrinterCapabilityInfo(
(printerId) -> (new PrinterCapabilitiesInfo.Builder(printerId))
.addMediaSize(MediaSize.ISO_A4, true)
.addResolution(RESOLUTION_300, true)
.setColorModes(PrintAttributes.COLOR_MODE_MONOCHROME,
PrintAttributes.COLOR_MODE_MONOCHROME)
.setDuplexModes(PrintAttributes.DUPLEX_MODE_LONG_EDGE
| PrintAttributes.DUPLEX_MODE_NONE,
PrintAttributes.DUPLEX_MODE_SHORT_EDGE).build(),
(layoutAttributes) -> assertTrue(layoutAttributes.getDuplexMode() ==
PrintAttributes.DUPLEX_MODE_LONG_EDGE || layoutAttributes.getDuplexMode() ==
PrintAttributes.DUPLEX_MODE_NONE));
}
}