19dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann/* 29dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Copyright (C) 2016 The Android Open Source Project 39dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 49dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License"); 59dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * you may not use this file except in compliance with the License. 69dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * You may obtain a copy of the License at 79dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 89dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * http://www.apache.org/licenses/LICENSE-2.0 99dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 109dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software 119dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS, 129dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * See the License for the specific language governing permissions and 149dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * limitations under the License. 159dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 169dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 179dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannpackage com.android.printservice.recommendation; 189dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 199dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.annotation.IntRange; 209dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.annotation.NonNull; 219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport android.annotation.StringRes; 229dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannimport com.android.internal.util.Preconditions; 239dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann/** 259dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Wrapper for a {@link PrintServicePlugin}, isolating issues with the plugin as good as possible 269dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * from the {@link RecommendationServiceImpl service}. 279dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 289dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmannclass RemotePrintServicePlugin implements PrintServicePlugin.PrinterDiscoveryCallback { 299dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Lock for this object */ 309dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private final Object mLock = new Object(); 319dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 329dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** The name of the print service. */ 339dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public final @StringRes int name; 349dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 359dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** If the print service if for more than a single vendor */ 369dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public final boolean recommendsMultiVendorService; 379dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 389dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** The package name of the full print service */ 399dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public final @NonNull CharSequence packageName; 409dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 419dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Wrapped plugin */ 429dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private final @NonNull PrintServicePlugin mPlugin; 439dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 449dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** The number of printers discovered by the plugin */ 459dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private @IntRange(from = 0) int mNumPrinters; 469dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 479dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** If the plugin is started by not yet stopped */ 489dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private boolean isRunning; 499dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 509dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** Listener for changes to {@link #mNumPrinters}. */ 519dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private @NonNull OnChangedListener mListener; 529dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 539dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 549dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Create a new remote for a {@link PrintServicePlugin plugin}. 559dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 569dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param plugin The plugin to be wrapped 579dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param listener The listener to be notified about changes in this plugin 589dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @param recommendsMultiVendorService If the plugin detects printers of more than a single 599dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * vendor 609dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 619dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @throws PluginException If the plugin has issues while caching basic stub properties 629dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 639dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public RemotePrintServicePlugin(@NonNull PrintServicePlugin plugin, 649dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @NonNull OnChangedListener listener, boolean recommendsMultiVendorService) 659dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws PluginException { 669dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mListener = listener; 679dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mPlugin = plugin; 689dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann this.recommendsMultiVendorService = recommendsMultiVendorService; 699dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 709dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann // We handle any throwable to isolate our self from bugs in the plugin code. 719dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann // Cache simple properties to avoid having to deal with exceptions later in the code. 729dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann try { 739dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann name = Preconditions.checkArgumentPositive(mPlugin.getName(), "name"); 749dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann packageName = Preconditions.checkStringNotEmpty(mPlugin.getPackageName(), 759dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann "packageName"); 769dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } catch (Throwable e) { 779dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new PluginException(mPlugin, "Cannot cache simple properties ", e); 789dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 799dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 809dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann isRunning = false; 819dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 829dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 839dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 849dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Start the plugin. From now on there might be callbacks to the registered listener. 859dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 869dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public void start() 879dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throws PluginException { 889dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann // We handle any throwable to isolate our self from bugs in the stub code 899dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann try { 909dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann synchronized (mLock) { 919dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann isRunning = true; 929dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mPlugin.start(this); 939dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 949dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } catch (Throwable e) { 959dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new PluginException(mPlugin, "Cannot start", e); 969dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 979dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 989dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 999dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1009dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Stop the plugin. From this call on there will not be any more callbacks. 1019dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1029dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public void stop() throws PluginException { 1039dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann // We handle any throwable to isolate our self from bugs in the stub code 1049dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann try { 1059dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann synchronized (mLock) { 1069dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mPlugin.stop(); 1079dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann isRunning = false; 1089dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1099dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } catch (Throwable e) { 1109dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann throw new PluginException(mPlugin, "Cannot stop", e); 1119dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1129dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1139dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1149dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1159dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Get the current number of printers reported by the stub. 1169dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * 1179dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * @return The number of printers reported by the stub. 1189dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1199dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public @IntRange(from = 0) int getNumPrinters() { 1209dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann return mNumPrinters; 1219dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1229dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1239dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann @Override 1249dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public void onChanged(@IntRange(from = 0) int numDiscoveredPrinters) { 1259dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann synchronized (mLock) { 1269dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann Preconditions.checkState(isRunning); 1279dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1289dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mNumPrinters = Preconditions.checkArgumentNonnegative(numDiscoveredPrinters, 1299dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann "numDiscoveredPrinters"); 1309dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1319dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann if (mNumPrinters > 0) { 1329dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann mListener.onChanged(); 1339dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1349dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1359dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1369dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1379dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1389dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Listener to listen for changes to {@link #getNumPrinters} 1399dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1409dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public interface OnChangedListener { 1419dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann void onChanged(); 1429dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1439dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann 1449dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann /** 1459dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann * Exception thrown if the stub has any issues. 1469dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann */ 1479dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann public class PluginException extends Exception { 1489dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann private PluginException(PrintServicePlugin plugin, String message, Throwable e) { 1499dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann super(plugin + ": " + message, e); 1509dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1519dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann } 1529dcb86a48d73f399fb1b5c020005d76d350eeac2Philip P. Moltmann} 153