Home | History | Annotate | Download | only in cts
      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 android.app.Activity;
     20 import android.app.PendingIntent;
     21 import android.content.Intent;
     22 import android.print.PrintAttributes;
     23 import android.print.PrintAttributes.Margins;
     24 import android.print.PrintAttributes.MediaSize;
     25 import android.print.PrintAttributes.Resolution;
     26 import android.print.PrintDocumentAdapter;
     27 import android.print.PrinterCapabilitiesInfo;
     28 import android.print.PrinterId;
     29 import android.print.PrinterInfo;
     30 import android.print.test.BasePrintTest;
     31 import android.print.test.services.FirstPrintService;
     32 import android.print.test.services.PrintServiceCallbacks;
     33 import android.print.test.services.PrinterDiscoverySessionCallbacks;
     34 import android.print.test.services.SecondPrintService;
     35 import android.print.test.services.StubbablePrinterDiscoverySession;
     36 import android.support.test.uiautomator.UiObject;
     37 import android.support.test.uiautomator.UiSelector;
     38 import android.text.TextUtils;
     39 
     40 import androidx.test.runner.AndroidJUnit4;
     41 
     42 import org.junit.Test;
     43 import org.junit.runner.RunWith;
     44 
     45 import java.util.ArrayList;
     46 import java.util.List;
     47 
     48 /**
     49  * Tests all allowed types of printerInfo
     50  */
     51 @RunWith(AndroidJUnit4.class)
     52 public class PrinterInfoTest extends BasePrintTest {
     53     private static final String NAMED_PRINTERS_NAME_PREFIX = "Printer ";
     54 
     55     /** The printer discovery session used in this test */
     56     private static StubbablePrinterDiscoverySession sDiscoverySession;
     57 
     58     private boolean isValidStatus(int status) {
     59         return status == PrinterInfo.STATUS_IDLE
     60                 || status == PrinterInfo.STATUS_BUSY
     61                 || status == PrinterInfo.STATUS_UNAVAILABLE;
     62     }
     63 
     64     /**
     65      * Create a mock {@link PrinterDiscoverySessionCallbacks} that discovers a printers with all
     66      * possible combinations of interesting printers.
     67      *
     68      * @return The mock session callbacks
     69      */
     70     private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
     71         return createMockPrinterDiscoverySessionCallbacks(invocation -> {
     72             // Get the session.
     73             sDiscoverySession = ((PrinterDiscoverySessionCallbacks) invocation.getMock())
     74                     .getSession();
     75 
     76             if (sDiscoverySession.getPrinters().isEmpty()) {
     77                 final int INVALID_RES_ID = 0xffffffff;
     78 
     79                 final PrinterInfo.Builder badPrinter = new PrinterInfo.Builder(
     80                         sDiscoverySession.getService().generatePrinterId("bad printer"),
     81                         "badPrinter", PrinterInfo.STATUS_UNAVAILABLE);
     82 
     83                 String[] localPrinterIds = {
     84                         "Printer", null
     85                 };
     86 
     87                 String[] names = {
     88                         NAMED_PRINTERS_NAME_PREFIX, "", null
     89                 };
     90                 int[] statusList = {
     91                         PrinterInfo.STATUS_IDLE, PrinterInfo.STATUS_BUSY,
     92                         PrinterInfo.STATUS_UNAVAILABLE, 0, 42
     93                 };
     94                 int[] iconResourceIds = {
     95                         R.drawable.red_printer, 0, INVALID_RES_ID, -1
     96                 };
     97 
     98                 boolean[] hasCustomPrinterIcons = {
     99                         true, false
    100                 };
    101 
    102                 String[] descriptions = {
    103                         "Description", "", null
    104                 };
    105 
    106                 PendingIntent[] infoIntents = {
    107                         PendingIntent.getActivity(getActivity(), 0,
    108                                 new Intent(getActivity(), Activity.class),
    109                                 PendingIntent.FLAG_IMMUTABLE),
    110                         null
    111                 };
    112 
    113                 PrinterCapabilitiesInfo[] capabilityList = {
    114                         // The printerId not used in PrinterCapabilitiesInfo
    115                         new PrinterCapabilitiesInfo.Builder(sDiscoverySession.getService()
    116                                 .generatePrinterId("unused"))
    117                                         .setMinMargins(new Margins(200, 200, 200, 200))
    118                                         .addMediaSize(MediaSize.ISO_A4, true)
    119                                         .addResolution(
    120                                                 new Resolution("300x300", "300x300", 300, 300),
    121                                                 true)
    122                                         .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
    123                                                 PrintAttributes.COLOR_MODE_COLOR)
    124                                         .build(),
    125                         null
    126                 };
    127 
    128                 List<PrinterInfo> printers = new ArrayList<>();
    129                 for (String localPrinterId : localPrinterIds) {
    130                     for (String name : names) {
    131                         for (int status : statusList) {
    132                             for (int iconResourceId : iconResourceIds) {
    133                                 for (boolean hasCustomPrinterIcon : hasCustomPrinterIcons) {
    134                                     for (String description : descriptions) {
    135                                         for (PendingIntent infoIntent : infoIntents) {
    136                                             for (PrinterCapabilitiesInfo capabilities
    137                                                     : capabilityList) {
    138                                                 // printerId
    139                                                 RuntimeException e = null;
    140                                                 PrinterId printerId = null;
    141                                                 try {
    142                                                     if (localPrinterId == null) {
    143                                                         printerId = sDiscoverySession
    144                                                                 .getService()
    145                                                                 .generatePrinterId(
    146                                                                         localPrinterId);
    147                                                     } else {
    148                                                         printerId = sDiscoverySession
    149                                                                 .getService()
    150                                                                 .generatePrinterId(
    151                                                                         localPrinterId
    152                                                                                 + printers
    153                                                                                         .size());
    154                                                     }
    155                                                 } catch (RuntimeException ex) {
    156                                                     e = ex;
    157                                                 }
    158 
    159                                                 // Expect exception if localId is null
    160                                                 if (localPrinterId == null) {
    161                                                     if (e == null) {
    162                                                         throw new IllegalStateException();
    163                                                     }
    164                                                 } else if (e != null) {
    165                                                     throw e;
    166                                                 }
    167 
    168                                                 // Constructor
    169                                                 PrinterInfo.Builder b = null;
    170                                                 e = null;
    171                                                 try {
    172                                                     b = new PrinterInfo.Builder(
    173                                                             printerId, name, status);
    174                                                 } catch (RuntimeException ex) {
    175                                                     e = ex;
    176                                                 }
    177 
    178                                                 // Expect exception if any of the parameters was
    179                                                 // bad
    180                                                 if (printerId == null
    181                                                         || TextUtils.isEmpty(name)
    182                                                         || !isValidStatus(status)) {
    183                                                     if (e == null) {
    184                                                         throw new IllegalStateException();
    185                                                     } else {
    186                                                         b = badPrinter;
    187                                                     }
    188                                                 } else if (e != null) {
    189                                                     throw e;
    190                                                 }
    191 
    192                                                 // IconResourceId
    193                                                 e = null;
    194                                                 try {
    195                                                     b.setIconResourceId(iconResourceId);
    196                                                 } catch (RuntimeException ex) {
    197                                                     e = ex;
    198                                                 }
    199 
    200                                                 // Expect exception if iconResourceId was bad
    201                                                 // We do allow invalid Ids as the printerInfo
    202                                                 // might be created after the package of the
    203                                                 // printer is already gone if the printer is a
    204                                                 // historical printer.
    205                                                 if (iconResourceId < 0) {
    206                                                     if (e == null) {
    207                                                         throw new IllegalStateException();
    208                                                     } else {
    209                                                         b = badPrinter;
    210                                                     }
    211                                                 } else if (e != null) {
    212                                                     throw e;
    213                                                 }
    214 
    215                                                 // Status
    216                                                 e = null;
    217                                                 try {
    218                                                     b.setStatus(status);
    219                                                 } catch (RuntimeException ex) {
    220                                                     e = ex;
    221                                                 }
    222 
    223                                                 // Expect exception is status is not valid
    224                                                 if (!isValidStatus(status)) {
    225                                                     if (e == null) {
    226                                                         throw new IllegalStateException();
    227                                                     } else {
    228                                                         b = badPrinter;
    229                                                     }
    230                                                 } else if (e != null) {
    231                                                     throw e;
    232                                                 }
    233 
    234                                                 // Name
    235                                                 e = null;
    236                                                 try {
    237                                                     b.setName(name);
    238                                                 } catch (RuntimeException ex) {
    239                                                     e = ex;
    240                                                 }
    241 
    242                                                 // Expect exception if name is empty
    243                                                 if (TextUtils.isEmpty(name)) {
    244                                                     if (e == null) {
    245                                                         throw new IllegalStateException();
    246                                                     } else {
    247                                                         b = badPrinter;
    248                                                     }
    249                                                 } else if (e != null) {
    250                                                     throw e;
    251                                                 }
    252 
    253                                                 // hasCustomPrinterIcon
    254                                                 b.setHasCustomPrinterIcon(hasCustomPrinterIcon);
    255 
    256                                                 // Description
    257                                                 b.setDescription(description);
    258 
    259                                                 // InfoIntent
    260                                                 b.setInfoIntent(infoIntent);
    261 
    262                                                 // Capabilities
    263                                                 b.setCapabilities(capabilities);
    264 
    265                                                 PrinterInfo printer = b.build();
    266 
    267                                                 // Don't create bad printers
    268                                                 if (b == badPrinter) {
    269                                                     continue;
    270                                                 }
    271 
    272                                                 // Verify get* methods
    273                                                 if (printer.getId() != printerId
    274                                                         || printer.getName() != name
    275                                                         || printer.getStatus() != status
    276                                                         || printer
    277                                                                 .getDescription() != description
    278                                                         || printer.getCapabilities()
    279                                                                 != capabilities) {
    280                                                     throw new IllegalStateException();
    281                                                 }
    282 
    283                                                 printers.add(printer);
    284                                             }
    285                                         }
    286                                     }
    287                                 }
    288                             }
    289                         }
    290                     }
    291                 }
    292 
    293                 sDiscoverySession.addPrinters(printers);
    294             }
    295             return null;
    296         }, null, null, invocation -> null, invocation -> null, null, invocation -> {
    297             // Take a note onDestroy was called.
    298             onPrinterDiscoverySessionDestroyCalled();
    299             return null;
    300         });
    301     }
    302 
    303     /**
    304      * Create mock service callback for a session.
    305      *
    306      * @param sessionCallbacks The callbacks of the session
    307      */
    308     private PrintServiceCallbacks createFirstMockPrinterServiceCallbacks(
    309             final PrinterDiscoverySessionCallbacks sessionCallbacks) {
    310         return createMockPrintServiceCallbacks(
    311                 invocation -> sessionCallbacks,
    312                 null, null);
    313     }
    314 
    315     /**
    316      * Test that all printInfos possible can be used and that invalid printInfos throw exceptions.
    317      *
    318      * @throws Exception If anything is unexpected.
    319      */
    320     @Test
    321     public void printerInfos() throws Exception {
    322         // Create the session of the printers that we will be checking.
    323         PrinterDiscoverySessionCallbacks sessionCallbacks
    324                 = createFirstMockPrinterDiscoverySessionCallbacks();
    325 
    326         // Create the service callbacks for the first print service.
    327         PrintServiceCallbacks serviceCallbacks = createFirstMockPrinterServiceCallbacks(
    328                 sessionCallbacks);
    329 
    330         // Configure the print services.
    331         FirstPrintService.setCallbacks(serviceCallbacks);
    332 
    333         // We don't use the second service, but we have to still configure it
    334         SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));
    335 
    336         // Create a print adapter that respects the print contract.
    337         PrintDocumentAdapter adapter = createDefaultPrintDocumentAdapter(1);
    338 
    339         // Start printing.
    340         print(adapter);
    341 
    342         // Wait for write of the first page.
    343         waitForWriteAdapterCallback(1);
    344 
    345         // Open destination spinner
    346         UiObject destinationSpinner = getUiDevice().findObject(new UiSelector().resourceId(
    347                 "com.android.printspooler:id/destination_spinner"));
    348         destinationSpinner.click();
    349 
    350         // Wait until spinner is opened
    351         getUiDevice().waitForIdle();
    352 
    353         // Exit print spooler
    354         getUiDevice().pressBack();
    355         getUiDevice().pressBack();
    356         getUiDevice().pressBack();
    357     }
    358 }
    359