1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  * Copyright (C) 2016 Mopria Alliance, Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.bips;
19 
20 import android.print.PrintJobId;
21 import android.print.PrinterId;
22 
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.UUID;
26 import java.util.concurrent.CopyOnWriteArrayList;
27 
28 /** Manages a job queue, ensuring only one job is printed at a time */
29 class JobQueue {
30     private final List<LocalPrintJob> mJobs = new CopyOnWriteArrayList<>();
31     private LocalPrintJob mCurrent;
32 
33     /** Queue a print job for printing at the next available opportunity */
print(LocalPrintJob job)34     void print(LocalPrintJob job) {
35         mJobs.add(job);
36         startNextJob();
37     }
38 
39     /** Cancel any previously queued job for a printer with the supplied ID. */
cancel(PrinterId printerId)40     void cancel(PrinterId printerId) {
41         for (LocalPrintJob job : mJobs) {
42             if (printerId.equals(job.getPrintJob().getInfo().getPrinterId())) {
43                 cancel(job.getPrintJobId());
44             }
45         }
46 
47         if (mCurrent != null && printerId.equals(mCurrent.getPrintJob().getInfo().getPrinterId())) {
48             cancel(mCurrent.getPrintJobId());
49         }
50     }
51 
52     /** Restart any blocked job for a printer with this ID. */
restart(PrinterId printerId)53     void restart(PrinterId printerId) {
54         if (mCurrent != null && printerId.equals(mCurrent.getPrintJob().getInfo().getPrinterId())) {
55             mCurrent.restart();
56         }
57     }
58 
59     /** Cancel a previously queued job */
cancel(PrintJobId id)60     void cancel(PrintJobId id) {
61         // If a job hasn't started, kill it instantly.
62         for (LocalPrintJob job : mJobs) {
63             if (job.getPrintJobId().equals(id)) {
64                 mJobs.remove(job);
65                 job.getPrintJob().cancel();
66                 return;
67             }
68         }
69 
70         if (mCurrent != null && mCurrent.getPrintJobId().equals(id)) {
71             mCurrent.cancel();
72         }
73     }
74 
75     /** Launch the next job if possible */
startNextJob()76     private void startNextJob() {
77         if (mJobs.isEmpty() || mCurrent != null) {
78             return;
79         }
80 
81         mCurrent = mJobs.remove(0);
82         mCurrent.start(job -> {
83             mCurrent = null;
84             startNextJob();
85         });
86     }
87 }
88