• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.print.cts;
18 
19 import static android.print.test.Utils.assertException;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23 
24 import android.os.ParcelFileDescriptor;
25 import android.platform.test.annotations.Presubmit;
26 import android.print.PageRange;
27 import android.print.PrintAttributes;
28 import android.print.PrintAttributes.Margins;
29 import android.print.PrintAttributes.MediaSize;
30 import android.print.PrintAttributes.Resolution;
31 import android.print.PrintDocumentAdapter;
32 import android.print.PrintDocumentAdapter.LayoutResultCallback;
33 import android.print.PrintDocumentAdapter.WriteResultCallback;
34 import android.print.PrintDocumentInfo;
35 import android.print.PrinterCapabilitiesInfo;
36 import android.print.PrinterId;
37 import android.print.PrinterInfo;
38 import android.print.test.BasePrintTest;
39 import android.print.test.services.FirstPrintService;
40 import android.print.test.services.PrintServiceCallbacks;
41 import android.print.test.services.PrinterDiscoverySessionCallbacks;
42 import android.print.test.services.SecondPrintService;
43 import android.print.test.services.StubbablePrinterDiscoverySession;
44 
45 import androidx.test.runner.AndroidJUnit4;
46 
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 
50 import java.util.ArrayList;
51 import java.util.function.Consumer;
52 import java.util.function.Function;
53 
54 /**
55  * This test verifies changes to the printer capabilities are applied correctly.
56  */
57 @Presubmit
58 @RunWith(AndroidJUnit4.class)
59 public class PrinterCapabilitiesTest extends BasePrintTest {
60     private static final String PRINTER_NAME = "Test printer";
61 
62     private static final Margins DEFAULT_MARGINS = new Margins(0, 0, 0, 0);
63     private static final PrintAttributes.Resolution RESOLUTION_300 =
64             new PrintAttributes.Resolution("300", "300", 300, 300);
65     private static final PrintAttributes.Resolution RESOLUTION_600 =
66             new PrintAttributes.Resolution("600", "600", 600, 600);
67     private static boolean sDefaultPrinterBeenSet;
68 
69     /**
70      * That that you cannot create illegal PrinterCapabilityInfos.
71      *
72      * @throws Exception If anything is unexpected
73      */
74     @Test
illegalPrinterCapabilityInfos()75     public void illegalPrinterCapabilityInfos() throws Exception {
76         final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
77                 createMockPrinterDiscoverySessionCallbacks(invocation -> {
78                     StubbablePrinterDiscoverySession session =
79                             ((PrinterDiscoverySessionCallbacks)
80                                     invocation.getMock()).getSession();
81 
82                     PrinterId printerId = session.getService().generatePrinterId(PRINTER_NAME);
83 
84                     // printerId need to be set
85                     assertException(() -> new PrinterCapabilitiesInfo.Builder(null),
86                             IllegalArgumentException.class);
87 
88                     // All capability fields (beside duplex) need to be initialized:
89                     // Test no color
90                     assertException(() ->
91                                     (new PrinterCapabilitiesInfo.Builder(printerId))
92                                             .setMinMargins(DEFAULT_MARGINS)
93                                             .addMediaSize(MediaSize.ISO_A4, true)
94                                             .addResolution(RESOLUTION_300, true).build(),
95                             IllegalStateException.class);
96                     // Test bad colors
97                     assertException(() ->
98                                     (new PrinterCapabilitiesInfo.Builder(printerId))
99                                             .setColorModes(0xffff,
100                                                     PrintAttributes.COLOR_MODE_MONOCHROME),
101                             IllegalArgumentException.class);
102                     // Test bad duplex mode
103                     assertException(() ->
104                                     (new PrinterCapabilitiesInfo.Builder(printerId))
105                                             .setDuplexModes(0xffff,
106                                                     PrintAttributes.DUPLEX_MODE_NONE),
107                             IllegalArgumentException.class);
108                     // Test no mediasize
109                     assertException(() ->
110                                     (new PrinterCapabilitiesInfo.Builder(printerId))
111                                             .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
112                                                     PrintAttributes.COLOR_MODE_COLOR)
113                                             .setMinMargins(DEFAULT_MARGINS)
114                                             .addResolution(RESOLUTION_300, true).build(),
115                             IllegalStateException.class);
116                     // Test no default mediasize
117                     assertException(() ->
118                                     (new PrinterCapabilitiesInfo.Builder(printerId))
119                                             .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
120                                                     PrintAttributes.COLOR_MODE_COLOR)
121                                             .setMinMargins(DEFAULT_MARGINS)
122                                             .addMediaSize(MediaSize.ISO_A4, false)
123                                             .addResolution(RESOLUTION_300, true).build(),
124                             IllegalStateException.class);
125                     // Test two default mediasizes
126                     assertException(() ->
127                                     (new PrinterCapabilitiesInfo.Builder(printerId))
128                                             .addMediaSize(MediaSize.ISO_A4, true)
129                                             .addMediaSize(MediaSize.ISO_A5, true),
130                             IllegalArgumentException.class);
131                     // Test no resolution
132                     assertException(() ->
133                                     (new PrinterCapabilitiesInfo.Builder(printerId))
134                                             .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
135                                                     PrintAttributes.COLOR_MODE_COLOR)
136                                             .setMinMargins(DEFAULT_MARGINS)
137                                             .addMediaSize(MediaSize.ISO_A4, true).build(),
138                             IllegalStateException.class);
139                     // Test no default resolution
140                     assertException(() ->
141                                     (new PrinterCapabilitiesInfo.Builder(printerId))
142                                             .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
143                                                     PrintAttributes.COLOR_MODE_COLOR)
144                                             .setMinMargins(DEFAULT_MARGINS)
145                                             .addMediaSize(MediaSize.ISO_A4, true)
146                                             .addResolution(RESOLUTION_300, false).build(),
147                             IllegalStateException.class);
148                     // Test two default resolutions
149                     assertException(() ->
150                                     (new PrinterCapabilitiesInfo.Builder(printerId))
151                                             .addResolution(RESOLUTION_300, true)
152                                             .addResolution(RESOLUTION_600, true),
153                             IllegalArgumentException.class);
154 
155                     onPrinterDiscoverySessionCreateCalled();
156                     return null;
157                 }, null, null, null, null, null, invocation -> {
158                     onPrinterDiscoverySessionDestroyCalled();
159                     return null;
160                 });
161 
162         // Create the service callbacks for the first print service.
163         PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
164                 invocation -> firstSessionCallbacks, null, null);
165 
166         // Configure the print services.
167         FirstPrintService.setCallbacks(firstServiceCallbacks);
168         SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
169 
170         PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(null, null, null);
171 
172         // Start printing.
173         print(adapter);
174 
175         waitForPrinterDiscoverySessionCreateCallbackCalled();
176 
177         getActivity().finish();
178 
179         waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
180     }
181 
182     /**
183      * That that you can use all sane legal PrinterCapabilityInfos.
184      *
185      * @throws Exception If anything is unexpected
186      */
187     @Test
sanePrinterCapabilityInfos()188     public void sanePrinterCapabilityInfos() throws Exception {
189         final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
190                 createMockPrinterDiscoverySessionCallbacks(invocation -> {
191                     StubbablePrinterDiscoverySession session =
192                             ((PrinterDiscoverySessionCallbacks)
193                                     invocation.getMock()).getSession();
194 
195                     MediaSize[] mediaSizes = {MediaSize.ISO_A0, MediaSize.ISO_A0,
196                             MediaSize.ISO_A1};
197                     Resolution[] resolutions = {RESOLUTION_300, RESOLUTION_300,
198                             RESOLUTION_600};
199                     int[] colorModes = {PrintAttributes.COLOR_MODE_MONOCHROME,
200                             PrintAttributes.COLOR_MODE_COLOR};
201                     int[] duplexModes = {PrintAttributes.DUPLEX_MODE_NONE,
202                             PrintAttributes.DUPLEX_MODE_LONG_EDGE,
203                             PrintAttributes.DUPLEX_MODE_SHORT_EDGE};
204 
205                     ArrayList<PrinterInfo> printers = new ArrayList<>();
206                     for (int mediaSizeIndex = 1; mediaSizeIndex < mediaSizes.length;
207                          mediaSizeIndex++) {
208                         for (int resolutionIndex = 1; resolutionIndex < mediaSizes.length;
209                              resolutionIndex++) {
210                             for (int colorIndex = 1; colorIndex < colorModes.length;
211                                  colorIndex++) {
212                                 for (int duplexIndex = 1; duplexIndex < duplexModes.length;
213                                      duplexIndex++) {
214                                     PrinterId printerId = session.getService()
215                                             .generatePrinterId(Integer.valueOf(printers.size())
216                                                     .toString());
217 
218                                     // Setup capabilities
219                                     PrinterCapabilitiesInfo.Builder b =
220                                             new PrinterCapabilitiesInfo.Builder(printerId);
221 
222                                     for (int i = 0; i < mediaSizeIndex; i++) {
223                                         b.addMediaSize(mediaSizes[i], i == mediaSizeIndex - 1);
224                                     }
225 
226                                     for (int i = 0; i < resolutionIndex; i++) {
227                                         b.addResolution(resolutions[i],
228                                                 i == resolutionIndex - 1);
229                                     }
230 
231                                     int allColors = 0;
232                                     for (int i = 0; i < colorIndex; i++) {
233                                         allColors |= colorModes[i];
234                                     }
235                                     b.setColorModes(allColors, colorModes[colorIndex - 1]);
236 
237                                     int allDuplexModes = 0;
238                                     for (int i = 0; i < duplexIndex; i++) {
239                                         allDuplexModes |= duplexModes[i];
240                                     }
241                                     b.setDuplexModes(allDuplexModes,
242                                             duplexModes[duplexIndex - 1]);
243 
244                                     b.setMinMargins(DEFAULT_MARGINS);
245 
246                                     // Create printer
247                                     PrinterInfo printer = (new PrinterInfo.Builder(printerId,
248                                             Integer.valueOf(printers.size()).toString(),
249                                             PrinterInfo.STATUS_IDLE)).setCapabilities(b.build())
250                                             .build();
251 
252                                     // Verify capabilities
253                                     PrinterCapabilitiesInfo cap = printer.getCapabilities();
254 
255                                     assertEquals(mediaSizeIndex, cap.getMediaSizes().size());
256                                     assertEquals(mediaSizes[mediaSizeIndex - 1],
257                                             cap.getDefaults().getMediaSize());
258                                     for (int i = 0; i < mediaSizeIndex; i++) {
259                                         assertTrue(cap.getMediaSizes().contains(mediaSizes[i]));
260                                     }
261 
262                                     assertEquals(resolutionIndex, cap.getResolutions().size());
263                                     assertEquals(resolutions[resolutionIndex - 1],
264                                             cap.getDefaults().getResolution());
265                                     for (int i = 0; i < resolutionIndex; i++) {
266                                         assertTrue(cap.getResolutions().contains(resolutions[i]));
267                                     }
268 
269                                     assertEquals(allColors, cap.getColorModes());
270                                     assertEquals(colorModes[colorIndex - 1],
271                                             cap.getDefaults().getColorMode());
272 
273                                     assertEquals(allDuplexModes, cap.getDuplexModes());
274                                     assertEquals(duplexModes[duplexIndex - 1],
275                                             cap.getDefaults().getDuplexMode());
276 
277                                     assertEquals(DEFAULT_MARGINS, cap.getMinMargins());
278 
279                                     // Add printer
280                                     printers.add(printer);
281                                 }
282                             }
283                         }
284                     }
285 
286                     session.addPrinters(printers);
287 
288                     onPrinterDiscoverySessionCreateCalled();
289                     return null;
290                 }, null, null, null, null, null, invocation -> {
291                     onPrinterDiscoverySessionDestroyCalled();
292                     return null;
293                 });
294 
295         // Create the service callbacks for the first print service.
296         PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
297                 invocation -> firstSessionCallbacks, null, null);
298 
299         // Configure the print services.
300         FirstPrintService.setCallbacks(firstServiceCallbacks);
301         SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
302 
303         PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(null, null, null);
304 
305         // Start printing.
306         print(adapter);
307 
308         waitForPrinterDiscoverySessionCreateCallbackCalled();
309 
310         mPrintHelper.cancelPrinting();
311 
312         waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
313     }
314 
315     /**
316      * Base test that performs a print operation with a give PrinterCapabilityInfo and run a test
317      * function before finishing.
318      *
319      * @throws Exception
320      */
testPrinterCapabilityInfo(final Function<PrinterId, PrinterCapabilitiesInfo> capBuilder, Consumer<PrintAttributes> test)321     private void testPrinterCapabilityInfo(final Function<PrinterId, PrinterCapabilitiesInfo>
322             capBuilder, Consumer<PrintAttributes> test) throws Exception {
323         final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
324                 createMockPrinterDiscoverySessionCallbacks(invocation -> {
325                     StubbablePrinterDiscoverySession session =
326                             ((PrinterDiscoverySessionCallbacks)
327                                     invocation.getMock()).getSession();
328 
329                     PrinterId printerId = session.getService()
330                             .generatePrinterId(PRINTER_NAME);
331 
332                     ArrayList<PrinterInfo> printers = new ArrayList<>();
333                     printers.add((new PrinterInfo.Builder(printerId, PRINTER_NAME,
334                             PrinterInfo.STATUS_IDLE))
335                             .setCapabilities(capBuilder.apply(printerId)).build());
336 
337                     session.addPrinters(printers);
338 
339                     onPrinterDiscoverySessionCreateCalled();
340                     return null;
341                 }, null, null, null, null, null, invocation -> {
342                     onPrinterDiscoverySessionDestroyCalled();
343                     return null;
344                 });
345 
346         // Create the service callbacks for the first print service.
347         PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
348                 invocation -> firstSessionCallbacks, null, null);
349 
350         // Configure the print services.
351         FirstPrintService.setCallbacks(firstServiceCallbacks);
352         SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
353 
354         final PrintAttributes[] layoutAttributes = new PrintAttributes[1];
355 
356         PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
357                 invocation -> {
358                     LayoutResultCallback callback = (LayoutResultCallback) invocation
359                             .getArguments()[3];
360                     PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
361                             .setPageCount(1)
362                             .build();
363                     layoutAttributes[0] = (PrintAttributes) invocation.getArguments()[1];
364 
365                     callback.onLayoutFinished(info, true);
366                     return null;
367                 },
368                 invocation -> {
369                     Object[] args = invocation.getArguments();
370                     PageRange[] pages = (PageRange[]) args[0];
371                     ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
372                     WriteResultCallback callback = (WriteResultCallback) args[3];
373 
374                     writeBlankPages(layoutAttributes[0], fd, pages[0].getStart(),
375                             pages[0].getEnd());
376                     fd.close();
377 
378                     callback.onWriteFinished(pages);
379                     return null;
380                 }, null);
381 
382         // Start printing.
383         print(adapter);
384 
385         // make sure that options does not crash
386         openPrintOptions();
387 
388         if (!sDefaultPrinterBeenSet) {
389             // Select printer under test
390             selectPrinter(PRINTER_NAME);
391         }
392 
393         mPrintHelper.submitPrintJob();
394 
395         if (!sDefaultPrinterBeenSet) {
396             answerPrintServicesWarning(true);
397             sDefaultPrinterBeenSet = true;
398         }
399 
400         test.accept(layoutAttributes[0]);
401 
402         waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
403     }
404 
405     /**
406      * That that you use a default color that is not in the allowed colors. This is allowed because
407      * of historical reasons.
408      *
409      * @throws Exception If anything is unexpected
410      */
411     @Test
invalidDefaultColor()412     public void invalidDefaultColor() throws Exception {
413         testPrinterCapabilityInfo(
414                 (printerId) -> (new PrinterCapabilitiesInfo.Builder(printerId))
415                         .addMediaSize(MediaSize.ISO_A4, true)
416                         .addResolution(RESOLUTION_300, true)
417                         .setColorModes(PrintAttributes.COLOR_MODE_MONOCHROME,
418                                 PrintAttributes.COLOR_MODE_COLOR).build(),
419                 (layoutAttributes) -> assertEquals(layoutAttributes.getColorMode(),
420                         PrintAttributes.COLOR_MODE_MONOCHROME));
421     }
422 
423     /**
424      * That that you use a default duplex mode that is not in the allowed duplex modes. This is
425      * allowed because of historical reasons.
426      *
427      * @throws Exception If anything is unexpected
428      */
429     @Test
invalidDefaultDuplexMode()430     public void invalidDefaultDuplexMode() throws Exception {
431         testPrinterCapabilityInfo(
432                 (printerId) -> (new PrinterCapabilitiesInfo.Builder(printerId))
433                         .addMediaSize(MediaSize.ISO_A4, true)
434                         .addResolution(RESOLUTION_300, true)
435                         .setColorModes(PrintAttributes.COLOR_MODE_MONOCHROME,
436                                 PrintAttributes.COLOR_MODE_MONOCHROME)
437                         .setDuplexModes(PrintAttributes.DUPLEX_MODE_LONG_EDGE
438                                 | PrintAttributes.DUPLEX_MODE_NONE,
439                                 PrintAttributes.DUPLEX_MODE_SHORT_EDGE).build(),
440                 (layoutAttributes) -> assertTrue(layoutAttributes.getDuplexMode() ==
441                         PrintAttributes.DUPLEX_MODE_LONG_EDGE || layoutAttributes.getDuplexMode() ==
442                         PrintAttributes.DUPLEX_MODE_NONE));
443     }
444 }
445