Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8b3e3d1 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge "When selected printer can't print show error"

parents f1ac71db 86090a11
Loading
Loading
Loading
Loading
+148 −85
Original line number Diff line number Diff line
@@ -27,27 +27,33 @@ import android.print.mockservice.PrinterDiscoverySessionCallbacks;
import android.print.mockservice.StubbablePrinterDiscoverySession;
import android.print.pdf.PrintedPdfDocument;
import android.support.test.filters.LargeTest;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.Log;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
 * Tests for the basic printing workflows
 */
@RunWith(Parameterized.class)
public class WorkflowTest extends BasePrintTest {
    private static final String LOG_TAG = WorkflowTest.class.getSimpleName();

@@ -55,6 +61,17 @@ public class WorkflowTest extends BasePrintTest {
    private static float sTransitionAnimationScaleBefore;
    private static float sAnimatiorDurationScaleBefore;

    private PrintAttributes.MediaSize mFirst;
    private boolean mSelectPrinter;
    private PrintAttributes.MediaSize mSecond;

    public WorkflowTest(PrintAttributes.MediaSize first, boolean selectPrinter,
            PrintAttributes.MediaSize second) {
        mFirst = first;
        mSelectPrinter = selectPrinter;
        mSecond = second;
    }

    interface InterruptableConsumer<T> {
        void accept(T t) throws InterruptedException;
    }
@@ -155,6 +172,8 @@ public class WorkflowTest extends BasePrintTest {
        PrinterCapabilitiesInfo.Builder builder =
                new PrinterCapabilitiesInfo.Builder(printerId);

        PrinterInfo printerInfo;
        if (mediaSize != null) {
            builder.setMinMargins(new PrintAttributes.Margins(0, 0, 0, 0))
                    .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
                            PrintAttributes.COLOR_MODE_COLOR)
@@ -162,9 +181,14 @@ public class WorkflowTest extends BasePrintTest {
                    .addResolution(new PrintAttributes.Resolution("300x300", "300x300", 300, 300),
                            true);

        printers.add(new PrinterInfo.Builder(printerId, name,
                PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build());
            printerInfo = new PrinterInfo.Builder(printerId, name,
                    PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build();
        } else {
            printerInfo = (new PrinterInfo.Builder(printerId, name,
                    PrinterInfo.STATUS_IDLE)).build();
        }

        printers.add(printerInfo);
        session.addPrinters(printers);
    }

@@ -193,21 +217,35 @@ public class WorkflowTest extends BasePrintTest {
     *
     * @param sessionRef Where to store the reference to the session once started
     */
    private void setMockPrintServiceCallbacks(StubbablePrinterDiscoverySession[] sessionRef) {
    private void setMockPrintServiceCallbacks(StubbablePrinterDiscoverySession[] sessionRef,
            ArrayList<String> trackedPrinters, PrintAttributes.MediaSize mediaSize) {
        MockPrintService.setCallbacks(createMockPrintServiceCallbacks(
                inv -> createMockPrinterDiscoverySessionCallbacks(inv2 -> {
                            synchronized (sessionRef) {
                                sessionRef[0] = ((PrinterDiscoverySessionCallbacks) inv2.getMock())
                                        .getSession();

                                addPrinter(sessionRef[0], "1st printer",
                                        PrintAttributes.MediaSize.ISO_A0);
                                addPrinter(sessionRef[0], "1st printer", mediaSize);

                                sessionRef.notifyAll();
                            }
                            return null;
                        },
                        null, null, null, null, null, inv2 -> {
                        null, null, inv2 -> {
                            synchronized (trackedPrinters) {
                                trackedPrinters
                                        .add(((PrinterId) inv2.getArguments()[0]).getLocalId());
                                trackedPrinters.notifyAll();
                            }
                            return null;
                        }, null, inv2 -> {
                            synchronized (trackedPrinters) {
                                trackedPrinters
                                        .remove(((PrinterId) inv2.getArguments()[0]).getLocalId());
                                trackedPrinters.notifyAll();
                            }
                            return null;
                        }, inv2 -> {
                            synchronized (sessionRef) {
                                sessionRef[0] = null;
                                sessionRef.notifyAll();
@@ -271,13 +309,37 @@ public class WorkflowTest extends BasePrintTest {
        }, null);
    }

    @Parameterized.Parameters
    public static Collection<Object[]> getParameters() {
        ArrayList<Object[]> tests = new ArrayList<>();

        for (PrintAttributes.MediaSize first : new PrintAttributes.MediaSize[]{
                PrintAttributes.MediaSize.ISO_A0, null}) {
            for (Boolean selectPrinter : new Boolean[]{true, false}) {
                for (PrintAttributes.MediaSize second : new PrintAttributes.MediaSize[]{
                        PrintAttributes.MediaSize.ISO_A1, null}) {
                    // If we do not use the second printer, no need to try various options
                    if (!selectPrinter && second == null) {
                        continue;
                    }
                    tests.add(new Object[]{first, selectPrinter, second});
                }
            }
        }

        return tests;
    }

    @Test
    @LargeTest
    public void addAndSelectPrinter() throws Exception {
        final StubbablePrinterDiscoverySession session[] = new StubbablePrinterDiscoverySession[1];
        final PrintAttributes printAttributes[] = new PrintAttributes[1];
        ArrayList<String> trackedPrinters = new ArrayList<>();

        Log.i(LOG_TAG, "Running " + mFirst + " " + mSelectPrinter + " " + mSecond);

        setMockPrintServiceCallbacks(session);
        setMockPrintServiceCallbacks(session, trackedPrinters, mFirst);
        print(printAttributes);

        // We are now in the PrintActivity
@@ -288,11 +350,23 @@ public class WorkflowTest extends BasePrintTest {

        setPrinter("1st printer");

        Log.i(LOG_TAG, "Waiting for 1st printer to be tracked");
        synchronized (trackedPrinters) {
            waitWithTimeout(() -> !trackedPrinters.contains("1st printer"), trackedPrinters::wait);
        }

        if (mFirst != null) {
            Log.i(LOG_TAG, "Waiting for print attributes to change");
            synchronized (printAttributes) {
                waitWithTimeout(
                    () -> printAttributes[0] == null || !printAttributes[0].getMediaSize().equals(
                            PrintAttributes.MediaSize.ISO_A0), printAttributes::wait);
                        () -> printAttributes[0] == null ||
                                !printAttributes[0].getMediaSize().equals(
                                        mFirst), printAttributes::wait);
            }
        } else {
            Log.i(LOG_TAG, "Waiting for error message");
            assertNotNull(getUiDevice().wait(Until.findObject(
                    By.text("This printer isn't available right now.")), OPERATION_TIMEOUT));
        }

        setPrinter("All printers\u2026");
@@ -302,7 +376,7 @@ public class WorkflowTest extends BasePrintTest {

        // We are now in the AddPrinterActivity
        AddPrintersActivity.addObserver(
                () -> addPrinter(session[0], "2nd printer", PrintAttributes.MediaSize.ISO_A1));
                () -> addPrinter(session[0], "2nd printer", mSecond));

        // This executes the observer registered above
        clickOn(new UiSelector().text(MockPrintService.class.getCanonicalName())
@@ -311,74 +385,63 @@ public class WorkflowTest extends BasePrintTest {
        getUiDevice().pressBack();
        AddPrintersActivity.clearObservers();

        if (mSelectPrinter) {
            // We are now in the SelectPrinterActivity
            clickOnText("2nd printer");
        } else {
            getUiDevice().pressBack();
        }

        // We are now in the PrintActivity
        if (mSelectPrinter) {
            if (mSecond != null) {
                Log.i(LOG_TAG, "Waiting for print attributes to change");
                synchronized (printAttributes) {
                    waitWithTimeout(
                    () -> printAttributes[0] == null || !printAttributes[0].getMediaSize().equals(
                            PrintAttributes.MediaSize.ISO_A1), printAttributes::wait);
        }

        getUiDevice().pressBack();

        // We are back in the test activity
        Log.i(LOG_TAG, "Waiting for session to end");
        synchronized (session) {
            waitWithTimeout(() -> session[0] != null, session::wait);
                            () -> printAttributes[0] == null ||
                                    !printAttributes[0].getMediaSize().equals(
                                            mSecond), printAttributes::wait);
                }
            } else {
                Log.i(LOG_TAG, "Waiting for error message");
                assertNotNull(getUiDevice().wait(Until.findObject(
                        By.text("This printer isn't available right now.")), OPERATION_TIMEOUT));
            }

    @Test
    @LargeTest
    public void abortSelectingPrinter() throws Exception {
        final StubbablePrinterDiscoverySession session[] = new StubbablePrinterDiscoverySession[1];
        final PrintAttributes printAttributes[] = new PrintAttributes[1];

        setMockPrintServiceCallbacks(session);
        print(printAttributes);

        // We are now in the PrintActivity
        Log.i(LOG_TAG, "Waiting for session");
        synchronized (session) {
            waitWithTimeout(() -> session[0] == null, session::wait);
            Log.i(LOG_TAG, "Waiting for 1st printer to be not tracked");
            synchronized (trackedPrinters) {
                waitWithTimeout(() -> trackedPrinters.contains("1st printer"),
                        trackedPrinters::wait);
            }

        setPrinter("1st printer");
            Log.i(LOG_TAG, "Waiting for 2nd printer to be tracked");
            synchronized (trackedPrinters) {
                waitWithTimeout(() -> !trackedPrinters.contains("2nd printer"),
                        trackedPrinters::wait);
            }
        } else {
            Thread.sleep(100);

            if (mFirst != null) {
                Log.i(LOG_TAG, "Waiting for print attributes to change");
                synchronized (printAttributes) {
                    waitWithTimeout(
                    () -> printAttributes[0] == null || !printAttributes[0].getMediaSize().equals(
                            PrintAttributes.MediaSize.ISO_A0), printAttributes::wait);
                            () -> printAttributes[0] == null ||
                                    !printAttributes[0].getMediaSize().equals(
                                            mFirst), printAttributes::wait);
                }
            } else {
                Log.i(LOG_TAG, "Waiting for error message");
                assertNotNull(getUiDevice().wait(Until.findObject(
                        By.text("This printer isn't available right now.")), OPERATION_TIMEOUT));
            }

        setPrinter("All printers\u2026");

        // We are now in the SelectPrinterActivity
        clickOnText("Add printer");

        // We are now in the AddPrinterActivity
        AddPrintersActivity.addObserver(
                () -> addPrinter(session[0], "2nd printer", PrintAttributes.MediaSize.ISO_A1));

        // This executes the observer registered above
        clickOn(new UiSelector().text(MockPrintService.class.getCanonicalName())
                .resourceId("com.android.printspooler:id/title"));

        getUiDevice().pressBack();
        AddPrintersActivity.clearObservers();

        // Do not select a new printer, just press back
        getUiDevice().pressBack();

        // We are now in the PrintActivity
        // The media size should not change
        Log.i(LOG_TAG, "Make sure print attributes did not change");
        Thread.sleep(100);
        assertEquals(PrintAttributes.MediaSize.ISO_A0, printAttributes[0].getMediaSize());
            Log.i(LOG_TAG, "Waiting for 1st printer to be tracked");
            synchronized (trackedPrinters) {
                waitWithTimeout(() -> !trackedPrinters.contains("1st printer"),
                        trackedPrinters::wait);
            }
        }

        getUiDevice().pressBack();

+11 −6
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.print.IPrintDocumentAdapter;
import android.print.PageRange;
@@ -760,8 +759,11 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
                mPrintJob.setPrinterId(printerInfo.getId());
                mPrintJob.setPrinterName(printerInfo.getName());

                if (printerInfo.getCapabilities() != null) {
                if (canPrint(printerInfo)) {
                    updatePrintAttributesFromCapabilities(printerInfo.getCapabilities());
                    onPrinterAvailable(printerInfo);
                } else {
                    onPrinterUnavailable(printerInfo);
                }

                mDestinationSpinnerAdapter.ensurePrinterInVisibleAdapterPosition(printerInfo);
@@ -2050,7 +2052,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
    }

    public void onPrinterUnavailable(PrinterInfo printer) {
        if (mCurrentPrinter.getId().equals(printer.getId())) {
        if (mCurrentPrinter == null || mCurrentPrinter.getId().equals(printer.getId())) {
            setState(STATE_PRINTER_UNAVAILABLE);
            mPrintedDocument.cancel(false);
            ensureErrorUiShown(getString(R.string.print_error_printer_unavailable),
@@ -2309,8 +2311,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
        public int getPrinterIndex(PrinterId printerId) {
            for (int i = 0; i < getCount(); i++) {
                PrinterHolder printerHolder = (PrinterHolder) getItem(i);
                if (printerHolder != null && !printerHolder.removed
                        && printerHolder.printer.getId().equals(printerId)) {
                if (printerHolder != null && printerHolder.printer.getId().equals(printerId)) {
                    return i;
                }
            }
@@ -2539,7 +2540,11 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
                if (updatedPrinter != null) {
                    printerHolder.printer = updatedPrinter;
                    printerHolder.removed = false;
                    if (canPrint(printerHolder.printer)) {
                        onPrinterAvailable(printerHolder.printer);
                    } else {
                        onPrinterUnavailable(printerHolder.printer);
                    }
                    newPrinterHolders.add(printerHolder);
                } else if (mCurrentPrinter != null && mCurrentPrinter.getId().equals(oldPrinterId)){
                    printerHolder.removed = true;