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
17package android.print;
18
19import static android.print.test.Utils.assertException;
20
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertTrue;
23
24import android.annotation.NonNull;
25import android.content.ComponentName;
26import android.content.Context;
27import android.os.Bundle;
28import android.os.CancellationSignal;
29import android.os.Handler;
30import android.os.Looper;
31import android.os.ParcelFileDescriptor;
32import android.os.Process;
33import android.os.ServiceManager;
34import android.os.UserHandle;
35import android.print.PrintAttributes.Margins;
36import android.print.PrintAttributes.MediaSize;
37import android.print.PrintAttributes.Resolution;
38import android.print.test.BasePrintTest;
39import android.print.test.services.FirstPrintService;
40import android.print.test.services.PrintServiceCallbacks;
41import android.print.test.services.PrinterDiscoverySessionCallbacks;
42import android.print.test.services.StubbablePrinterDiscoverySession;
43import android.printservice.recommendation.IRecommendationsChangeListener;
44import android.support.test.filters.LargeTest;
45import android.support.test.filters.MediumTest;
46import android.support.test.runner.AndroidJUnit4;
47
48import org.junit.Before;
49import org.junit.Test;
50import org.junit.runner.RunWith;
51
52import java.util.ArrayList;
53import java.util.List;
54
55/**
56 * tests feeding all possible parameters to the IPrintManager Binder.
57 */
58@RunWith(AndroidJUnit4.class)
59public class IPrintManagerParametersTest extends BasePrintTest {
60
61    private final int BAD_APP_ID = 0xffffffff;
62
63    private final int mAppId;
64    private final int mUserId;
65    private final PrintJobId mBadPrintJobId;
66
67    private PrintJob mGoodPrintJob;
68    private PrinterId mGoodPrinterId;
69    private ComponentName mBadComponentName;
70
71    private IPrintManager mIPrintManager;
72
73    /**
74     * Create a new IPrintManagerParametersTest and setup basic fields.
75     */
76    public IPrintManagerParametersTest() {
77        super();
78
79        mAppId = UserHandle.getAppId(Process.myUid());
80        mUserId = UserHandle.myUserId();
81        mBadPrintJobId = new PrintJobId();
82        mBadComponentName = new ComponentName("bad", "bad");
83    }
84
85    /**
86     * Create a mock PrintDocumentAdapter.
87     *
88     * @return The adapter
89     */
90    private @NonNull PrintDocumentAdapter createMockAdapter() {
91        return new PrintDocumentAdapter() {
92            @Override
93            public void onStart() {
94                onStartCalled();
95            }
96
97            @Override
98            public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
99                    CancellationSignal cancellationSignal, LayoutResultCallback callback,
100                    Bundle extras) {
101                callback.onLayoutFailed("not implemented");
102            }
103
104            @Override
105            public void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
106                    CancellationSignal cancellationSignal, WriteResultCallback callback) {
107            }
108        };
109    }
110
111    /**
112     * Create mock print service callbacks.
113     *
114     * @return the callbacks
115     */
116    private PrintServiceCallbacks createMockCallbacks() {
117        return createMockPrintServiceCallbacks(
118                invocation -> createMockPrinterDiscoverySessionCallbacks(invocation1 -> {
119                    // Get the session.
120                    StubbablePrinterDiscoverySession session =
121                            ((PrinterDiscoverySessionCallbacks) invocation1
122                            .getMock()).getSession();
123
124                    if (session.getPrinters().isEmpty()) {
125                        final String PRINTER_NAME = "good printer";
126                        List<PrinterInfo> printers = new ArrayList<>();
127
128                        // Add the printer.
129                        mGoodPrinterId = session.getService()
130                                .generatePrinterId(PRINTER_NAME);
131
132                        PrinterCapabilitiesInfo capabilities =
133                                new PrinterCapabilitiesInfo.Builder(mGoodPrinterId)
134                                        .setMinMargins(
135                                                new Margins(200, 200, 200, 200))
136                                        .addMediaSize(MediaSize.ISO_A4, true)
137                                        .addResolution(new Resolution("300x300",
138                                                "300x300", 300, 300),
139                                                true)
140                                        .setColorModes(
141                                                PrintAttributes.COLOR_MODE_COLOR,
142                                                PrintAttributes.COLOR_MODE_COLOR)
143                                        .build();
144
145                        PrinterInfo printer = new PrinterInfo.Builder(
146                                mGoodPrinterId,
147                                PRINTER_NAME,
148                                PrinterInfo.STATUS_IDLE)
149                                        .setCapabilities(capabilities)
150                                        .build();
151                        printers.add(printer);
152
153                        session.addPrinters(printers);
154                    }
155                    onPrinterDiscoverySessionCreateCalled();
156                    return null;
157                }, null, null, null, null, null, null),
158                null, null);
159    }
160
161    /**
162     * Create a IPrintJobStateChangeListener object.
163     *
164     * @return the object
165     * @throws Exception if the object could not be created.
166     */
167    private IPrintJobStateChangeListener createMockIPrintJobStateChangeListener() throws Exception {
168        return new PrintManager.PrintJobStateChangeListenerWrapper(null,
169                new Handler(Looper.getMainLooper()));
170    }
171
172    /**
173     * Create a IPrintServicesChangeListener object.
174     *
175     * @return the object
176     * @throws Exception if the object could not be created.
177     */
178    private IPrintServicesChangeListener createMockIPrintServicesChangeListener() throws Exception {
179        return new PrintManager.PrintServicesChangeListenerWrapper(null,
180                new Handler(Looper.getMainLooper()));
181    }
182
183    /**
184     * Create a IPrintServiceRecommendationsChangeListener object.
185     *
186     * @return the object
187     * @throws Exception if the object could not be created.
188     */
189    private IRecommendationsChangeListener
190    createMockIPrintServiceRecommendationsChangeListener() throws Exception {
191        return new PrintManager.PrintServiceRecommendationsChangeListenerWrapper(null,
192                new Handler(Looper.getMainLooper()));
193    }
194
195    /**
196     * Create a IPrinterDiscoveryObserver object.
197     *
198     * @return the object
199     * @throws Exception if the object could not be created.
200     */
201    private IPrinterDiscoveryObserver createMockIPrinterDiscoveryObserver() throws Exception {
202        return new PrinterDiscoverySession.PrinterDiscoveryObserver(null);
203    }
204
205    private void startPrinting() {
206        mGoodPrintJob = print(createMockAdapter(), (PrintAttributes) null);
207
208        // Wait for PrintActivity to be ready
209        waitForAdapterStartCallbackCalled();
210
211        // Wait for printer discovery session to be ready
212        waitForPrinterDiscoverySessionCreateCallbackCalled();
213    }
214
215    private void endPrinting() {
216        getUiDevice().pressBack();
217        getUiDevice().pressBack();
218    }
219
220    /**
221     * Return a printer Id that is not from any print service
222     *
223     * @return The bad printer id.
224     */
225    private PrinterId getBadPrinterId() {
226        return new PrinterId(getActivity().getComponentName(), "dummy printer");
227    }
228
229    @Before
230    public void setUpMockService() throws Exception {
231        FirstPrintService.setCallbacks(createMockCallbacks());
232
233        mIPrintManager = IPrintManager.Stub
234                .asInterface(ServiceManager.getService(Context.PRINT_SERVICE));
235    }
236
237    /**
238     * test IPrintManager.getPrintJobInfo
239     */
240    @LargeTest
241    @Test
242    public void testGetPrintJobInfo() throws Throwable {
243        startPrinting();
244
245        assertEquals(mGoodPrintJob.getId(), mIPrintManager.getPrintJobInfo(mGoodPrintJob.getId(),
246                        mAppId, mUserId).getId());
247        assertEquals(null, mIPrintManager.getPrintJobInfo(mBadPrintJobId, mAppId, mUserId));
248        assertEquals(null, mIPrintManager.getPrintJobInfo(null, mAppId, mUserId));
249
250        assertException(
251                () -> mIPrintManager.getPrintJobInfo(mGoodPrintJob.getId(), BAD_APP_ID, mUserId),
252                SecurityException.class);
253
254        // Cannot test bad user Id as these tests are allowed to call across users
255
256        endPrinting();
257    }
258
259    /**
260     * test IPrintManager.getPrintJobInfos
261     */
262    @LargeTest
263    @Test
264    public void testGetPrintJobInfos() throws Throwable {
265        startPrinting();
266
267        List<PrintJobInfo> infos = mIPrintManager.getPrintJobInfos(mAppId, mUserId);
268
269        boolean foundPrintJob = false;
270        for (PrintJobInfo info : infos) {
271            if (info.getId().equals(mGoodPrintJob.getId())) {
272                assertEquals(PrintJobInfo.STATE_CREATED, info.getState());
273                foundPrintJob = true;
274            }
275        }
276        assertTrue(foundPrintJob);
277
278        assertException(() -> mIPrintManager.getPrintJobInfos(BAD_APP_ID, mUserId),
279                SecurityException.class);
280
281        // Cannot test bad user Id as these tests are allowed to call across users
282
283        endPrinting();
284    }
285
286    /**
287     * test IPrintManager.print
288     */
289    @LargeTest
290    @Test
291    public void testPrint() throws Throwable {
292        final String name = "dummy print job";
293
294        final IPrintDocumentAdapter adapter = new PrintManager
295                .PrintDocumentAdapterDelegate(getActivity(), createMockAdapter());
296
297        startPrinting();
298
299        assertException(() -> mIPrintManager.print(null, adapter, null,
300                getActivity().getPackageName(), mAppId, mUserId),
301                IllegalArgumentException.class);
302
303        assertException(() -> mIPrintManager.print(name, null, null,
304                getActivity().getPackageName(), mAppId, mUserId),
305                NullPointerException.class);
306
307        assertException(() -> mIPrintManager.print(name, adapter, null, null, mAppId, mUserId),
308                IllegalArgumentException.class);
309
310        assertException(() -> mIPrintManager.print(name, adapter, null,
311                mBadComponentName.getPackageName(), mAppId, mUserId),
312                IllegalArgumentException.class);
313
314        assertException(() -> mIPrintManager.print(name, adapter, null,
315                getActivity().getPackageName(), BAD_APP_ID, mUserId), SecurityException.class);
316
317        // Cannot test bad user Id as these tests are allowed to call across users
318
319        endPrinting();
320    }
321
322    /**
323     * test IPrintManager.cancelPrintJob
324     */
325    @LargeTest
326    @Test
327    public void testCancelPrintJob() throws Throwable {
328        startPrinting();
329
330        // Invalid print jobs IDs do not produce an exception
331        mIPrintManager.cancelPrintJob(mBadPrintJobId, mAppId, mUserId);
332        mIPrintManager.cancelPrintJob(null, mAppId, mUserId);
333
334        assertException(
335                () -> mIPrintManager.cancelPrintJob(mGoodPrintJob.getId(), BAD_APP_ID, mUserId),
336                SecurityException.class);
337
338        // Cannot test bad user Id as these tests are allowed to call across users
339
340        // Must be last as otherwise mGoodPrintJob will not be good anymore
341        mIPrintManager.cancelPrintJob(mGoodPrintJob.getId(), mAppId, mUserId);
342
343        endPrinting();
344    }
345
346    /**
347     * test IPrintManager.restartPrintJob
348     */
349    @LargeTest
350    @Test
351    public void testRestartPrintJob() throws Throwable {
352        startPrinting();
353
354        mIPrintManager.restartPrintJob(mGoodPrintJob.getId(), mAppId, mUserId);
355
356        // Invalid print jobs IDs do not produce an exception
357        mIPrintManager.restartPrintJob(mBadPrintJobId, mAppId, mUserId);
358        mIPrintManager.restartPrintJob(null, mAppId, mUserId);
359
360        assertException(
361                () -> mIPrintManager.restartPrintJob(mGoodPrintJob.getId(), BAD_APP_ID, mUserId),
362                SecurityException.class);
363
364        // Cannot test bad user Id as these tests are allowed to call across users
365
366        endPrinting();
367    }
368
369    /**
370     * test IPrintManager.addPrintJobStateChangeListener
371     */
372    @MediumTest
373    @Test
374    @NoActivity
375    public void testAddPrintJobStateChangeListener() throws Throwable {
376        final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
377
378        mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
379
380        assertException(() -> mIPrintManager.addPrintJobStateChangeListener(null, mAppId, mUserId),
381                NullPointerException.class);
382
383        assertException(
384                () -> mIPrintManager.addPrintJobStateChangeListener(listener, BAD_APP_ID, mUserId),
385                SecurityException.class);
386
387        // Cannot test bad user Id as these tests are allowed to call across users
388    }
389
390    /**
391     * test IPrintManager.removePrintJobStateChangeListener
392     */
393    @MediumTest
394    @Test
395    @NoActivity
396    public void testRemovePrintJobStateChangeListener() throws Throwable {
397        final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
398
399        mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
400        mIPrintManager.removePrintJobStateChangeListener(listener, mUserId);
401
402        // Removing unknown listeners is a no-op
403        mIPrintManager.removePrintJobStateChangeListener(listener, mUserId);
404
405        mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
406        assertException(() -> mIPrintManager.removePrintJobStateChangeListener(null, mUserId),
407                NullPointerException.class);
408
409        // Cannot test bad user Id as these tests are allowed to call across users
410    }
411
412    /**
413     * test IPrintManager.addPrintServicesChangeListener
414     */
415    @MediumTest
416    @Test
417    @NoActivity
418    public void testAddPrintServicesChangeListener() throws Throwable {
419        final IPrintServicesChangeListener listener = createMockIPrintServicesChangeListener();
420
421        assertException(() ->  mIPrintManager.addPrintServicesChangeListener(listener, mUserId),
422                SecurityException.class);
423
424        assertException(() -> mIPrintManager.addPrintServicesChangeListener(null, mUserId),
425                NullPointerException.class);
426
427        // Cannot test bad user Id as these tests are allowed to call across users
428    }
429
430    /**
431     * test IPrintManager.removePrintServicesChangeListener
432     */
433    @MediumTest
434    @Test
435    @NoActivity
436    public void testRemovePrintServicesChangeListener() throws Throwable {
437        final IPrintServicesChangeListener listener = createMockIPrintServicesChangeListener();
438
439        assertException(() ->  mIPrintManager.removePrintServicesChangeListener(listener, mUserId),
440                SecurityException.class);
441
442        assertException(() ->  mIPrintManager.removePrintServicesChangeListener(null, mUserId),
443                NullPointerException.class);
444    }
445
446    /**
447     * test IPrintManager.getPrintServices
448     */
449    @MediumTest
450    @Test
451    @NoActivity
452    public void testGetPrintServices() throws Throwable {
453        assertException(() -> mIPrintManager.getPrintServices(PrintManager.ALL_SERVICES, mUserId),
454                SecurityException.class);
455
456        assertException(() -> mIPrintManager.getPrintServices(0, mUserId),
457                SecurityException.class);
458
459        assertException(() -> mIPrintManager.getPrintServices(~PrintManager.ALL_SERVICES, mUserId),
460                IllegalArgumentException.class);
461
462        // Cannot test bad user Id as these tests are allowed to call across users
463    }
464
465    /**
466     * test IPrintManager.setPrintServiceEnabled
467     */
468    @MediumTest
469    @Test
470    @NoActivity
471    public void testSetPrintServiceEnabled() throws Throwable {
472        assertException(
473                () -> mIPrintManager.setPrintServiceEnabled(new ComponentName("bad", "name"), true,
474                                mUserId), SecurityException.class);
475
476        assertException(() -> mIPrintManager.setPrintServiceEnabled(null, true, mUserId),
477                SecurityException.class);
478
479        // Cannot test bad user Id as these tests are allowed to call across users
480    }
481
482    /**
483     * test IPrintManager.addPrintServiceRecommendationsChangeListener
484     */
485    @MediumTest
486    @Test
487    @NoActivity
488    public void testAddPrintServiceRecommendationsChangeListener() throws Throwable {
489        final IRecommendationsChangeListener listener =
490                createMockIPrintServiceRecommendationsChangeListener();
491
492        assertException(() -> mIPrintManager.addPrintServiceRecommendationsChangeListener(listener,
493                mUserId), SecurityException.class);
494
495        assertException(
496                () -> mIPrintManager.addPrintServiceRecommendationsChangeListener(null, mUserId),
497                NullPointerException.class);
498
499        // Cannot test bad user Id as these tests are allowed to call across users
500    }
501
502    /**
503     * test IPrintManager.removePrintServicesChangeListener
504     */
505    @MediumTest
506    @Test
507    @NoActivity
508    public void testRemovePrintServiceRecommendationsChangeListener() throws Throwable {
509        final IRecommendationsChangeListener listener =
510                createMockIPrintServiceRecommendationsChangeListener();
511
512        assertException(() -> mIPrintManager.removePrintServiceRecommendationsChangeListener(
513                listener, mUserId), SecurityException.class);
514
515        assertException(
516                () -> mIPrintManager.removePrintServiceRecommendationsChangeListener(null, mUserId),
517                NullPointerException.class);
518
519        // Cannot test bad user Id as these tests are allowed to call across users
520    }
521
522    /**
523     * test IPrintManager.getPrintServiceRecommendations
524     */
525    @MediumTest
526    @Test
527    @NoActivity
528    public void testGetPrintServiceRecommendations() throws Throwable {
529        assertException(() -> mIPrintManager.getPrintServiceRecommendations(mUserId),
530                SecurityException.class);
531
532        // Cannot test bad user Id as these tests are allowed to call across users
533    }
534
535    /**
536     * test IPrintManager.createPrinterDiscoverySession
537     */
538    @MediumTest
539    @Test
540    @NoActivity
541    public void testCreatePrinterDiscoverySession() throws Throwable {
542        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
543
544        mIPrintManager.createPrinterDiscoverySession(listener, mUserId);
545
546        try {
547            assertException(() -> mIPrintManager.createPrinterDiscoverySession(null, mUserId),
548                    NullPointerException.class);
549
550            // Cannot test bad user Id as these tests are allowed to call across users
551        } finally {
552            // Remove discovery session so that the next test create a new one. Usually a leaked
553            // session is removed on the next call from the print service. But in this case we want
554            // to force a new call to onPrinterDiscoverySessionStart in the next test.
555            mIPrintManager.destroyPrinterDiscoverySession(listener, mUserId);
556        }
557    }
558
559    /**
560     * test IPrintManager.startPrinterDiscovery
561     */
562    @LargeTest
563    @Test
564    public void testStartPrinterDiscovery() throws Throwable {
565        startPrinting();
566
567        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
568        final List<PrinterId> goodPrinters = new ArrayList<>();
569        goodPrinters.add(mGoodPrinterId);
570
571        final List<PrinterId> badPrinters = new ArrayList<>();
572        badPrinters.add(getBadPrinterId());
573
574        final List<PrinterId> emptyPrinters = new ArrayList<>();
575
576        final List<PrinterId> nullPrinters = new ArrayList<>();
577        nullPrinters.add(null);
578
579        mIPrintManager.startPrinterDiscovery(listener, goodPrinters, mUserId);
580
581        // Bad or no printers do no cause exceptions
582        mIPrintManager.startPrinterDiscovery(listener, badPrinters, mUserId);
583        mIPrintManager.startPrinterDiscovery(listener, emptyPrinters, mUserId);
584        mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
585
586        assertException(() -> mIPrintManager.startPrinterDiscovery(listener, nullPrinters, mUserId),
587                NullPointerException.class);
588
589        assertException(() -> mIPrintManager.startPrinterDiscovery(null, goodPrinters, mUserId),
590                NullPointerException.class);
591
592        // Cannot test bad user Id as these tests are allowed to call across users
593
594        endPrinting();
595    }
596
597    /**
598     * test IPrintManager.stopPrinterDiscovery
599     */
600    @MediumTest
601    @Test
602    @NoActivity
603    public void testStopPrinterDiscovery() throws Throwable {
604        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
605
606        mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
607        mIPrintManager.stopPrinterDiscovery(listener, mUserId);
608
609        // Stopping an already stopped session is a no-op
610        mIPrintManager.stopPrinterDiscovery(listener, mUserId);
611
612        mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
613        assertException(() -> mIPrintManager.stopPrinterDiscovery(null, mUserId),
614                NullPointerException.class);
615
616        // Cannot test bad user Id as these tests are allowed to call across users
617    }
618
619    /**
620     * test IPrintManager.validatePrinters
621     */
622    @LargeTest
623    @Test
624    public void testValidatePrinters() throws Throwable {
625        startPrinting();
626
627        final List<PrinterId> goodPrinters = new ArrayList<>();
628        goodPrinters.add(mGoodPrinterId);
629
630        final List<PrinterId> badPrinters = new ArrayList<>();
631        badPrinters.add(getBadPrinterId());
632
633        final List<PrinterId> emptyPrinters = new ArrayList<>();
634
635        final List<PrinterId> nullPrinters = new ArrayList<>();
636        nullPrinters.add(null);
637
638        mIPrintManager.validatePrinters(goodPrinters, mUserId);
639
640        // Bad or empty list of printers do no cause exceptions
641        mIPrintManager.validatePrinters(badPrinters, mUserId);
642        mIPrintManager.validatePrinters(emptyPrinters, mUserId);
643
644        assertException(() -> mIPrintManager.validatePrinters(null, mUserId),
645                NullPointerException.class);
646
647        assertException(() -> mIPrintManager.validatePrinters(nullPrinters, mUserId),
648                NullPointerException.class);
649
650        // Cannot test bad user Id as these tests are allowed to call across users
651
652        endPrinting();
653    }
654
655    /**
656     * test IPrintManager.startPrinterStateTracking
657     */
658    @LargeTest
659    @Test
660    public void testStartPrinterStateTracking() throws Throwable {
661        startPrinting();
662
663        mIPrintManager.startPrinterStateTracking(mGoodPrinterId, mUserId);
664
665        // Bad printers do no cause exceptions
666        mIPrintManager.startPrinterStateTracking(getBadPrinterId(), mUserId);
667
668        assertException(() -> mIPrintManager.startPrinterStateTracking(null, mUserId),
669                NullPointerException.class);
670
671        // Cannot test bad user Id as these tests are allowed to call across users
672
673        endPrinting();
674    }
675
676    /**
677     * test IPrintManager.getCustomPrinterIcon
678     */
679    @LargeTest
680    @Test
681    public void testGetCustomPrinterIcon() throws Throwable {
682        startPrinting();
683
684        mIPrintManager.getCustomPrinterIcon(mGoodPrinterId, mUserId);
685
686        // Bad printers do no cause exceptions
687        mIPrintManager.getCustomPrinterIcon(getBadPrinterId(), mUserId);
688
689        assertException(() -> mIPrintManager.getCustomPrinterIcon(null, mUserId),
690                NullPointerException.class);
691
692        // Cannot test bad user Id as these tests are allowed to call across users
693
694        endPrinting();
695    }
696
697    /**
698     * test IPrintManager.stopPrinterStateTracking
699     */
700    @LargeTest
701    @Test
702    public void testStopPrinterStateTracking() throws Throwable {
703        startPrinting();
704
705        mIPrintManager.startPrinterStateTracking(mGoodPrinterId, mUserId);
706        mIPrintManager.stopPrinterStateTracking(mGoodPrinterId, mUserId);
707
708        // Stop to track a non-tracked printer is a no-op
709        mIPrintManager.stopPrinterStateTracking(mGoodPrinterId, mUserId);
710
711        // Bad printers do no cause exceptions
712        mIPrintManager.startPrinterStateTracking(getBadPrinterId(), mUserId);
713        mIPrintManager.stopPrinterStateTracking(getBadPrinterId(), mUserId);
714
715        assertException(() -> mIPrintManager.stopPrinterStateTracking(null, mUserId),
716                NullPointerException.class);
717
718        // Cannot test bad user Id as these tests are allowed to call across users
719
720        endPrinting();
721    }
722
723    /**
724     * test IPrintManager.destroyPrinterDiscoverySession
725     */
726    @MediumTest
727    @Test
728    @NoActivity
729    public void testDestroyPrinterDiscoverySession() throws Throwable {
730        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
731
732        mIPrintManager.createPrinterDiscoverySession(listener, mUserId);
733        mIPrintManager.destroyPrinterDiscoverySession(listener, mUserId);
734
735        // Destroying already destroyed session is a no-op
736        mIPrintManager.destroyPrinterDiscoverySession(listener, mUserId);
737
738        assertException(() -> mIPrintManager.destroyPrinterDiscoverySession(null, mUserId),
739                NullPointerException.class);
740
741        // Cannot test bad user Id as these tests are allowed to call across users
742    }
743}
744