From a26b775dc132b135fa23ab17c39c08955e291da2 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 23 May 2016 10:33:57 -0700 Subject: [PATCH] Add Samsung print recommendation plugin. The code follows the same pattern as the HP and Mopria plugins. As this code is contributed by a 3rd I'd rather submit this as is and let the original submitter clean it up once it appears in AOSP. The code should not affect anything outside of the package it is in. In the package the code is strongly isolated so that one plugin cannot cause issues with another plugin. The code was minimally tested on a Samsung SCX-3406FW . Bug: 28908572 Change-Id: I33c2673d06711902dbd0f1d82563cf5d3fbfe86a (cherry picked from commit 83defde08560ae2f1c3426466a2aa3e6944d6b79) --- .../res/values/donottranslate.xml | 7 + .../res/values/strings.xml | 2 +- .../res/xml/vendorconfigs.xml | 8 - .../RecommendationServiceImpl.java | 9 + .../plugin/samsung/MDnsUtils.java | 74 +++++++ .../plugin/samsung/PrinterHashMap.java | 33 ++++ .../samsung/SamsungRecommendationPlugin.java | 102 ++++++++++ .../plugin/samsung/ServiceListener.java | 186 ++++++++++++++++++ .../samsung/ServiceRecommendationPlugin.java | 86 ++++++++ .../plugin/samsung/ServiceResolveQueue.java | 109 ++++++++++ .../plugin/samsung/VendorInfo.java | 40 ++++ 11 files changed, 647 insertions(+), 9 deletions(-) create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java create mode 100644 packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java diff --git a/packages/PrintRecommendationService/res/values/donottranslate.xml b/packages/PrintRecommendationService/res/values/donottranslate.xml index 68effbfbdf355..86027cda405a6 100644 --- a/packages/PrintRecommendationService/res/values/donottranslate.xml +++ b/packages/PrintRecommendationService/res/values/donottranslate.xml @@ -32,8 +32,15 @@ Hewlett Packard + + com.sec.app.samsungprintservice + Samsung Electronics + Samsung + + @array/known_print_vendor_info_for_mopria @array/known_print_vendor_info_for_hp + @array/known_print_vendor_info_for_samsung diff --git a/packages/PrintRecommendationService/res/values/strings.xml b/packages/PrintRecommendationService/res/values/strings.xml index 97281de5b4ecd..348fcace90c57 100644 --- a/packages/PrintRecommendationService/res/values/strings.xml +++ b/packages/PrintRecommendationService/res/values/strings.xml @@ -23,7 +23,7 @@ Brother Canon Xerox - Samsung Electronics + Samsung Epson Konica Minolta Fuji diff --git a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml index b7925df07b7e8..108ea66c404e8 100644 --- a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml +++ b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml @@ -50,14 +50,6 @@ - - @string/plugin_vendor_samsung - com.sec.app.samsungprintservice - - Samsung - - - @string/plugin_vendor_epson com.epson.mobilephone.android.epsonprintserviceplugin diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java index 4b4b47084b820..d95654f7a2475 100644 --- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java @@ -25,6 +25,7 @@ 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 org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -74,6 +75,14 @@ public class RecommendationServiceImpl extends RecommendationService " plugin", e); } + try { + mPlugins.add(new RemotePrintServicePlugin(new SamsungRecommendationPlugin(this), this, + false)); + } catch (Exception e) { + Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_samsung) + + " plugin", e); + } + final int numPlugins = mPlugins.size(); for (int i = 0; i < numPlugins; i++) { try { 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 new file mode 100644 index 0000000000000..963e09b252572 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java @@ -0,0 +1,74 @@ +/* + * 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 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 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/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java new file mode 100644 index 0000000000000..032fe22dd7443 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java @@ -0,0 +1,33 @@ +/* + * 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 { + 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 new file mode 100644 index 0000000000000..e5b8a0f15f2e0 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java @@ -0,0 +1,102 @@ +/* +(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 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; + } +} 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 new file mode 100644 index 0000000000000..7bb83c9384f75 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java @@ -0,0 +1,186 @@ +/* + * 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 mVendorInfoHashMap; + private final String[] mServiceType; + private final Observer mObserver; + private final ServiceResolveQueue mResolveQueue; + private List mListeners = new ArrayList<>(); + public HashMap 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 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 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 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 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 new file mode 100644 index 0000000000000..9d15f3054ee26 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java @@ -0,0 +1,86 @@ +/* + * 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 new file mode 100644 index 0000000000000..e5691b7344162 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java @@ -0,0 +1,109 @@ +/* + * 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> 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 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 newRequest = Pair.create(serviceInfo, callback); + if (mQueue.contains(newRequest)) return; + mQueue.add(newRequest); + makeNextRequest(); + } + } + + public void removeRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) { + synchronized (mLock) { + Pair 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 new file mode 100644 index 0000000000000..0ebb4e441f115 --- /dev/null +++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java @@ -0,0 +1,40 @@ +/* + * 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[]{}; + } +}