From 7e01895e6972c0ebc552215b1207a519529af3fd Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sun, 2 Apr 2017 14:34:09 -0700 Subject: [PATCH] Return inet addr for discoverable printers ... by extending the RecommendationInfo to store the inet addresses not just the count. Thankfully the recommendation plugins already contained all the printers, not only the count. Also expose the print service state as system APIs as they will be used by the default print service. Bug: 35765644 Test: Ran AddPrinterActivity on network that had printers to discover Change-Id: I929a177adb75f6848848ba30a472cf0343d2e67e --- api/system-current.txt | 26 ++++- core/java/android/print/PrintManager.java | 98 ++++++++++--------- .../PrintServiceRecommendationsLoader.java | 3 +- .../android/print/PrintServicesLoader.java | 3 +- .../printservice/PrintServiceInfo.java | 24 ++++- .../recommendation/RecommendationInfo.java | 82 ++++++++++++++-- .../recommendation/PrintServicePlugin.java | 9 +- .../RecommendationServiceImpl.java | 13 ++- .../RemotePrintServicePlugin.java | 35 ++++--- .../plugin/hp/ServiceListener.java | 25 +++-- .../hp/ServiceRecommendationPlugin.java | 12 ++- .../mopria/MopriaRecommendationPlugin.java | 11 ++- .../plugin/xerox/ServiceResolver.java | 11 ++- ...XeroxPrintServiceRecommendationPlugin.java | 12 +-- .../util/MDNSFilteredDiscovery.java | 29 +++--- .../com/android/server/print/UserState.java | 9 +- 16 files changed, 274 insertions(+), 128 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 1306f6d65d084..30d1207d8e0f9 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -35598,8 +35598,23 @@ package android.print { } public final class PrintManager { + method public void addPrintServiceRecommendationsChangeListener(android.print.PrintManager.PrintServiceRecommendationsChangeListener, android.os.Handler); + method public void addPrintServicesChangeListener(android.print.PrintManager.PrintServicesChangeListener, android.os.Handler); method public java.util.List getPrintJobs(); + method public java.util.List getPrintServiceRecommendations(); + method public java.util.List getPrintServices(int); method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes); + method public void removePrintServiceRecommendationsChangeListener(android.print.PrintManager.PrintServiceRecommendationsChangeListener); + method public void removePrintServicesChangeListener(android.print.PrintManager.PrintServicesChangeListener); + field public static final int ENABLED_SERVICES = 1; // 0x1 + } + + public static abstract interface PrintManager.PrintServiceRecommendationsChangeListener { + method public abstract void onPrintServiceRecommendationsChanged(); + } + + public static abstract interface PrintManager.PrintServicesChangeListener { + method public abstract void onPrintServicesChanged(); } public final class PrinterCapabilitiesInfo implements android.os.Parcelable { @@ -35728,6 +35743,13 @@ package android.printservice { field public static final java.lang.String SERVICE_META_DATA = "android.printservice"; } + public final class PrintServiceInfo implements android.os.Parcelable { + method public int describeContents(); + method public android.content.ComponentName getComponentName(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + public abstract class PrinterDiscoverySession { ctor public PrinterDiscoverySession(); method public final void addPrinters(java.util.List); @@ -35750,8 +35772,10 @@ package android.printservice { package android.printservice.recommendation { public final class RecommendationInfo implements android.os.Parcelable { - ctor public RecommendationInfo(java.lang.CharSequence, java.lang.CharSequence, int, boolean); + ctor public RecommendationInfo(java.lang.CharSequence, java.lang.CharSequence, java.util.List, boolean); + ctor public deprecated RecommendationInfo(java.lang.CharSequence, java.lang.CharSequence, int, boolean); method public int describeContents(); + method public java.util.List getDiscoveredPrinters(); method public java.lang.CharSequence getName(); method public int getNumDiscoveredPrinters(); method public java.lang.CharSequence getPackageName(); diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index 5d0ad5568173f..8ee05177f1860 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -18,6 +18,7 @@ package android.print; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.app.Activity; import android.app.Application.ActivityLifecycleCallbacks; import android.content.ComponentName; @@ -43,8 +44,8 @@ import android.util.ArrayMap; import android.util.Log; import com.android.internal.os.SomeArgs; - import com.android.internal.util.Preconditions; + import libcore.io.IoUtils; import java.lang.ref.WeakReference; @@ -115,8 +116,6 @@ public final class PrintManager { private static final boolean DEBUG = false; private static final int MSG_NOTIFY_PRINT_JOB_STATE_CHANGED = 1; - private static final int MSG_NOTIFY_PRINT_SERVICES_CHANGED = 2; - private static final int MSG_NOTIFY_PRINT_SERVICE_RECOMMENDATIONS_CHANGED = 3; /** * Package name of print spooler. @@ -131,6 +130,7 @@ public final class PrintManager { * @see #getPrintServices * @hide */ + @SystemApi public static final int ENABLED_SERVICES = 1 << 0; /** @@ -221,16 +221,26 @@ public final class PrintManager { public void onPrintJobStateChanged(PrintJobId printJobId); } - /** @hide */ + /** + * Listen for changes to {@link #getPrintServices(int)}. + * + * @hide + */ + @SystemApi public interface PrintServicesChangeListener { /** * Callback notifying that the print services changed. */ - public void onPrintServicesChanged(); + void onPrintServicesChanged(); } - /** @hide */ + /** + * Listen for changes to {@link #getPrintServiceRecommendations()}. + * + * @hide + */ + @SystemApi public interface PrintServiceRecommendationsChangeListener { /** @@ -268,22 +278,6 @@ public final class PrintManager { } args.recycle(); } break; - case MSG_NOTIFY_PRINT_SERVICES_CHANGED: { - PrintServicesChangeListenerWrapper wrapper = - (PrintServicesChangeListenerWrapper) message.obj; - PrintServicesChangeListener listener = wrapper.getListener(); - if (listener != null) { - listener.onPrintServicesChanged(); - } - } break; - case MSG_NOTIFY_PRINT_SERVICE_RECOMMENDATIONS_CHANGED: { - PrintServiceRecommendationsChangeListenerWrapper wrapper = - (PrintServiceRecommendationsChangeListenerWrapper) message.obj; - PrintServiceRecommendationsChangeListener listener = wrapper.getListener(); - if (listener != null) { - listener.onPrintServiceRecommendationsChanged(); - } - } break; } } }; @@ -325,8 +319,7 @@ public final class PrintManager { return; } if (mPrintJobStateChangeListeners == null) { - mPrintJobStateChangeListeners = new ArrayMap(); + mPrintJobStateChangeListeners = new ArrayMap<>(); } PrintJobStateChangeListenerWrapper wrappedListener = new PrintJobStateChangeListenerWrapper(listener, mHandler); @@ -399,7 +392,7 @@ public final class PrintManager { * @param printerId the id of the printer the icon should be loaded for * @return the custom icon to be used for the printer or null if the icon is * not yet available - * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon() + * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon(boolean) * @hide */ public Icon getCustomPrinterIcon(PrinterId printerId) { @@ -558,12 +551,21 @@ public final class PrintManager { * Listen for changes to the installed and enabled print services. * * @param listener the listener to add + * @param handler the handler the listener is called back on * * @see android.print.PrintManager#getPrintServices + * + * @hide */ - void addPrintServicesChangeListener(@NonNull PrintServicesChangeListener listener) { + @SystemApi + public void addPrintServicesChangeListener(@NonNull PrintServicesChangeListener listener, + @Nullable Handler handler) { Preconditions.checkNotNull(listener); + if (handler == null) { + handler = mHandler; + } + if (mService == null) { Log.w(LOG_TAG, "Feature android.software.print not available"); return; @@ -572,7 +574,7 @@ public final class PrintManager { mPrintServicesChangeListeners = new ArrayMap<>(); } PrintServicesChangeListenerWrapper wrappedListener = - new PrintServicesChangeListenerWrapper(listener, mHandler); + new PrintServicesChangeListenerWrapper(listener, handler); try { mService.addPrintServicesChangeListener(wrappedListener, mUserId); mPrintServicesChangeListeners.put(listener, wrappedListener); @@ -587,8 +589,11 @@ public final class PrintManager { * @param listener the listener to remove * * @see android.print.PrintManager#getPrintServices + * + * @hide */ - void removePrintServicesChangeListener(@NonNull PrintServicesChangeListener listener) { + @SystemApi + public void removePrintServicesChangeListener(@NonNull PrintServicesChangeListener listener) { Preconditions.checkNotNull(listener); if (mService == null) { @@ -623,11 +628,12 @@ public final class PrintManager { * * @return The print service list or an empty list. * - * @see #addPrintServicesChangeListener(PrintServicesChangeListener) + * @see #addPrintServicesChangeListener(PrintServicesChangeListener, Handler) * @see #removePrintServicesChangeListener(PrintServicesChangeListener) * * @hide */ + @SystemApi public @NonNull List getPrintServices(int selectionFlags) { Preconditions.checkFlagsArgument(selectionFlags, ALL_SERVICES); @@ -646,13 +652,22 @@ public final class PrintManager { * Listen for changes to the print service recommendations. * * @param listener the listener to add + * @param handler the handler the listener is called back on * * @see android.print.PrintManager#getPrintServiceRecommendations + * + * @hide */ - void addPrintServiceRecommendationsChangeListener( - @NonNull PrintServiceRecommendationsChangeListener listener) { + @SystemApi + public void addPrintServiceRecommendationsChangeListener( + @NonNull PrintServiceRecommendationsChangeListener listener, + @Nullable Handler handler) { Preconditions.checkNotNull(listener); + if (handler == null) { + handler = mHandler; + } + if (mService == null) { Log.w(LOG_TAG, "Feature android.software.print not available"); return; @@ -661,7 +676,7 @@ public final class PrintManager { mPrintServiceRecommendationsChangeListeners = new ArrayMap<>(); } PrintServiceRecommendationsChangeListenerWrapper wrappedListener = - new PrintServiceRecommendationsChangeListenerWrapper(listener, mHandler); + new PrintServiceRecommendationsChangeListenerWrapper(listener, handler); try { mService.addPrintServiceRecommendationsChangeListener(wrappedListener, mUserId); mPrintServiceRecommendationsChangeListeners.put(listener, wrappedListener); @@ -676,8 +691,11 @@ public final class PrintManager { * @param listener the listener to remove * * @see android.print.PrintManager#getPrintServiceRecommendations + * + * @hide */ - void removePrintServiceRecommendationsChangeListener( + @SystemApi + public void removePrintServiceRecommendationsChangeListener( @NonNull PrintServiceRecommendationsChangeListener listener) { Preconditions.checkNotNull(listener); @@ -715,6 +733,7 @@ public final class PrintManager { * * @hide */ + @SystemApi public @NonNull List getPrintServiceRecommendations() { try { List recommendations = @@ -1349,17 +1368,13 @@ public final class PrintManager { Handler handler = mWeakHandler.get(); PrintServicesChangeListener listener = mWeakListener.get(); if (handler != null && listener != null) { - handler.obtainMessage(MSG_NOTIFY_PRINT_SERVICES_CHANGED, this).sendToTarget(); + handler.post(listener::onPrintServicesChanged); } } public void destroy() { mWeakListener.clear(); } - - public PrintServicesChangeListener getListener() { - return mWeakListener.get(); - } } /** @@ -1381,17 +1396,12 @@ public final class PrintManager { Handler handler = mWeakHandler.get(); PrintServiceRecommendationsChangeListener listener = mWeakListener.get(); if (handler != null && listener != null) { - handler.obtainMessage(MSG_NOTIFY_PRINT_SERVICE_RECOMMENDATIONS_CHANGED, - this).sendToTarget(); + handler.post(listener::onPrintServiceRecommendationsChanged); } } public void destroy() { mWeakListener.clear(); } - - public PrintServiceRecommendationsChangeListener getListener() { - return mWeakListener.get(); - } } } diff --git a/core/java/android/print/PrintServiceRecommendationsLoader.java b/core/java/android/print/PrintServiceRecommendationsLoader.java index c6a4d5103a479..dbd2197507581 100644 --- a/core/java/android/print/PrintServiceRecommendationsLoader.java +++ b/core/java/android/print/PrintServiceRecommendationsLoader.java @@ -22,6 +22,7 @@ import android.content.Loader; import android.os.Handler; import android.os.Message; import android.printservice.recommendation.RecommendationInfo; + import com.android.internal.util.Preconditions; import java.util.List; @@ -77,7 +78,7 @@ public class PrintServiceRecommendationsLoader extends Loader> { } }; - mPrintManager.addPrintServicesChangeListener(mListener); + mPrintManager.addPrintServicesChangeListener(mListener, null); // Immediately deliver a result deliverResult(mPrintManager.getPrintServices(mSelectionFlags)); diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java index 45e3d47c39dee..57f122923c69b 100644 --- a/core/java/android/printservice/PrintServiceInfo.java +++ b/core/java/android/printservice/PrintServiceInfo.java @@ -17,6 +17,7 @@ package android.printservice; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; @@ -47,6 +48,7 @@ import java.io.IOException; * * @hide */ +@SystemApi public final class PrintServiceInfo implements Parcelable { private static final String LOG_TAG = PrintServiceInfo.class.getSimpleName(); @@ -86,6 +88,8 @@ public final class PrintServiceInfo implements Parcelable { * @param settingsActivityName Optional settings activity name. * @param addPrintersActivityName Optional add printers activity name. * @param advancedPrintOptionsActivityName Optional advanced print options activity. + * + * @hide */ public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName, String addPrintersActivityName, String advancedPrintOptionsActivityName) { @@ -110,11 +114,13 @@ public final class PrintServiceInfo implements Parcelable { /** * Creates a new instance. * - * @param resolveInfo The service resolve info. * @param context Context for accessing resources. + * @param resolveInfo The service resolve info. * @return The created instance. + * + * @hide */ - public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) { + public static PrintServiceInfo create(Context context, ResolveInfo resolveInfo) { String settingsActivityName = null; String addPrintersActivityName = null; String advancedPrintOptionsActivityName = null; @@ -177,6 +183,8 @@ public final class PrintServiceInfo implements Parcelable { *

