blob: 5580cdae8bc08df200d0c54010b80e7f8871f1d5 [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 android.print.test.Utils.runOnMainThread;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.inOrder;
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.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.PrinterDiscoverySession;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiSelector;
import androidx.annotation.NonNull;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.exceptions.verification.VerificationInOrderFailure;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* This test verifies that the system respects the {@link PrinterDiscoverySession}
* contract is respected.
*/
@RunWith(AndroidJUnit4.class)
public class PrinterDiscoverySessionLifecycleTest extends BasePrintTest {
private static final String FIRST_PRINTER_LOCAL_ID = "first_printer";
private static final String SECOND_PRINTER_LOCAL_ID = "second_printer";
private static StubbablePrinterDiscoverySession sSession;
@Before
public void clearPrintSpoolerState() throws Exception {
clearPrintSpoolerData();
}
/**
* Add a printer to {@#sSession}.
*
* @param localId The id of the printer to add
* @param hasCapabilities If the printer has capabilities
*/
private void addPrinter(@NonNull String localId, boolean hasCapabilities) {
// Add the first printer.
PrinterId firstPrinterId = sSession.getService().generatePrinterId(
localId);
PrinterInfo.Builder printer = new PrinterInfo.Builder(firstPrinterId,
localId, PrinterInfo.STATUS_IDLE);
if (hasCapabilities) {
printer.setCapabilities(new PrinterCapabilitiesInfo.Builder(firstPrinterId)
.setMinMargins(new Margins(200, 200, 200, 200))
.addMediaSize(MediaSize.ISO_A0, true)
.addResolution(new Resolution("300x300", "300x300", 300, 300), true)
.setColorModes(PrintAttributes.COLOR_MODE_COLOR,
PrintAttributes.COLOR_MODE_COLOR)
.build());
}
sSession.addPrinters(Collections.singletonList(printer.build()));
}
/**
* Make {@code localPrinterId} the default printer. This requires a full print workflow.
*
* As a side-effect also approved the print service.
*
* @param localPrinterId The printer to make default
*/
private void makeDefaultPrinter(String localPrinterId) throws Throwable {
PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
print(adapter);
waitForWriteAdapterCallback(1);
runOnMainThread(() -> addPrinter(localPrinterId, true));
selectPrinter(localPrinterId);
waitForWriteAdapterCallback(2);
clickPrintButton();
answerPrintServicesWarning(true);
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
resetCounters();
}
/**
* Select a printer in the all printers activity
*
* @param printerName The name of the printer to select
*/
private void selectInAllPrintersActivity(@NonNull String printerName) throws Exception {
while (true) {
UiObject printerItem = getUiDevice().findObject(
new UiSelector().text(printerName));
if (printerItem.isEnabled()) {
printerItem.click();
break;
} else {
Thread.sleep(100);
}
}
}
@Test
public void defaultPrinterBecomesAvailableWhileInBackground() throws Throwable {
// Create the session callbacks that we will be checking.
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createMockPrinterDiscoverySessionCallbacks(invocation -> {
sSession =
((PrinterDiscoverySessionCallbacks) invocation.getMock()).getSession();
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(createSecondMockPrintServiceCallbacks());
makeDefaultPrinter(FIRST_PRINTER_LOCAL_ID);
PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
print(adapter);
waitForPrinterDiscoverySessionCreateCallbackCalled();
waitForPrinterUnavailable();
selectPrinter("All printers…");
// Let all printers activity start
Thread.sleep(500);
// Add printer
runOnMainThread(() -> addPrinter(FIRST_PRINTER_LOCAL_ID, true));
// Select printer once available (this returns to main print activity)
selectInAllPrintersActivity(FIRST_PRINTER_LOCAL_ID);
// Wait for preview to load and finish print
waitForWriteAdapterCallback(1);
clickPrintButton();
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
}
@Test
public void defaultPrinterBecomesUsableWhileInBackground() throws Throwable {
// Create the session callbacks that we will be checking.
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createMockPrinterDiscoverySessionCallbacks(invocation -> {
sSession =
((PrinterDiscoverySessionCallbacks) invocation.getMock()).getSession();
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(createSecondMockPrintServiceCallbacks());
makeDefaultPrinter(FIRST_PRINTER_LOCAL_ID);
PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
print(adapter);
waitForPrinterDiscoverySessionCreateCallbackCalled();
// Add printer but do not enable it (capabilities == null)
runOnMainThread(() -> addPrinter(FIRST_PRINTER_LOCAL_ID, false));
waitForPrinterUnavailable();
selectPrinter("All printers…");
// Let all printers activity start
Thread.sleep(500);
// Enable printer
runOnMainThread(() -> addPrinter(FIRST_PRINTER_LOCAL_ID, true));
// Select printer once available (this returns to main print activity)
selectInAllPrintersActivity(FIRST_PRINTER_LOCAL_ID);
// Wait for preview to load and finish print
waitForWriteAdapterCallback(1);
clickPrintButton();
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
}
@Test
public void normalLifecycle() throws Throwable {
// Create the session callbacks that we will be checking.
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createFirstMockPrinterDiscoverySessionCallbacks();
// Create the service callbacks for the first print service.
PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> firstSessionCallbacks,
invocation -> {
PrintJob printJob = (PrintJob) invocation.getArguments()[0];
// We pretend the job is handled immediately.
printJob.complete();
return null;
}, null);
// Configure the print services.
FirstPrintService.setCallbacks(firstServiceCallbacks);
SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
// Create a print adapter that respects the print contract.
PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
// Start printing.
print(adapter);
// Wait for write of the first page.
waitForWriteAdapterCallback(1);
runOnMainThread(() -> assertFalse(sSession.isDestroyed()));
runOnMainThread(() -> assertEquals(0, sSession.getTrackedPrinters().size()));
// Select the first printer.
selectPrinter(FIRST_PRINTER_LOCAL_ID);
eventually(() -> runOnMainThread(() -> assertEquals(FIRST_PRINTER_LOCAL_ID,
sSession.getTrackedPrinters().get(0).getLocalId())));
runOnMainThread(() -> assertTrue(sSession.isPrinterDiscoveryStarted()));
runOnMainThread(() -> assertEquals(1, sSession.getTrackedPrinters().size()));
// Wait for layout as the printer has different capabilities.
waitForLayoutAdapterCallbackCount(2);
// Select the second printer (same capabilities as the other
// one so no layout should happen).
selectPrinter(SECOND_PRINTER_LOCAL_ID);
eventually(() -> runOnMainThread(() -> assertEquals(SECOND_PRINTER_LOCAL_ID,
sSession.getTrackedPrinters().get(0).getLocalId())));
runOnMainThread(() -> assertEquals(1, sSession.getTrackedPrinters().size()));
// While the printer discovery session is still alive store the
// ids of printers as we want to make some assertions about them
// but only the print service can create printer ids which means
// that we need to get the created ones.
PrinterId firstPrinterId = getAddedPrinterIdForLocalId(
FIRST_PRINTER_LOCAL_ID);
PrinterId secondPrinterId = getAddedPrinterIdForLocalId(
SECOND_PRINTER_LOCAL_ID);
assertNotNull("Coundn't find printer:" + FIRST_PRINTER_LOCAL_ID, firstPrinterId);
assertNotNull("Coundn't find printer:" + SECOND_PRINTER_LOCAL_ID, secondPrinterId);
// Click the print button.
clickPrintButton();
// Answer the dialog for the print service cloud warning
answerPrintServicesWarning(true);
// Wait for all print jobs to be handled after which the session destroyed.
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
runOnMainThread(() -> assertTrue(sSession.isDestroyed()));
runOnMainThread(() -> assertFalse(sSession.isPrinterDiscoveryStarted()));
runOnMainThread(() -> assertEquals(0, sSession.getTrackedPrinters().size()));
// Verify the expected calls.
InOrder inOrder = inOrder(firstSessionCallbacks);
// We start discovery as the print dialog was up.
List<PrinterId> emptyPrinterIdList = Collections.emptyList();
inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
emptyPrinterIdList);
// We selected the first printer and now it should be tracked.
inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
firstPrinterId);
// We selected the second printer so the first should not be tracked.
inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
firstPrinterId);
// We selected the second printer and now it should be tracked.
inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
secondPrinterId);
// The print dialog went away so we first stop the printer tracking...
inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
secondPrinterId);
// ... next we stop printer discovery...
inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
// ... last the session is destroyed.
inOrder.verify(firstSessionCallbacks).onDestroy();
}
@Test
public void cancelPrintServicesAlertDialog() throws Throwable {
// Create the session callbacks that we will be checking.
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createFirstMockPrinterDiscoverySessionCallbacks();
// Create the service callbacks for the first print service.
PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> firstSessionCallbacks,
invocation -> {
PrintJob printJob = (PrintJob) invocation.getArguments()[0];
// We pretend the job is handled immediately.
printJob.complete();
return null;
}, null);
// Configure the print services.
FirstPrintService.setCallbacks(firstServiceCallbacks);
SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
// Create a print adapter that respects the print contract.
PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
// Start printing.
print(adapter);
// Wait for write of the first page.
waitForWriteAdapterCallback(1);
runOnMainThread(() -> assertFalse(sSession.isDestroyed()));
runOnMainThread(() -> assertEquals(0, sSession.getTrackedPrinters().size()));
// Select the first printer.
selectPrinter(FIRST_PRINTER_LOCAL_ID);
eventually(() -> runOnMainThread(() -> assertEquals(FIRST_PRINTER_LOCAL_ID,
sSession.getTrackedPrinters().get(0).getLocalId())));
runOnMainThread(() -> assertTrue(sSession.isPrinterDiscoveryStarted()));
runOnMainThread(() -> assertEquals(1, sSession.getTrackedPrinters().size()));
// While the printer discovery session is still alive store the
// ids of printers as we want to make some assertions about them
// but only the print service can create printer ids which means
// that we need to get the created ones.
PrinterId firstPrinterId = getAddedPrinterIdForLocalId(
FIRST_PRINTER_LOCAL_ID);
assertNotNull("Coundn't find printer:" + FIRST_PRINTER_LOCAL_ID, firstPrinterId);
// Click the print button.
clickPrintButton();
// Cancel the dialog for the print service cloud warning
answerPrintServicesWarning(false);
// Click the print button again.
clickPrintButton();
// Answer the dialog for the print service cloud warning
answerPrintServicesWarning(true);
// Wait for all print jobs to be handled after which the session destroyed.
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
runOnMainThread(() -> assertTrue(sSession.isDestroyed()));
runOnMainThread(() -> assertFalse(sSession.isPrinterDiscoveryStarted()));
runOnMainThread(() -> assertEquals(0, sSession.getTrackedPrinters().size()));
// Verify the expected calls.
InOrder inOrder = inOrder(firstSessionCallbacks);
// We start discovery as the print dialog was up.
List<PrinterId> emptyPrinterIdList = Collections.emptyList();
inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
emptyPrinterIdList);
// We selected the first printer and now it should be tracked.
inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
firstPrinterId);
// We selected the second printer so the first should not be tracked.
inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
firstPrinterId);
// ... next we stop printer discovery...
inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
// ... last the session is destroyed.
inOrder.verify(firstSessionCallbacks).onDestroy();
}
@Test
public void startPrinterDiscoveryWithHistoricalPrinters() throws Throwable {
// Create the session callbacks that we will be checking.
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createFirstMockPrinterDiscoverySessionCallbacks();
// Create the service callbacks for the first print service.
PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
invocation -> firstSessionCallbacks,
invocation -> {
PrintJob printJob = (PrintJob) invocation.getArguments()[0];
// We pretend the job is handled immediately.
printJob.complete();
return null;
}, null);
// Configure the print services.
FirstPrintService.setCallbacks(firstServiceCallbacks);
SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
// Create a print adapter that respects the print contract.
PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
// Start printing.
print(adapter);
// Wait for write of the first page.
waitForWriteAdapterCallback(1);
runOnMainThread(() -> assertFalse(sSession.isDestroyed()));
runOnMainThread(() -> assertEquals(0, sSession.getTrackedPrinters().size()));
// Select the first printer.
selectPrinter(FIRST_PRINTER_LOCAL_ID);
eventually(() -> runOnMainThread(() -> assertEquals(FIRST_PRINTER_LOCAL_ID,
sSession.getTrackedPrinters().get(0).getLocalId())));
runOnMainThread(() -> assertTrue(sSession.isPrinterDiscoveryStarted()));
runOnMainThread(() -> assertEquals(1, sSession.getTrackedPrinters().size()));
// Wait for a layout to finish - first layout was for the
// PDF printer, second for the first printer in preview mode.
waitForLayoutAdapterCallbackCount(2);
// While the printer discovery session is still alive store the
// ids of printer as we want to make some assertions about it
// but only the print service can create printer ids which means
// that we need to get the created one.
PrinterId firstPrinterId = getAddedPrinterIdForLocalId(
FIRST_PRINTER_LOCAL_ID);
// Click the print button.
clickPrintButton();
// Answer the dialog for the print service cloud warning
answerPrintServicesWarning(true);
// Wait for the print to complete.
waitForAdapterFinishCallbackCalled();
// Now print again as we want to confirm that the start
// printer discovery passes in the priority list.
print(adapter);
// Wait for a layout to finish - first layout was for the
// PDF printer, second for the first printer in preview mode,
// the third for the first printer in non-preview mode, and
// now a fourth for the PDF printer as we are printing again.
waitForLayoutAdapterCallbackCount(4);
// Cancel the printing.
getUiDevice().pressBack(); // wakes up the device.
getUiDevice().pressBack();
// Wait for all print jobs to be handled after which the is session destroyed.
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
runOnMainThread(() -> assertTrue(sSession.isDestroyed()));
runOnMainThread(() -> assertFalse(sSession.isPrinterDiscoveryStarted()));
runOnMainThread(() -> assertEquals(0, sSession.getTrackedPrinters().size()));
// Verify the expected calls.
InOrder inOrder = inOrder(firstSessionCallbacks);
// We start discovery with no printer history.
List<PrinterId> priorityList = new ArrayList<>();
inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
priorityList);
// We selected the first printer and now it should be tracked.
inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
firstPrinterId);
// We confirmed print so the first should not be tracked.
inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
firstPrinterId);
// This is tricky. It is possible that the print activity was not
// destroyed (the platform delays destruction at convenient time as
// an optimization) and we get the same instance which means that
// the discovery session may not have been destroyed. We try the
// case with the activity being destroyed and if this fails the
// case with the activity brought to front.
priorityList.add(firstPrinterId);
try {
inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(priorityList);
} catch (VerificationInOrderFailure error) {
inOrder.verify(firstSessionCallbacks).onValidatePrinters(priorityList);
}
// The system selects the highest ranked historical printer.
inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
firstPrinterId);
// We canceled print so the first should not be tracked.
inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
firstPrinterId);
// Discovery is always stopped before the session is always destroyed.
inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
// ...last the session is destroyed.
inOrder.verify(firstSessionCallbacks).onDestroy();
}
@Test
public void addRemovePrinters() throws Throwable {
StubbablePrinterDiscoverySession[] session = new StubbablePrinterDiscoverySession[1];
// Create the session callbacks that we will be checking.
final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
createMockPrinterDiscoverySessionCallbacks(invocation -> {
session[0] = ((PrinterDiscoverySessionCallbacks)
invocation.getMock()).getSession();
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(createSecondMockPrintServiceCallbacks());
print(createDefaultPrintDocumentAdapter(1));
waitForPrinterDiscoverySessionCreateCallbackCalled();
runOnMainThread(() -> assertEquals(0, session[0].getPrinters().size()));
PrinterId[] printerIds = new PrinterId[3];
runOnMainThread(() -> {
printerIds[0] = session[0].getService().generatePrinterId("0");
printerIds[1] = session[0].getService().generatePrinterId("1");
printerIds[2] = session[0].getService().generatePrinterId("2");
});
PrinterInfo printer1 = (new PrinterInfo.Builder(printerIds[0], "0",
PrinterInfo.STATUS_IDLE)).build();
PrinterInfo printer2 = (new PrinterInfo.Builder(printerIds[1], "1",
PrinterInfo.STATUS_IDLE)).build();
PrinterInfo printer3 = (new PrinterInfo.Builder(printerIds[2], "2",
PrinterInfo.STATUS_IDLE)).build();
ArrayList<PrinterInfo> printers = new ArrayList<>();
printers.add(printer1);
runOnMainThread(() -> session[0].addPrinters(printers));
eventually(() -> runOnMainThread(() -> assertEquals(1, session[0].getPrinters().size())));
printers.add(printer2);
printers.add(printer3);
runOnMainThread(() -> session[0].addPrinters(printers));
eventually(() -> runOnMainThread(() -> assertEquals(3, session[0].getPrinters().size())));
ArrayList<PrinterId> printerIdsToRemove = new ArrayList<>();
printerIdsToRemove.add(printer1.getId());
runOnMainThread(() -> session[0].removePrinters(printerIdsToRemove));
eventually(() -> runOnMainThread(() -> assertEquals(2, session[0].getPrinters().size())));
printerIdsToRemove.add(printer2.getId());
printerIdsToRemove.add(printer3.getId());
runOnMainThread(() -> session[0].removePrinters(printerIdsToRemove));
eventually(() -> runOnMainThread(() -> assertEquals(0, session[0].getPrinters().size())));
getUiDevice().pressBack();
waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
}
private PrinterId getAddedPrinterIdForLocalId(String printerLocalId) throws Throwable {
final List<PrinterInfo> reportedPrinters = new ArrayList<>();
runOnMainThread(() -> {
// Grab the printer ids as only the service can create such.
reportedPrinters.addAll(sSession.getPrinters());
});
final int reportedPrinterCount = reportedPrinters.size();
for (int i = 0; i < reportedPrinterCount; i++) {
PrinterInfo reportedPrinter = reportedPrinters.get(i);
String localId = reportedPrinter.getId().getLocalId();
if (printerLocalId.equals(localId)) {
return reportedPrinter.getId();
}
}
return null;
}
private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
return createMockPrintServiceCallbacks(null, null, null);
}
private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
return createMockPrinterDiscoverySessionCallbacks(invocation -> {
// Get the session.
sSession = ((PrinterDiscoverySessionCallbacks)
invocation.getMock()).getSession();
assertTrue(sSession.isPrinterDiscoveryStarted());
addPrinter(FIRST_PRINTER_LOCAL_ID, false);
addPrinter(SECOND_PRINTER_LOCAL_ID, false);
return null;
}, invocation -> {
assertFalse(sSession.isPrinterDiscoveryStarted());
return null;
}, null, invocation -> {
// Get the session.
StubbablePrinterDiscoverySession session = ((PrinterDiscoverySessionCallbacks)
invocation.getMock()).getSession();
PrinterId trackedPrinterId = (PrinterId) invocation.getArguments()[0];
List<PrinterInfo> reportedPrinters = session.getPrinters();
// We should be tracking a printer that we added.
PrinterInfo trackedPrinter = null;
final int reportedPrinterCount = reportedPrinters.size();
for (int i = 0; i < reportedPrinterCount; i++) {
PrinterInfo reportedPrinter = reportedPrinters.get(i);
if (reportedPrinter.getId().equals(trackedPrinterId)) {
trackedPrinter = reportedPrinter;
break;
}
}
assertNotNull("Can track only added printers", trackedPrinter);
assertTrue(sSession.getTrackedPrinters().contains(trackedPrinter.getId()));
assertEquals(1, sSession.getTrackedPrinters().size());
// If the printer does not have capabilities reported add them.
if (trackedPrinter.getCapabilities() == null) {
// Add the capabilities to emulate lazy discovery.
// Same for each printer is fine for what we test.
PrinterCapabilitiesInfo capabilities =
new PrinterCapabilitiesInfo.Builder(trackedPrinterId)
.setMinMargins(new Margins(200, 200, 200, 200))
.addMediaSize(MediaSize.ISO_A4, 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 updatedPrinter = new PrinterInfo.Builder(trackedPrinter)
.setCapabilities(capabilities)
.build();
// Update the printer.
List<PrinterInfo> printers = new ArrayList<>();
printers.add(updatedPrinter);
session.addPrinters(printers);
}
return null;
}, null, null, invocation -> {
assertTrue(sSession.isDestroyed());
// Take a note onDestroy was called.
onPrinterDiscoverySessionDestroyCalled();
return null;
});
}
}