Merge "Add Samsung print recommendation plugin." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b4a45472bb
@@ -32,8 +32,15 @@
|
|||||||
<item>Hewlett Packard</item>
|
<item>Hewlett Packard</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="known_print_vendor_info_for_samsung" translatable="false">
|
||||||
|
<item>com.sec.app.samsungprintservice</item>
|
||||||
|
<item>Samsung Electronics</item>
|
||||||
|
<item>Samsung</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<array name="known_print_plugin_vendors" translatable="false">
|
<array name="known_print_plugin_vendors" translatable="false">
|
||||||
<item>@array/known_print_vendor_info_for_mopria</item>
|
<item>@array/known_print_vendor_info_for_mopria</item>
|
||||||
<item>@array/known_print_vendor_info_for_hp</item>
|
<item>@array/known_print_vendor_info_for_hp</item>
|
||||||
|
<item>@array/known_print_vendor_info_for_samsung</item>
|
||||||
</array>
|
</array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<string name="plugin_vendor_brother">Brother</string>
|
<string name="plugin_vendor_brother">Brother</string>
|
||||||
<string name="plugin_vendor_canon">Canon</string>
|
<string name="plugin_vendor_canon">Canon</string>
|
||||||
<string name="plugin_vendor_xerox">Xerox</string>
|
<string name="plugin_vendor_xerox">Xerox</string>
|
||||||
<string name="plugin_vendor_samsung">Samsung Electronics</string>
|
<string name="plugin_vendor_samsung">Samsung</string>
|
||||||
<string name="plugin_vendor_epson">Epson</string>
|
<string name="plugin_vendor_epson">Epson</string>
|
||||||
<string name="plugin_vendor_konica_minolta">Konica Minolta</string>
|
<string name="plugin_vendor_konica_minolta">Konica Minolta</string>
|
||||||
<string name="plugin_vendor_fuji">Fuji</string>
|
<string name="plugin_vendor_fuji">Fuji</string>
|
||||||
|
|||||||
@@ -50,14 +50,6 @@
|
|||||||
</mdns-names>
|
</mdns-names>
|
||||||
</vendor>
|
</vendor>
|
||||||
|
|
||||||
<vendor>
|
|
||||||
<name>@string/plugin_vendor_samsung</name>
|
|
||||||
<package>com.sec.app.samsungprintservice</package>
|
|
||||||
<mdns-names>
|
|
||||||
<mdns-name>Samsung</mdns-name>
|
|
||||||
</mdns-names>
|
|
||||||
</vendor>
|
|
||||||
|
|
||||||
<vendor>
|
<vendor>
|
||||||
<name>@string/plugin_vendor_epson</name>
|
<name>@string/plugin_vendor_epson</name>
|
||||||
<package>com.epson.mobilephone.android.epsonprintserviceplugin</package>
|
<package>com.epson.mobilephone.android.epsonprintserviceplugin</package>
|
||||||
|
|||||||
@@ -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.MDNSFilterPlugin;
|
||||||
import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
|
import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
|
||||||
import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin;
|
import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin;
|
||||||
|
import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -74,6 +75,14 @@ public class RecommendationServiceImpl extends RecommendationService
|
|||||||
" plugin", e);
|
" 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();
|
final int numPlugins = mPlugins.size();
|
||||||
for (int i = 0; i < numPlugins; i++) {
|
for (int i = 0; i < numPlugins; i++) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -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<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 + " "));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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[]{};
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user