* * @return The id. + * + * @hide */ public String getId() { return mId; @@ -186,6 +194,8 @@ public final class PrintServiceInfo implements Parcelable { * If the service was enabled when it was read from the system. * * @return The id. + * + * @hide */ public boolean isEnabled() { return mIsEnabled; @@ -195,6 +205,8 @@ public final class PrintServiceInfo implements Parcelable { * Mark a service as enabled or not * * @param isEnabled If the service should be marked as enabled. + * + * @hide */ public void setIsEnabled(boolean isEnabled) { mIsEnabled = isEnabled; @@ -204,6 +216,8 @@ public final class PrintServiceInfo implements Parcelable { * The service {@link ResolveInfo}. * * @return The info. + * + * @hide */ public ResolveInfo getResolveInfo() { return mResolveInfo; @@ -217,6 +231,8 @@ public final class PrintServiceInfo implements Parcelable { *

* * @return The settings activity name. + * + * @hide */ public String getSettingsActivityName() { return mSettingsActivityName; @@ -230,6 +246,8 @@ public final class PrintServiceInfo implements Parcelable { *

* * @return The add printers activity name. + * + * @hide */ public String getAddPrintersActivityName() { return mAddPrintersActivityName; @@ -243,6 +261,8 @@ public final class PrintServiceInfo implements Parcelable { *

* * @return The advanced print options activity name. + * + * @hide */ public String getAdvancedOptionsActivityName() { return mAdvancedPrintOptionsActivityName; diff --git a/core/java/android/printservice/recommendation/RecommendationInfo.java b/core/java/android/printservice/recommendation/RecommendationInfo.java index 65d534e45e1cf..a327956312273 100644 --- a/core/java/android/printservice/recommendation/RecommendationInfo.java +++ b/core/java/android/printservice/recommendation/RecommendationInfo.java @@ -22,8 +22,14 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.printservice.PrintService; + import com.android.internal.util.Preconditions; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + /** * A recommendation to install a {@link PrintService print service}. * @@ -37,8 +43,8 @@ public final class RecommendationInfo implements Parcelable { /** Display name of the print service. */ private @NonNull final CharSequence mName; - /** Number of printers the print service would discover if installed. */ - private @IntRange(from = 0) final int mNumDiscoveredPrinters; + /** Printers the print service would discover if installed. */ + @NonNull private final List mDiscoveredPrinters; /** If the service detects printer from multiple vendors. */ private final boolean mRecommendsMultiVendorService; @@ -48,18 +54,62 @@ public final class RecommendationInfo implements Parcelable { * * @param packageName Package name of the print service * @param name Display name of the print service - * @param numDiscoveredPrinters Number of printers the print service would discover if - * installed + * @param discoveredPrinters The {@link InetAddress addresses} of the discovered + * printers. Cannot be null or empty. * @param recommendsMultiVendorService If the service detects printer from multiple vendor */ public RecommendationInfo(@NonNull CharSequence packageName, @NonNull CharSequence name, - @IntRange(from = 0) int numDiscoveredPrinters, boolean recommendsMultiVendorService) { + @NonNull List discoveredPrinters, boolean recommendsMultiVendorService) { mPackageName = Preconditions.checkStringNotEmpty(packageName); mName = Preconditions.checkStringNotEmpty(name); - mNumDiscoveredPrinters = Preconditions.checkArgumentNonnegative(numDiscoveredPrinters); + mDiscoveredPrinters = Preconditions.checkCollectionElementsNotNull(discoveredPrinters, + "discoveredPrinters"); mRecommendsMultiVendorService = recommendsMultiVendorService; } + /** + * Create a new recommendation. + * + * @param packageName Package name of the print service + * @param name Display name of the print service + * @param numDiscoveredPrinters Number of printers the print service would discover if + * installed + * @param recommendsMultiVendorService If the service detects printer from multiple vendor + * + * @deprecated Use {@link RecommendationInfo(String, String, List, boolean)} + * instead + */ + @Deprecated + public RecommendationInfo(@NonNull CharSequence packageName, @NonNull CharSequence name, + @IntRange(from = 0) int numDiscoveredPrinters, boolean recommendsMultiVendorService) { + throw new IllegalArgumentException("This constructor has been deprecated"); + } + + /** + * Read a list of blobs from the parcel and return it as a list of {@link InetAddress + * addresses}. + * + * @param parcel the parcel to read the blobs from + * + * @return The list of {@link InetAddress addresses} or null if no printers were found. + * + * @see #writeToParcel(Parcel, int) + */ + @NonNull private static ArrayList readDiscoveredPrinters(@NonNull Parcel parcel) { + int numDiscoveredPrinters = parcel.readInt(); + ArrayList discoveredPrinters = new ArrayList<>(numDiscoveredPrinters); + + for (int i = 0; i < numDiscoveredPrinters; i++) { + try { + discoveredPrinters.add(InetAddress.getByAddress(parcel.readBlob())); + } catch (UnknownHostException e) { + throw new IllegalArgumentException(e); + } + } + + return discoveredPrinters; + } + /** * Create a new recommendation from a parcel. * @@ -68,7 +118,7 @@ public final class RecommendationInfo implements Parcelable { * @see #CREATOR */ private RecommendationInfo(@NonNull Parcel parcel) { - this(parcel.readCharSequence(), parcel.readCharSequence(), parcel.readInt(), + this(parcel.readCharSequence(), parcel.readCharSequence(), readDiscoveredPrinters(parcel), parcel.readByte() != 0); } @@ -86,11 +136,18 @@ public final class RecommendationInfo implements Parcelable { return mRecommendsMultiVendorService; } + /** + * @return The {@link InetAddress address} of the printers the print service would detect. + */ + @NonNull public List getDiscoveredPrinters() { + return mDiscoveredPrinters; + } + /** * @return The number of printer the print service would detect. */ public int getNumDiscoveredPrinters() { - return mNumDiscoveredPrinters; + return mDiscoveredPrinters.size(); } /** @@ -109,7 +166,14 @@ public final class RecommendationInfo implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeCharSequence(mPackageName); dest.writeCharSequence(mName); - dest.writeInt(mNumDiscoveredPrinters); + + int numDiscoveredPrinters = mDiscoveredPrinters.size(); + dest.writeInt(numDiscoveredPrinters); + + for (InetAddress printer : mDiscoveredPrinters) { + dest.writeBlob(printer.getAddress()); + } + dest.writeByte((byte) (mRecommendsMultiVendorService ? 1 : 0)); } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/PrintServicePlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/PrintServicePlugin.java index d604ef8a49ea5..d723d2fd19f77 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/PrintServicePlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/PrintServicePlugin.java @@ -16,10 +16,13 @@ package com.android.printservice.recommendation; -import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.StringRes; +import java.net.InetAddress; +import java.util.List; + /** * Interface to be implemented by each print service plugin. *

@@ -35,9 +38,9 @@ public interface PrintServicePlugin { /** * Announce that something changed and the UI for this plugin should be updated. * - * @param numDiscoveredPrinters The number of printers discovered. + * @param discoveredPrinters The printers discovered. */ - void onChanged(@IntRange(from = 0) int numDiscoveredPrinters); + void onChanged(@Nullable List discoveredPrinters); } /** diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java index d0483962eae3d..e18ee90d39d74 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java @@ -17,20 +17,24 @@ package com.android.printservice.recommendation; import android.content.res.Configuration; +import android.printservice.PrintService; import android.printservice.recommendation.RecommendationInfo; import android.printservice.recommendation.RecommendationService; -import android.printservice.PrintService; import android.util.Log; + import com.android.printservice.recommendation.plugin.hp.HPRecommendationPlugin; import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugin; import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig; import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin; import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin; import com.android.printservice.recommendation.plugin.xerox.XeroxPrintServiceRecommendationPlugin; + import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.net.InetAddress; import java.util.ArrayList; +import java.util.List; /** * Service that recommends {@link PrintService print services} that might be a good idea to install. @@ -129,12 +133,11 @@ public class RecommendationServiceImpl extends RecommendationService RemotePrintServicePlugin plugin = mPlugins.get(i); try { - int numPrinters = plugin.getNumPrinters(); + List printers = plugin.getPrinters(); - if (numPrinters > 0) { + if (!printers.isEmpty()) { recommendations.add(new RecommendationInfo(plugin.packageName, - getString(plugin.name), numPrinters, - plugin.recommendsMultiVendorService)); + getString(plugin.name), printers, plugin.recommendsMultiVendorService)); } } catch (Exception e) { Log.e(LOG_TAG, "Could not read state of plugin for " + plugin.packageName, e); diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RemotePrintServicePlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RemotePrintServicePlugin.java index dbd164946dfbd..fd929a7c82332 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RemotePrintServicePlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RemotePrintServicePlugin.java @@ -16,11 +16,16 @@ package com.android.printservice.recommendation; -import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.StringRes; + import com.android.internal.util.Preconditions; +import java.net.InetAddress; +import java.util.Collections; +import java.util.List; + /** * Wrapper for a {@link PrintServicePlugin}, isolating issues with the plugin as good as possible * from the {@link RecommendationServiceImpl service}. @@ -41,13 +46,13 @@ class RemotePrintServicePlugin implements PrintServicePlugin.PrinterDiscoveryCal /** Wrapped plugin */ private final @NonNull PrintServicePlugin mPlugin; - /** The number of printers discovered by the plugin */ - private @IntRange(from = 0) int mNumPrinters; + /** The printers discovered by the plugin */ + private @NonNull List mPrinters; /** If the plugin is started by not yet stopped */ private boolean isRunning; - /** Listener for changes to {@link #mNumPrinters}. */ + /** Listener for changes to {@link #mPrinters}. */ private @NonNull OnChangedListener mListener; /** @@ -65,6 +70,8 @@ class RemotePrintServicePlugin implements PrintServicePlugin.PrinterDiscoveryCal throws PluginException { mListener = listener; mPlugin = plugin; + mPrinters = Collections.emptyList(); + this.recommendsMultiVendorService = recommendsMultiVendorService; // We handle any throwable to isolate our self from bugs in the plugin code. @@ -116,26 +123,28 @@ class RemotePrintServicePlugin implements PrintServicePlugin.PrinterDiscoveryCal * * @return The number of printers reported by the stub. */ - public @IntRange(from = 0) int getNumPrinters() { - return mNumPrinters; + public @NonNull List getPrinters() { + return mPrinters; } @Override - public void onChanged(@IntRange(from = 0) int numDiscoveredPrinters) { + public void onChanged(@Nullable List discoveredPrinters) { synchronized (mLock) { Preconditions.checkState(isRunning); - mNumPrinters = Preconditions.checkArgumentNonnegative(numDiscoveredPrinters, - "numDiscoveredPrinters"); - - if (mNumPrinters > 0) { - mListener.onChanged(); + if (discoveredPrinters == null) { + mPrinters = Collections.emptyList(); + } else { + mPrinters = Preconditions.checkCollectionElementsNotNull(discoveredPrinters, + "discoveredPrinters"); } + + mListener.onChanged(); } } /** - * Listener to listen for changes to {@link #getNumPrinters} + * Listener to listen for changes to {@link #getPrinters} */ public interface OnChangedListener { void onChanged(); diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java index e34247a66fb6d..600af1ff6da4d 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java @@ -21,17 +21,17 @@ import android.content.res.TypedArray; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.text.TextUtils; -import android.util.Pair; +import com.android.printservice.recommendation.R; +import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer; + +import java.net.InetAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import com.android.printservice.recommendation.R; -import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer; - public class ServiceListener implements ServiceResolveQueue.ResolveCallback { private final NsdManager mNSDManager; @@ -176,11 +176,18 @@ public class ServiceListener implements ServiceResolveQueue.ResolveCallback { mListeners.clear(); } - public Pair getCount() { - int count = 0; - for (PrinterHashMap map : mVendorHashMap.values()) { - count += map.size(); + /** + * @return The {@link InetAddress addresses} of the discovered printers + */ + public ArrayList getPrinters() { + ArrayList printerAddressess = new ArrayList<>(); + + for (PrinterHashMap oneVendorPrinters : mVendorHashMap.values()) { + for (NsdServiceInfo printer : oneVendorPrinters.values()) { + printerAddressess.add(printer.getHost()); + } } - return Pair.create(mVendorHashMap.size(), count); + + return printerAddressess; } } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceRecommendationPlugin.java index 7ea530dda9d8b..4e3bf933a5240 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceRecommendationPlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceRecommendationPlugin.java @@ -16,13 +16,17 @@ package com.android.printservice.recommendation.plugin.hp; +import android.annotation.NonNull; import android.content.Context; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; -import android.annotation.NonNull; import android.text.TextUtils; + import com.android.printservice.recommendation.PrintServicePlugin; +import java.net.InetAddress; +import java.util.ArrayList; + public abstract class ServiceRecommendationPlugin implements PrintServicePlugin, ServiceListener.Observer { protected static final String PDL_ATTRIBUTE = "pdl"; @@ -71,7 +75,7 @@ public abstract class ServiceRecommendationPlugin implements PrintServicePlugin, @Override public void dataSetChanged() { synchronized (mLock) { - if (mCallback != null) mCallback.onChanged(getCount()); + if (mCallback != null) mCallback.onChanged(getPrinters()); } } @@ -80,7 +84,7 @@ public abstract class ServiceRecommendationPlugin implements PrintServicePlugin, return TextUtils.equals(vendor, mVendorInfo.mVendorID); } - public int getCount() { - return mListener.getCount().second; + public ArrayList getPrinters() { + return mListener.getPrinters(); } } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mopria/MopriaRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mopria/MopriaRecommendationPlugin.java index 18c9da51865ad..a9e1aed0d624e 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mopria/MopriaRecommendationPlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mopria/MopriaRecommendationPlugin.java @@ -20,12 +20,14 @@ package com.android.printservice.recommendation.plugin.mopria; import android.content.Context; import android.net.nsd.NsdServiceInfo; import android.text.TextUtils; -import android.util.Pair; +import com.android.printservice.recommendation.R; import com.android.printservice.recommendation.plugin.hp.MDnsUtils; import com.android.printservice.recommendation.plugin.hp.ServiceRecommendationPlugin; import com.android.printservice.recommendation.plugin.hp.VendorInfo; -import com.android.printservice.recommendation.R; + +import java.net.InetAddress; +import java.util.ArrayList; public class MopriaRecommendationPlugin extends ServiceRecommendationPlugin { @@ -47,8 +49,7 @@ public class MopriaRecommendationPlugin extends ServiceRecommendationPlugin { } @Override - public int getCount() { - Pair count = mListener.getCount(); - return ((count.first > 1) ? count.second : 0); + public ArrayList getPrinters() { + return mListener.getPrinters(); } } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java index f64eed47f785f..4d0efd8be23d1 100755 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java @@ -19,9 +19,11 @@ import android.content.Context; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.text.TextUtils; + import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer; import com.android.printservice.recommendation.util.NsdResolveQueue; +import java.net.InetAddress; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -192,8 +194,13 @@ class ServiceResolver { } } - public int getCount() { - return mPrinterHashMap.size(); + public ArrayList getPrinters() { + ArrayList printerAddresses = new ArrayList<>(); + for (NsdServiceInfo printer : mPrinterHashMap.values()) { + printerAddresses.add(printer.getHost()); + } + + return printerAddresses; } } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java index 3fb9ca2397160..e0942b7e91a40 100755 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java @@ -15,11 +15,11 @@ */ package com.android.printservice.recommendation.plugin.xerox; +import android.annotation.NonNull; import android.content.Context; import android.net.nsd.NsdManager; -import android.annotation.NonNull; -import com.android.printservice.recommendation.PrintServicePlugin; +import com.android.printservice.recommendation.PrintServicePlugin; import com.android.printservice.recommendation.R; public class XeroxPrintServiceRecommendationPlugin implements PrintServicePlugin, ServiceResolver.Observer { @@ -69,11 +69,9 @@ public class XeroxPrintServiceRecommendationPlugin implements PrintServicePlugin @Override public void dataSetChanged() { synchronized (mLock) { - if (mDiscoveryCallback != null) mDiscoveryCallback.onChanged(getCount()); + if (mDiscoveryCallback != null) { + mDiscoveryCallback.onChanged(mServiceResolver.getPrinters()); + } } } - - public int getCount() { - return mServiceResolver.getCount(); - } } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java index c5dbc8c32e91f..87ab2d3fcf222 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java @@ -15,17 +15,19 @@ */ package com.android.printservice.recommendation.util; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import com.android.printservice.recommendation.PrintServicePlugin; +import java.net.InetAddress; +import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -54,7 +56,7 @@ public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { /** Printer identifiers of the mPrinters found. */ @GuardedBy("mLock") - private final @NonNull HashSet mPrinters; + private final @NonNull HashSet mPrinters; /** Service types discovered by this plugin */ private final @NonNull HashSet mServiceTypes; @@ -111,7 +113,7 @@ public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { */ public void start(@NonNull PrintServicePlugin.PrinterDiscoveryCallback callback) { mCallback = callback; - mCallback.onChanged(mPrinters.size()); + mCallback.onChanged(new ArrayList<>(mPrinters)); for (String serviceType : mServiceTypes) { DiscoveryListenerMultiplexer.addListener(getNDSManager(), serviceType, this); @@ -122,7 +124,7 @@ public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { * Stop the discovery. This can only return once the plugin is completely finished and cleaned up. */ public void stop() { - mCallback.onChanged(0); + mCallback.onChanged(null); mCallback = null; for (int i = 0; i < mServiceTypes.size(); ++i) { @@ -130,14 +132,6 @@ public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { } } - /** - * - * @return The number of discovered printers - */ - public int getCount() { - return mPrinters.size(); - } - @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { Log.w(LOG_TAG, "Failed to start network discovery for type " + serviceType + ": " @@ -174,9 +168,9 @@ public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { public void onServiceResolved(NsdServiceInfo serviceInfo) { if (mPrinterFilter.matchesCriteria(serviceInfo)) { if (mCallback != null) { - boolean added = mPrinters.add(serviceInfo.getHost().getHostAddress()); + boolean added = mPrinters.add(serviceInfo.getHost()); if (added) { - mCallback.onChanged(mPrinters.size()); + mCallback.onChanged(new ArrayList<>(mPrinters)); } } } @@ -198,11 +192,10 @@ public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { public void onServiceResolved(NsdServiceInfo serviceInfo) { if (mPrinterFilter.matchesCriteria(serviceInfo)) { if (mCallback != null) { - boolean removed = mPrinters - .remove(serviceInfo.getHost().getHostAddress()); + boolean removed = mPrinters.remove(serviceInfo.getHost()); if (removed) { - mCallback.onChanged(mPrinters.size()); + mCallback.onChanged(new ArrayList<>(mPrinters)); } } } diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index 7474a64c32cb7..75df892b30b18 100644 --- a/services/print/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java @@ -45,17 +45,17 @@ import android.os.RemoteException; import android.os.UserHandle; import android.print.IPrintDocumentAdapter; import android.print.IPrintJobStateChangeListener; -import android.printservice.recommendation.IRecommendationsChangeListener; import android.print.IPrintServicesChangeListener; import android.print.IPrinterDiscoveryObserver; import android.print.PrintAttributes; import android.print.PrintJobId; import android.print.PrintJobInfo; import android.print.PrintManager; -import android.printservice.recommendation.RecommendationInfo; import android.print.PrinterId; import android.print.PrinterInfo; import android.printservice.PrintServiceInfo; +import android.printservice.recommendation.IRecommendationsChangeListener; +import android.printservice.recommendation.RecommendationInfo; import android.provider.DocumentsContract; import android.provider.Settings; import android.text.TextUtils; @@ -72,8 +72,9 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.BackgroundThread; import com.android.internal.os.SomeArgs; import com.android.server.print.RemotePrintService.PrintServiceCallbacks; +import com.android.server.print.RemotePrintServiceRecommendationService + .RemotePrintServiceRecommendationServiceCallbacks; import com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks; -import com.android.server.print.RemotePrintServiceRecommendationService.RemotePrintServiceRecommendationServiceCallbacks; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -882,7 +883,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, + android.Manifest.permission.BIND_PRINT_SERVICE); continue; } - tempPrintServices.add(PrintServiceInfo.create(installedService, mContext)); + tempPrintServices.add(PrintServiceInfo.create(mContext, installedService)); } mInstalledServices.clear();