• 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 com.android.printservice.recommendation;
18 
19 import androidx.annotation.NonNull;
20 import androidx.annotation.Nullable;
21 import androidx.annotation.StringRes;
22 
23 import com.android.printservice.recommendation.util.Preconditions;
24 
25 import java.net.InetAddress;
26 import java.util.Collections;
27 import java.util.List;
28 
29 /**
30  * Wrapper for a {@link PrintServicePlugin}, isolating issues with the plugin as good as possible
31  * from the {@link RecommendationServiceImpl service}.
32  */
33 class RemotePrintServicePlugin implements PrintServicePlugin.PrinterDiscoveryCallback {
34     /** Lock for this object */
35     private final Object mLock = new Object();
36 
37     /** The name of the print service. */
38     public final @StringRes int name;
39 
40     /** If the print service if for more than a single vendor */
41     public final boolean recommendsMultiVendorService;
42 
43     /** The package name of the full print service */
44     public final @NonNull CharSequence packageName;
45 
46     /** Wrapped plugin */
47     private final @NonNull PrintServicePlugin mPlugin;
48 
49     /** The printers discovered by the plugin */
50     private @NonNull List<InetAddress> mPrinters;
51 
52     /** If the plugin is started by not yet stopped */
53     private boolean isRunning;
54 
55     /** Listener for changes to {@link #mPrinters}. */
56     private @NonNull OnChangedListener mListener;
57 
58     /**
59      * Create a new remote for a {@link PrintServicePlugin plugin}.
60      *
61      * @param plugin                       The plugin to be wrapped
62      * @param listener                     The listener to be notified about changes in this plugin
63      * @param recommendsMultiVendorService If the plugin detects printers of more than a single
64      *                                     vendor
65      *
66      * @throws PluginException If the plugin has issues while caching basic stub properties
67      */
RemotePrintServicePlugin(@onNull PrintServicePlugin plugin, @NonNull OnChangedListener listener, boolean recommendsMultiVendorService)68     public RemotePrintServicePlugin(@NonNull PrintServicePlugin plugin,
69             @NonNull OnChangedListener listener, boolean recommendsMultiVendorService)
70             throws PluginException {
71         mListener = listener;
72         mPlugin = plugin;
73         mPrinters = Collections.emptyList();
74 
75         this.recommendsMultiVendorService = recommendsMultiVendorService;
76 
77         // We handle any throwable to isolate our self from bugs in the plugin code.
78         // Cache simple properties to avoid having to deal with exceptions later in the code.
79         try {
80             name = Preconditions.checkArgumentPositive(mPlugin.getName(), "name");
81             packageName = Preconditions.checkStringNotEmpty(mPlugin.getPackageName(),
82                     "packageName");
83         } catch (Throwable e) {
84             throw new PluginException(mPlugin, "Cannot cache simple properties ", e);
85         }
86 
87         isRunning = false;
88     }
89 
90     /**
91      * Start the plugin. From now on there might be callbacks to the registered listener.
92      */
start()93     public void start()
94             throws PluginException {
95         // We handle any throwable to isolate our self from bugs in the stub code
96         try {
97             synchronized (mLock) {
98                 isRunning = true;
99                 mPlugin.start(this);
100             }
101         } catch (Throwable e) {
102             throw new PluginException(mPlugin, "Cannot start", e);
103         }
104     }
105 
106     /**
107      * Stop the plugin. From this call on there will not be any more callbacks.
108      */
stop()109     public void stop() throws PluginException {
110         // We handle any throwable to isolate our self from bugs in the stub code
111         try {
112             synchronized (mLock) {
113                 mPlugin.stop();
114                 isRunning = false;
115             }
116         } catch (Throwable e) {
117             throw new PluginException(mPlugin, "Cannot stop", e);
118         }
119     }
120 
121     /**
122      * Get the current number of printers reported by the stub.
123      *
124      * @return The number of printers reported by the stub.
125      */
getPrinters()126     public @NonNull List<InetAddress> getPrinters() {
127         return mPrinters;
128     }
129 
130     @Override
onChanged(@ullable List<InetAddress> discoveredPrinters)131     public void onChanged(@Nullable List<InetAddress> discoveredPrinters) {
132         synchronized (mLock) {
133             Preconditions.checkState(isRunning);
134 
135             if (discoveredPrinters == null) {
136                 mPrinters = Collections.emptyList();
137             } else {
138                 mPrinters = Preconditions.checkCollectionElementsNotNull(discoveredPrinters,
139                         "discoveredPrinters");
140             }
141 
142             mListener.onChanged();
143         }
144     }
145 
146     /**
147      * Listener to listen for changes to {@link #getPrinters}
148      */
149     public interface OnChangedListener {
onChanged()150         void onChanged();
151     }
152 
153     /**
154      * Exception thrown if the stub has any issues.
155      */
156     public class PluginException extends Exception {
PluginException(PrintServicePlugin plugin, String message, Throwable e)157         private PluginException(PrintServicePlugin plugin, String message, Throwable e) {
158             super(plugin + ": " + message, e);
159         }
160     }
161 }
162