diff options
author | Sergey Yakovlev <s.yakovlev@samsung.com> | 2016-11-18 18:59:47 +0300 |
---|---|---|
committer | Sergey Yakovlev <s.yakovlev@samsung.com> | 2016-11-23 13:26:48 +0300 |
commit | 989c44be2c383568fcd4e4373ed5acb5442a019e (patch) | |
tree | 4d37d962b2930b3c138a397286f9e16f826f864f /packages/PrintRecommendationService/src | |
parent | ebb722d04af4aa8626e32e0e8a9b885b11d03c0f (diff) |
Update Samsung Print Recommendation Plugin (to support Mopria printers)
- Extract common part of MDNSFilterPlugin to common utils, MDNSFilteredDiscovery.java (other vendors can use it too)
- Refactor Samsung Print Recomendation Plugin to use MDNSFilteredDiscovery.java
- Add Mopria devices detection to Samsung Print Recomendation Plugin
*Samsung Print Service Plugin supports Mopria printers since v3.00.161011.
Test: Tested manually. Test app was developed to make sure that Samsung Print Recommendation plugin can find both Samsung and Mopria devices. Additionally MDNSFilterPlugin was tested on HP printers.
Change-Id: Idc0d311171495f879564336370a86f7a8890378b
Diffstat (limited to 'packages/PrintRecommendationService/src')
13 files changed, 541 insertions, 762 deletions
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java index ac60a88e5ca6..1fe5a2a4d40b 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java @@ -78,7 +78,7 @@ public class RecommendationServiceImpl extends RecommendationService try { mPlugins.add(new RemotePrintServicePlugin(new SamsungRecommendationPlugin(this), this, - false)); + true)); } catch (Exception e) { Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_samsung) + " plugin", e); diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mdnsFilter/MDNSFilterPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mdnsFilter/MDNSFilterPlugin.java index a2c0485f3d0a..d60a25f54a22 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mdnsFilter/MDNSFilterPlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mdnsFilter/MDNSFilterPlugin.java @@ -16,30 +16,52 @@ package com.android.printservice.recommendation.plugin.mdnsFilter; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.StringRes; import android.content.Context; -import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; -import android.util.Log; -import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.Preconditions; +import android.annotation.NonNull; +import android.annotation.StringRes; + import com.android.printservice.recommendation.PrintServicePlugin; -import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer; -import com.android.printservice.recommendation.util.NsdResolveQueue; +import com.android.printservice.recommendation.util.MDNSFilteredDiscovery; +import com.android.printservice.recommendation.util.MDNSUtils; import java.util.HashSet; import java.util.List; +import java.util.Set; /** * A plugin listening for mDNS results and only adding the ones that {@link * MDNSUtils#isVendorPrinter match} configured list */ -public class MDNSFilterPlugin implements PrintServicePlugin, NsdManager.DiscoveryListener { - private static final String LOG_TAG = "MDNSFilterPlugin"; +public class MDNSFilterPlugin implements PrintServicePlugin { - private static final String PRINTER_SERVICE_TYPE = "_ipp._tcp"; + /** The mDNS service types supported */ + private static final Set<String> PRINTER_SERVICE_TYPES = new HashSet<String>() {{ + add("_ipp._tcp"); + }}; + + /** + * The printer filter for {@link MDNSFilteredDiscovery} passing only mDNS results + * that {@link MDNSUtils#isVendorPrinter match} configured list + */ + private static class VendorNameFilter implements MDNSFilteredDiscovery.PrinterFilter { + /** mDNS names handled by the print service this plugin is for */ + private final @NonNull Set<String> mMDNSNames; + + /** + * Filter constructor + * + * @param vendorNames The vendor names to pass + */ + VendorNameFilter(@NonNull Set<String> vendorNames) { + mMDNSNames = new HashSet<>(vendorNames); + } + + @Override + public boolean matchesCriteria(NsdServiceInfo nsdServiceInfo) { + return MDNSUtils.isVendorPrinter(nsdServiceInfo, mMDNSNames); + } + } /** Name of the print service this plugin is for */ private final @StringRes int mName; @@ -47,26 +69,8 @@ public class MDNSFilterPlugin implements PrintServicePlugin, NsdManager.Discover /** Package name of the print service this plugin is for */ private final @NonNull CharSequence mPackageName; - /** mDNS names handled by the print service this plugin is for */ - private final @NonNull HashSet<String> mMDNSNames; - - /** Printer identifiers of the mPrinters found. */ - @GuardedBy("mLock") - private final @NonNull HashSet<String> mPrinters; - - /** Context of the user of this plugin */ - private final @NonNull Context mContext; - - /** - * Call back to report the number of mPrinters found. - * - * We assume that {@link #start} and {@link #stop} are never called in parallel, hence it is - * safe to not synchronize access to this field. - */ - private @Nullable PrinterDiscoveryCallback mCallback; - - /** Queue used to resolve nsd infos */ - private final @NonNull NsdResolveQueue mResolveQueue; + /** The mDNS filtered discovery */ + private final MDNSFilteredDiscovery mMDNSFilteredDiscovery; /** * Create new stub that assumes that a print service can be used to print on all mPrinters @@ -79,16 +83,11 @@ public class MDNSFilterPlugin implements PrintServicePlugin, NsdManager.Discover */ public MDNSFilterPlugin(@NonNull Context context, @NonNull String name, @NonNull CharSequence packageName, @NonNull List<String> mDNSNames) { - mContext = Preconditions.checkNotNull(context, "context"); - mName = mContext.getResources().getIdentifier(Preconditions.checkStringNotEmpty(name, - "name"), null, "com.android.printservice.recommendation"); - mPackageName = Preconditions.checkStringNotEmpty(packageName); - mMDNSNames = new HashSet<>(Preconditions - .checkCollectionNotEmpty(Preconditions.checkCollectionElementsNotNull(mDNSNames, - "mDNSNames"), "mDNSNames")); - - mResolveQueue = NsdResolveQueue.getInstance(); - mPrinters = new HashSet<>(); + mName = context.getResources().getIdentifier(name, null, + "com.android.printservice.recommendation"); + mPackageName = packageName; + mMDNSFilteredDiscovery = new MDNSFilteredDiscovery(context, PRINTER_SERVICE_TYPES, + new VendorNameFilter(new HashSet<>(mDNSNames))); } @Override @@ -96,18 +95,9 @@ public class MDNSFilterPlugin implements PrintServicePlugin, NsdManager.Discover return mPackageName; } - /** - * @return The NDS manager - */ - private NsdManager getNDSManager() { - return (NsdManager) mContext.getSystemService(Context.NSD_SERVICE); - } - @Override public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception { - mCallback = callback; - - DiscoveryListenerMultiplexer.addListener(getNDSManager(), PRINTER_SERVICE_TYPE, this); + mMDNSFilteredDiscovery.start(callback); } @Override @@ -117,82 +107,6 @@ public class MDNSFilterPlugin implements PrintServicePlugin, NsdManager.Discover @Override public void stop() throws Exception { - mCallback.onChanged(0); - mCallback = null; - - DiscoveryListenerMultiplexer.removeListener(getNDSManager(), this); - } - - @Override - public void onStartDiscoveryFailed(String serviceType, int errorCode) { - Log.w(LOG_TAG, "Failed to start network discovery for type " + serviceType + ": " - + errorCode); - } - - @Override - public void onStopDiscoveryFailed(String serviceType, int errorCode) { - Log.w(LOG_TAG, "Failed to stop network discovery for type " + serviceType + ": " - + errorCode); - } - - @Override - public void onDiscoveryStarted(String serviceType) { - // empty - } - - @Override - public void onDiscoveryStopped(String serviceType) { - mPrinters.clear(); - } - - @Override - public void onServiceFound(NsdServiceInfo serviceInfo) { - mResolveQueue.resolve(getNDSManager(), serviceInfo, - new NsdManager.ResolveListener() { - @Override - public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { - Log.w(LOG_TAG, "Service found: could not resolve " + serviceInfo + ": " + - errorCode); - } - - @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { - if (MDNSUtils.isVendorPrinter(serviceInfo, mMDNSNames)) { - if (mCallback != null) { - boolean added = mPrinters.add(serviceInfo.getHost().getHostAddress()); - - if (added) { - mCallback.onChanged(mPrinters.size()); - } - } - } - } - }); - } - - @Override - public void onServiceLost(NsdServiceInfo serviceInfo) { - mResolveQueue.resolve(getNDSManager(), serviceInfo, - new NsdManager.ResolveListener() { - @Override - public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { - Log.w(LOG_TAG, "Service lost: Could not resolve " + serviceInfo + ": " - + errorCode); - } - - @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { - if (MDNSUtils.isVendorPrinter(serviceInfo, mMDNSNames)) { - if (mCallback != null) { - boolean removed = mPrinters - .remove(serviceInfo.getHost().getHostAddress()); - - if (removed) { - mCallback.onChanged(mPrinters.size()); - } - } - } - } - }); + mMDNSFilteredDiscovery.stop(); } } diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java deleted file mode 100644 index 963e09b25257..000000000000 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.printservice.recommendation.plugin.samsung; - -import android.net.nsd.NsdServiceInfo; -import android.text.TextUtils; - -import java.nio.charset.StandardCharsets; -import java.util.Locale; -import java.util.Map; - -public class MDnsUtils { - public static final String ATTRIBUTE__TY = "ty"; - public static final String ATTRIBUTE__PRODUCT = "product"; - public static final String ATTRIBUTE__USB_MFG = "usb_MFG"; - public static final String ATTRIBUTE__MFG = "mfg"; - - public static String getString(byte[] value) { - if (value != null) return new String(value,StandardCharsets.UTF_8); - return null; - } - - public static boolean isVendorPrinter(NsdServiceInfo networkDevice, String[] vendorValues) { - - Map<String,byte[]> attributes = networkDevice.getAttributes(); - String product = getString(attributes.get(ATTRIBUTE__PRODUCT)); - String ty = getString(attributes.get(ATTRIBUTE__TY)); - String usbMfg = getString(attributes.get(ATTRIBUTE__USB_MFG)); - String mfg = getString(attributes.get(ATTRIBUTE__MFG)); - return containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) || containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues); - - } - - public static String getVendor(NsdServiceInfo networkDevice) { - String vendor; - - Map<String,byte[]> attributes = networkDevice.getAttributes(); - vendor = getString(attributes.get(ATTRIBUTE__MFG)); - if (!TextUtils.isEmpty(vendor)) return vendor; - vendor = getString(attributes.get(ATTRIBUTE__USB_MFG)); - if (!TextUtils.isEmpty(vendor)) return vendor; - - return null; - } - - private static boolean containsVendor(String container, String[] vendorValues) { - if ((container == null) || (vendorValues == null)) return false; - for (String value : vendorValues) { - if (containsString(container, value) - || containsString(container.toLowerCase(Locale.US), value.toLowerCase(Locale.US)) - || containsString(container.toUpperCase(Locale.US), value.toUpperCase(Locale.US))) - return true; - } - return false; - } - - private static boolean containsString(String container, String contained) { - return (container != null) && (contained != null) && (container.equalsIgnoreCase(contained) || container.contains(contained + " ")); - } -} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterFilterMopria.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterFilterMopria.java new file mode 100644 index 000000000000..d03bb1d76003 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterFilterMopria.java @@ -0,0 +1,63 @@ +/* + * (c) Copyright 2016 Samsung Electronics + * (c) Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.printservice.recommendation.plugin.samsung; + +import android.net.nsd.NsdServiceInfo; +import android.text.TextUtils; +import android.util.Log; + +import com.android.printservice.recommendation.util.MDNSFilteredDiscovery; +import com.android.printservice.recommendation.util.MDNSUtils; + +import java.util.HashSet; +import java.util.Set; + +/** + * Printer filter for Mopria printer models supported by the print service plugin + */ +class PrinterFilterMopria implements MDNSFilteredDiscovery.PrinterFilter { + private static final String TAG = "PrinterFilterMopria"; + + static final Set<String> MOPRIA_MDNS_SERVICES = new HashSet<String>() {{ + add("_ipp._tcp"); + add("_ipps._tcp"); + }}; + + private static final String PDL__PDF = "application/pdf"; + private static final String PDL__PCLM = "application/PCLm"; + private static final String PDL__PWG_RASTER = "image/pwg-raster"; + + private static final String PDL_ATTRIBUTE = "pdl"; + + @Override + public boolean matchesCriteria(NsdServiceInfo nsdServiceInfo) { + if (!MDNSUtils.isSupportedServiceType(nsdServiceInfo, MOPRIA_MDNS_SERVICES)) { + return false; + } + + String pdls = MDNSUtils.getString(nsdServiceInfo.getAttributes().get(PDL_ATTRIBUTE)); + boolean isMatch = !TextUtils.isEmpty(pdls) + && (pdls.contains(PDL__PDF) + || pdls.contains(PDL__PCLM) + || pdls.contains(PDL__PWG_RASTER)); + + if (isMatch) { + Log.d(TAG, "Mopria printer found: " + nsdServiceInfo.getServiceName()); + } + return isMatch; + } +} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterFilterSamsung.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterFilterSamsung.java new file mode 100644 index 000000000000..5b049efcf514 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterFilterSamsung.java @@ -0,0 +1,117 @@ +/* + * (c) Copyright 2016 Samsung Electronics + * (c) Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.printservice.recommendation.plugin.samsung; + +import android.net.nsd.NsdServiceInfo; +import android.annotation.NonNull; +import android.text.TextUtils; +import android.util.Log; + +import com.android.printservice.recommendation.util.MDNSFilteredDiscovery; +import com.android.printservice.recommendation.util.MDNSUtils; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + * Printer filter for Samsung printer models supported by the print service plugin + */ +class PrinterFilterSamsung implements MDNSFilteredDiscovery.PrinterFilter { + private static final String TAG = "PrinterFilterSamsung"; + + static final Set<String> SAMSUNG_MDNS_SERVICES = new HashSet<String>() {{ + add("_pdl-datastream._tcp"); + }}; + + private static final String[] NOT_SUPPORTED_MODELS = new String[]{ + "SCX-5x15", + "SF-555P", + "CF-555P", + "SCX-4x16", + "SCX-4214F", + "CLP-500", + "CJX-", + "MJC-" + }; + private static final String ATTR_USB_MFG = "usb_MFG"; + private static final String ATTR_MFG = "mfg"; + private static final String ATTR_USB_MDL = "usb_MDL"; + private static final String ATTR_MDL = "mdl"; + private static final String ATTR_PRODUCT = "product"; + private static final String ATTR_TY = "ty"; + + private static Set<String> SAMUNG_VENDOR_SET = new HashSet<String>() {{ + add("samsung"); + }}; + + @Override + public boolean matchesCriteria(NsdServiceInfo nsdServiceInfo) { + if (!MDNSUtils.isSupportedServiceType(nsdServiceInfo, SAMSUNG_MDNS_SERVICES)) { + return false; + } + + if (!MDNSUtils.isVendorPrinter(nsdServiceInfo, SAMUNG_VENDOR_SET)) { + return false; + } + + String modelName = getSamsungModelName(nsdServiceInfo); + if (modelName != null && isSupportedSamsungModel(modelName)) { + Log.d(TAG, "Samsung printer found: " + nsdServiceInfo.getServiceName()); + return true; + } + return false; + } + + private boolean isSupportedSamsungModel(String model) { + if (!TextUtils.isEmpty(model)) { + String modelToUpper = model.toUpperCase(Locale.US); + for (String unSupportedPrinter : NOT_SUPPORTED_MODELS) { + if (modelToUpper.contains(unSupportedPrinter)) { + return false; + } + } + } + return true; + } + + private String getSamsungModelName(@NonNull NsdServiceInfo resolvedDevice) { + Map<String,byte[]> attributes = resolvedDevice.getAttributes(); + String usb_mfg = MDNSUtils.getString(attributes.get(ATTR_USB_MFG)); + if (TextUtils.isEmpty(usb_mfg)) { + usb_mfg = MDNSUtils.getString(attributes.get(ATTR_MFG)); + } + + String usb_mdl = MDNSUtils.getString(attributes.get(ATTR_USB_MDL)); + if (TextUtils.isEmpty(usb_mdl)) { + usb_mdl = MDNSUtils.getString(attributes.get(ATTR_MDL)); + } + + String modelName; + if (!TextUtils.isEmpty(usb_mfg) && !TextUtils.isEmpty(usb_mdl)) { + modelName = usb_mfg.trim() + " " + usb_mdl.trim(); + } else { + modelName = MDNSUtils.getString(attributes.get(ATTR_PRODUCT)); + if (TextUtils.isEmpty(modelName)) { + modelName = MDNSUtils.getString(attributes.get(ATTR_TY)); + } + } + + return modelName; + } +} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java deleted file mode 100644 index 032fe22dd744..000000000000 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.printservice.recommendation.plugin.samsung; - -import android.net.nsd.NsdServiceInfo; - -import java.util.HashMap; - -final class PrinterHashMap extends HashMap<String, NsdServiceInfo> { - public static String getKey(NsdServiceInfo serviceInfo) { - return serviceInfo.getServiceName(); - } - public NsdServiceInfo addPrinter(NsdServiceInfo device) { - return put(getKey(device), device); - } - public NsdServiceInfo removePrinter(NsdServiceInfo device) { - return remove(getKey(device)); - } -} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java index e5b8a0f15f2e..eeb51229e7de 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java @@ -1,102 +1,69 @@ -/*
-(c) Copyright 2016 Samsung Electronics..
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-
-package com.android.printservice.recommendation.plugin.samsung;
-
-import android.content.Context;
-import android.net.nsd.NsdServiceInfo;
-import android.text.TextUtils;
-
-import java.util.Locale;
-import java.util.Map;
-
-import com.android.printservice.recommendation.R;
-
-public class SamsungRecommendationPlugin extends ServiceRecommendationPlugin {
-
- private static final String TAG = "SamsungRecommendation";
-
- private static final String ATTR_USB_MFG = "usb_MFG";
- private static final String ATTR_MFG = "mfg";
- private static final String ATTR_USB_MDL = "usb_MDL";
- private static final String ATTR_MDL = "mdl";
- private static final String ATTR_PRODUCT = "product";
- private static final String ATTR_TY = "ty";
-
- private static String[] mNotSupportedDevices = new String[]{
- "SCX-5x15",
- "SF-555P",
- "CF-555P",
- "SCX-4x16",
- "SCX-4214F",
- "CLP-500",
- "CJX-",
- "MJC-"
- };
-
- private static boolean isSupportedModel(String model) {
- if (!TextUtils.isEmpty(model)) {
- String modelToUpper = model.toUpperCase(Locale.US);
- for (String unSupportedPrinter : mNotSupportedDevices) {
- if (modelToUpper.contains(unSupportedPrinter)) {
- return false;
- }
- }
- }
- return true;
- }
-
- public SamsungRecommendationPlugin(Context context) {
- super(context, R.string.plugin_vendor_samsung, new VendorInfo(context.getResources(), R.array.known_print_vendor_info_for_samsung), new String[]{"_pdl-datastream._tcp"});
- }
-
- @Override
- public boolean matchesCriteria(String vendor, NsdServiceInfo nsdServiceInfo) {
- if (!TextUtils.equals(vendor, mVendorInfo.mVendorID)) return false;
-
- String modelName = getModelName(nsdServiceInfo);
- if (modelName != null) {
- return (isSupportedModel(modelName));
- }
- return false;
- }
-
- private String getModelName(NsdServiceInfo resolvedDevice) {
- Map<String,byte[]> attributes = resolvedDevice.getAttributes();
- String usb_mfg = MDnsUtils.getString(attributes.get(ATTR_USB_MFG));
- if (TextUtils.isEmpty(usb_mfg)) {
- usb_mfg = MDnsUtils.getString(attributes.get(ATTR_MFG));
- }
-
- String usb_mdl = MDnsUtils.getString(attributes.get(ATTR_USB_MDL));
- if (TextUtils.isEmpty(usb_mdl)) {
- usb_mdl = MDnsUtils.getString(attributes.get(ATTR_MDL));
- }
-
- String modelName = null;
- if (!TextUtils.isEmpty(usb_mfg) && !TextUtils.isEmpty(usb_mdl)) {
- modelName = usb_mfg.trim() + " " + usb_mdl.trim();
- } else {
- modelName = MDnsUtils.getString(attributes.get(ATTR_PRODUCT));
- if (TextUtils.isEmpty(modelName)) {
- modelName = MDnsUtils.getString(attributes.get(ATTR_TY));
- }
- }
-
- return modelName;
- }
-}
+/* + * (c) Copyright 2016 Samsung Electronics + * (c) Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.printservice.recommendation.plugin.samsung; + +import android.content.Context; +import android.net.nsd.NsdServiceInfo; +import android.annotation.NonNull; + +import com.android.printservice.recommendation.PrintServicePlugin; +import com.android.printservice.recommendation.R; +import com.android.printservice.recommendation.util.MDNSFilteredDiscovery; + +import java.util.HashSet; +import java.util.Set; + +public class SamsungRecommendationPlugin implements PrintServicePlugin { + private static final Set<String> ALL_MDNS_SERVICES = new HashSet<String>() {{ + addAll(PrinterFilterMopria.MOPRIA_MDNS_SERVICES); + addAll(PrinterFilterSamsung.SAMSUNG_MDNS_SERVICES); + }}; + + private final @NonNull Context mContext; + private final @NonNull MDNSFilteredDiscovery mMDNSFilteredDiscovery; + + private final @NonNull PrinterFilterSamsung mPrinterFilterSamsung = new PrinterFilterSamsung(); + private final @NonNull PrinterFilterMopria mPrinterFilterMopria = new PrinterFilterMopria(); + + public SamsungRecommendationPlugin(@NonNull Context context) { + mContext = context; + mMDNSFilteredDiscovery = new MDNSFilteredDiscovery(context, ALL_MDNS_SERVICES, + (NsdServiceInfo nsdServiceInfo) -> + mPrinterFilterSamsung.matchesCriteria(nsdServiceInfo) || + mPrinterFilterMopria.matchesCriteria(nsdServiceInfo)); + } + + @Override + public int getName() { + return R.string.plugin_vendor_samsung; + } + + @Override + public @NonNull CharSequence getPackageName() { + return mContext.getString(R.string.plugin_package_samsung); + } + + @Override + public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception { + mMDNSFilteredDiscovery.start(callback); + } + + @Override + public void stop() throws Exception { + mMDNSFilteredDiscovery.stop(); + } +} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java deleted file mode 100644 index 7bb83c9384f7..000000000000 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.printservice.recommendation.plugin.samsung; - -import android.content.Context; -import android.content.res.TypedArray; -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.text.TextUtils; -import android.util.Pair; - -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; - private final Map<String, VendorInfo> mVendorInfoHashMap; - private final String[] mServiceType; - private final Observer mObserver; - private final ServiceResolveQueue mResolveQueue; - private List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>(); - public HashMap<String, PrinterHashMap> mVendorHashMap = new HashMap<>(); - - public interface Observer { - boolean matchesCriteria(String vendor, NsdServiceInfo serviceInfo); - void dataSetChanged(); - } - - public ServiceListener(Context context, Observer observer, String[] serviceTypes) { - mObserver = observer; - mServiceType = serviceTypes; - mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE); - mResolveQueue = ServiceResolveQueue.getInstance(mNSDManager); - - Map<String, VendorInfo> vendorInfoMap = new HashMap<>(); - TypedArray testArray = context.getResources().obtainTypedArray(R.array.known_print_plugin_vendors); - for(int i = 0; i < testArray.length(); i++) { - int arrayID = testArray.getResourceId(i, 0); - if (arrayID != 0) { - VendorInfo info = new VendorInfo(context.getResources(), arrayID); - vendorInfoMap.put(info.mVendorID, info); - vendorInfoMap.put(info.mPackageName, info); - } - } - testArray.recycle(); - mVendorInfoHashMap = vendorInfoMap; - } - - @Override - public void serviceResolved(NsdServiceInfo nsdServiceInfo) { - printerFound(nsdServiceInfo); - } - - private synchronized void printerFound(NsdServiceInfo nsdServiceInfo) { - if (nsdServiceInfo == null) return; - if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return; - String vendor = MDnsUtils.getVendor(nsdServiceInfo); - if (vendor == null) vendor = ""; - for(Map.Entry<String,VendorInfo> entry : mVendorInfoHashMap.entrySet()) { - for(String vendorValues : entry.getValue().mDNSValues) { - if (vendor.equalsIgnoreCase(vendorValues)) { - vendor = entry.getValue().mVendorID; - break; - } - } - // intentional pointer check - //noinspection StringEquality - if ((vendor != entry.getValue().mVendorID) && - MDnsUtils.isVendorPrinter(nsdServiceInfo, entry.getValue().mDNSValues)) { - vendor = entry.getValue().mVendorID; - } - // intentional pointer check - //noinspection StringEquality - if (vendor == entry.getValue().mVendorID) break; - } - - if (TextUtils.isEmpty(vendor)) { - return; - } - - if (!mObserver.matchesCriteria(vendor, nsdServiceInfo)) - return; - boolean mapsChanged; - - PrinterHashMap vendorHash = mVendorHashMap.get(vendor); - if (vendorHash == null) { - vendorHash = new PrinterHashMap(); - } - mapsChanged = (vendorHash.addPrinter(nsdServiceInfo) == null); - mVendorHashMap.put(vendor, vendorHash); - - if (mapsChanged) { - mObserver.dataSetChanged(); - } - } - - private synchronized void printerRemoved(NsdServiceInfo nsdServiceInfo) { - boolean wasRemoved = false; - Set<String> vendors = mVendorHashMap.keySet(); - for(String vendor : vendors) { - PrinterHashMap map = mVendorHashMap.get(vendor); - wasRemoved |= (map.removePrinter(nsdServiceInfo) != null); - if (map.isEmpty()) wasRemoved |= (mVendorHashMap.remove(vendor) != null); - } - if (wasRemoved) { - mObserver.dataSetChanged(); - } - } - - public void start() { - stop(); - for(final String service :mServiceType) { - NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() { - @Override - public void onStartDiscoveryFailed(String s, int i) { - - } - - @Override - public void onStopDiscoveryFailed(String s, int i) { - - } - - @Override - public void onDiscoveryStarted(String s) { - - } - - @Override - public void onDiscoveryStopped(String s) { - - } - - @Override - public void onServiceFound(NsdServiceInfo nsdServiceInfo) { - mResolveQueue.queueRequest(nsdServiceInfo, ServiceListener.this); - } - - @Override - public void onServiceLost(NsdServiceInfo nsdServiceInfo) { - mResolveQueue.removeRequest(nsdServiceInfo, ServiceListener.this); - printerRemoved(nsdServiceInfo); - } - }; - DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener); - mListeners.add(listener); - } - } - - public void stop() { - for(NsdManager.DiscoveryListener listener : mListeners) { - DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener); - } - mVendorHashMap.clear(); - mListeners.clear(); - } - - public Pair<Integer, Integer> getCount() { - int count = 0; - for (PrinterHashMap map : mVendorHashMap.values()) { - count += map.size(); - } - return Pair.create(mVendorHashMap.size(), count); - } -} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java deleted file mode 100644 index 9d15f3054ee2..000000000000 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.printservice.recommendation.plugin.samsung; - -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; - -public abstract class ServiceRecommendationPlugin implements PrintServicePlugin, ServiceListener.Observer { - - protected static final String PDL_ATTRIBUTE = "pdl"; - - protected final Object mLock = new Object(); - protected PrinterDiscoveryCallback mCallback = null; - protected final ServiceListener mListener; - protected final NsdManager mNSDManager; - protected final VendorInfo mVendorInfo; - private final int mVendorStringID; - - protected ServiceRecommendationPlugin(Context context, int vendorStringID, VendorInfo vendorInfo, String[] services) { - mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE); - mVendorStringID = vendorStringID; - mVendorInfo = vendorInfo; - mListener = new ServiceListener(context, this, services); - } - - @Override - public int getName() { - return mVendorStringID; - } - - @NonNull - @Override - public CharSequence getPackageName() { - return mVendorInfo.mPackageName; - } - - @Override - public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception { - synchronized (mLock) { - mCallback = callback; - } - mListener.start(); - } - - @Override - public void stop() throws Exception { - synchronized (mLock) { - mCallback = null; - } - mListener.stop(); - } - - @Override - public void dataSetChanged() { - synchronized (mLock) { - if (mCallback != null) mCallback.onChanged(getCount()); - } - } - - @Override - public boolean matchesCriteria(String vendor, NsdServiceInfo nsdServiceInfo) { - return TextUtils.equals(vendor, mVendorInfo.mVendorID); - } - - public int getCount() { - return mListener.getCount().second; - } -} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java deleted file mode 100644 index e5691b734416..000000000000 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.printservice.recommendation.plugin.samsung; - -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.util.Pair; -import com.android.printservice.recommendation.util.NsdResolveQueue; - -import java.util.LinkedList; - -final class ServiceResolveQueue { - - private final NsdManager mNsdManager; - private final LinkedList<Pair<NsdServiceInfo, ResolveCallback>> mQueue = new LinkedList<>(); - private final Object mLock = new Object(); - - private static Object sLock = new Object(); - private static ServiceResolveQueue sInstance = null; - private final NsdResolveQueue mNsdResolveQueue; - private Pair<NsdServiceInfo, ResolveCallback> mCurrentRequest = null; - - public static void createInstance(NsdManager nsdManager) { - if (sInstance == null) sInstance = new ServiceResolveQueue(nsdManager); - } - - public static ServiceResolveQueue getInstance(NsdManager nsdManager) { - synchronized (sLock) { - createInstance(nsdManager); - return sInstance; - } - } - - public static void destroyInstance() { - sInstance = null; - } - - public interface ResolveCallback { - void serviceResolved(NsdServiceInfo nsdServiceInfo); - } - - public ServiceResolveQueue(NsdManager nsdManager) { - mNsdManager = nsdManager; - mNsdResolveQueue = NsdResolveQueue.getInstance(); - } - - public void queueRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) { - synchronized (mLock) { - Pair<NsdServiceInfo, ResolveCallback> newRequest = Pair.create(serviceInfo, callback); - if (mQueue.contains(newRequest)) return; - mQueue.add(newRequest); - makeNextRequest(); - } - } - - public void removeRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) { - synchronized (mLock) { - Pair<NsdServiceInfo, ResolveCallback> newRequest = Pair.create(serviceInfo, callback); - mQueue.remove(newRequest); - if ((mCurrentRequest != null) && newRequest.equals(mCurrentRequest)) mCurrentRequest = null; - } - } - - private void makeNextRequest() { - synchronized (mLock) { - if (mCurrentRequest != null) return; - if (mQueue.isEmpty()) return; - mCurrentRequest = mQueue.removeFirst(); - mNsdResolveQueue.resolve(mNsdManager, mCurrentRequest.first, - new NsdManager.ResolveListener() { - @Override - public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) { - synchronized (mLock) { - if (mCurrentRequest != null) mQueue.add(mCurrentRequest); - makeNextRequest(); - } - } - - @Override - public void onServiceResolved(NsdServiceInfo nsdServiceInfo) { - synchronized (mLock) { - if (mCurrentRequest != null) { - mCurrentRequest.second.serviceResolved(nsdServiceInfo); - mCurrentRequest = null; - } - makeNextRequest(); - } - } - }); - - } - } - - -} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java deleted file mode 100644 index 0ebb4e441f11..000000000000 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.printservice.recommendation.plugin.samsung; - -import android.content.res.Resources; - -import java.util.Arrays; - -public final class VendorInfo { - - public final String mPackageName; - public final String mVendorID; - public final String[] mDNSValues; - public final int mID; - - public VendorInfo(Resources resources, int vendor_info_id) { - mID = vendor_info_id; - String[] data = resources.getStringArray(vendor_info_id); - if ((data == null) || (data.length < 2)) { - data = new String[] { null, null }; - } - mPackageName = data[0]; - mVendorID = data[1]; - mDNSValues = (data.length > 2) ? Arrays.copyOfRange(data, 2, data.length) : new String[]{}; - } -} diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java new file mode 100644 index 000000000000..c5dbc8c32e91 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.printservice.recommendation.util; + +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.util.HashSet; +import java.util.Set; + +/** + * A discovery listening for mDNS results and only adding the ones that {@link + * PrinterFilter#matchesCriteria match} configured list + */ +public class MDNSFilteredDiscovery implements NsdManager.DiscoveryListener { + private static final String LOG_TAG = "MDNSFilteredDiscovery"; + + /** + * mDNS service filter interface. + * Implement {@link PrinterFilter#matchesCriteria} to filter out supported services + */ + public interface PrinterFilter { + /** + * Main filter method. Should return true if mDNS service is supported + * by the print service plugin + * + * @param nsdServiceInfo The service info to check + * + * @return True if service is supported by the print service plugin + */ + boolean matchesCriteria(NsdServiceInfo nsdServiceInfo); + } + + /** Printer identifiers of the mPrinters found. */ + @GuardedBy("mLock") + private final @NonNull HashSet<String> mPrinters; + + /** Service types discovered by this plugin */ + private final @NonNull HashSet<String> mServiceTypes; + + /** Context of the user of this plugin */ + private final @NonNull Context mContext; + + /** mDNS services filter */ + private final @NonNull PrinterFilter mPrinterFilter; + + /** + * Call back to report the number of mPrinters found. + * + * We assume that {@link #start} and {@link #stop} are never called in parallel, hence it is + * safe to not synchronize access to this field. + */ + private @Nullable PrintServicePlugin.PrinterDiscoveryCallback mCallback; + + /** Queue used to resolve nsd infos */ + private final @NonNull NsdResolveQueue mResolveQueue; + + /** + * Create new stub that assumes that a print service can be used to print on all mPrinters + * matching some mDNS names. + * + * @param context The context the plugin runs in + * @param serviceTypes The mDNS service types to listen to. + * @param printerFilter The filter for mDNS services + */ + public MDNSFilteredDiscovery(@NonNull Context context, + @NonNull Set<String> serviceTypes, + @NonNull PrinterFilter printerFilter) { + mContext = Preconditions.checkNotNull(context, "context"); + mServiceTypes = new HashSet<>(Preconditions + .checkCollectionNotEmpty(Preconditions.checkCollectionElementsNotNull(serviceTypes, + "serviceTypes"), "serviceTypes")); + mPrinterFilter = Preconditions.checkNotNull(printerFilter, "printerFilter"); + + mResolveQueue = NsdResolveQueue.getInstance(); + mPrinters = new HashSet<>(); + } + + /** + * @return The NDS manager + */ + private NsdManager getNDSManager() { + return (NsdManager) mContext.getSystemService(Context.NSD_SERVICE); + } + + /** + * Start the discovery. + * + * @param callback Callbacks used by this plugin. + */ + public void start(@NonNull PrintServicePlugin.PrinterDiscoveryCallback callback) { + mCallback = callback; + mCallback.onChanged(mPrinters.size()); + + for (String serviceType : mServiceTypes) { + DiscoveryListenerMultiplexer.addListener(getNDSManager(), serviceType, this); + } + } + + /** + * Stop the discovery. This can only return once the plugin is completely finished and cleaned up. + */ + public void stop() { + mCallback.onChanged(0); + mCallback = null; + + for (int i = 0; i < mServiceTypes.size(); ++i) { + DiscoveryListenerMultiplexer.removeListener(getNDSManager(), this); + } + } + + /** + * + * @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 + ": " + + errorCode); + } + + @Override + public void onStopDiscoveryFailed(String serviceType, int errorCode) { + Log.w(LOG_TAG, "Failed to stop network discovery for type " + serviceType + ": " + + errorCode); + } + + @Override + public void onDiscoveryStarted(String serviceType) { + // empty + } + + @Override + public void onDiscoveryStopped(String serviceType) { + mPrinters.clear(); + } + + @Override + public void onServiceFound(NsdServiceInfo serviceInfo) { + mResolveQueue.resolve(getNDSManager(), serviceInfo, + new NsdManager.ResolveListener() { + @Override + public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { + Log.w(LOG_TAG, "Service found: could not resolve " + serviceInfo + ": " + + errorCode); + } + + @Override + public void onServiceResolved(NsdServiceInfo serviceInfo) { + if (mPrinterFilter.matchesCriteria(serviceInfo)) { + if (mCallback != null) { + boolean added = mPrinters.add(serviceInfo.getHost().getHostAddress()); + if (added) { + mCallback.onChanged(mPrinters.size()); + } + } + } + } + }); + } + + @Override + public void onServiceLost(NsdServiceInfo serviceInfo) { + mResolveQueue.resolve(getNDSManager(), serviceInfo, + new NsdManager.ResolveListener() { + @Override + public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { + Log.w(LOG_TAG, "Service lost: Could not resolve " + serviceInfo + ": " + + errorCode); + } + + @Override + public void onServiceResolved(NsdServiceInfo serviceInfo) { + if (mPrinterFilter.matchesCriteria(serviceInfo)) { + if (mCallback != null) { + boolean removed = mPrinters + .remove(serviceInfo.getHost().getHostAddress()); + + if (removed) { + mCallback.onChanged(mPrinters.size()); + } + } + } + } + }); + } +}
\ No newline at end of file diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mdnsFilter/MDNSUtils.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSUtils.java index 4c27a47e144f..a6df3c8f2c24 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/mdnsFilter/MDNSUtils.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.android.printservice.recommendation.plugin.mdnsFilter; +package com.android.printservice.recommendation.util; import android.annotation.NonNull; import android.net.nsd.NsdServiceInfo; @@ -27,12 +27,15 @@ import java.util.Set; /** * Utils for dealing with mDNS attributes */ -class MDNSUtils { +public class MDNSUtils { public static final String ATTRIBUTE_TY = "ty"; public static final String ATTRIBUTE_PRODUCT = "product"; public static final String ATTRIBUTE_USB_MFG = "usb_mfg"; public static final String ATTRIBUTE_MFG = "mfg"; + private MDNSUtils() { + } + /** * Check if the service has any of a set of vendor names. * @@ -95,4 +98,35 @@ class MDNSUtils { private static boolean containsString(@NonNull String container, @NonNull String contained) { return container.equalsIgnoreCase(contained) || container.contains(contained + " "); } + + /** + * Return String from mDNS attribute byte array + * + * @param value the byte array with string data + * + * @return constructed string + */ + public static String getString(byte[] value) { + if (value != null) return new String(value, StandardCharsets.UTF_8); + return null; + } + + /** + * Check if service has a type of supported types set + * + * @param serviceInfo The service + * @param serviceTypes The supported service types set + * + * @return true if service has a type of supported types set + */ + public static boolean isSupportedServiceType(@NonNull NsdServiceInfo serviceInfo, + @NonNull Set<String> serviceTypes) { + String curType = serviceInfo.getServiceType().toLowerCase(); + for (String type : serviceTypes) { + if (curType.contains(type.toLowerCase())) { + return true; + } + } + return false; + } } |