Move Xerox recommendation plugin to service.
Only minimal changes just to make it work together with the other
plugins.
Bug: 28908572
Change-Id: Icac226b45e8a6885036466451d0e9f54a3b3c640
(cherry picked from commit d97fdfd943)
This commit is contained in:
@@ -32,12 +32,20 @@
|
||||
<item>Hewlett Packard</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Samsung plugin -->
|
||||
<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>
|
||||
|
||||
<!-- Xerox plugin -->
|
||||
<string-array name="known_print_vendor_info_for_xerox" translatable="false">
|
||||
<item>com.xerox.printservice</item>
|
||||
<item>Xerox</item>
|
||||
<item>Xerox</item>
|
||||
</string-array>
|
||||
|
||||
<array name="known_print_plugin_vendors" translatable="false">
|
||||
<item>@array/known_print_vendor_info_for_mopria</item>
|
||||
<item>@array/known_print_vendor_info_for_hp</item>
|
||||
|
||||
@@ -42,14 +42,6 @@
|
||||
</mdns-names>
|
||||
</vendor>
|
||||
|
||||
<vendor>
|
||||
<name>@string/plugin_vendor_xerox</name>
|
||||
<package>com.xerox.printservice</package>
|
||||
<mdns-names>
|
||||
<mdns-name>Xerox</mdns-name>
|
||||
</mdns-names>
|
||||
</vendor>
|
||||
|
||||
<vendor>
|
||||
<name>@string/plugin_vendor_epson</name>
|
||||
<package>com.epson.mobilephone.android.epsonprintserviceplugin</package>
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugi
|
||||
import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
|
||||
import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin;
|
||||
import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin;
|
||||
import com.android.printservice.recommendation.plugin.xerox.XeroxPrintServiceRecommendationPlugin;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -83,6 +84,14 @@ public class RecommendationServiceImpl extends RecommendationService
|
||||
" plugin", e);
|
||||
}
|
||||
|
||||
try {
|
||||
mPlugins.add(new RemotePrintServicePlugin(
|
||||
new XeroxPrintServiceRecommendationPlugin(this), this, false));
|
||||
} catch (Exception e) {
|
||||
Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_xerox) +
|
||||
" plugin", e);
|
||||
}
|
||||
|
||||
final int numPlugins = mPlugins.size();
|
||||
for (int i = 0; i < numPlugins; i++) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.xerox;
|
||||
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
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__USB_MDL = "usb_MDL";
|
||||
public static final String ATTRIBUTE__MFG = "mfg";
|
||||
public static final String EXCLUDE_FUJI = "fuji";
|
||||
public static final String PDL_ATTRIBUTE = "pdl";
|
||||
|
||||
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 usbMdl = getString(attributes.get(ATTRIBUTE__USB_MDL));
|
||||
String mfg = getString(attributes.get(ATTRIBUTE__MFG));
|
||||
return containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) || containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues) && !(containsString(ty, EXCLUDE_FUJI) || containsString(product, EXCLUDE_FUJI) || containsString(usbMdl, EXCLUDE_FUJI));
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static boolean checkPDLSupport(NsdServiceInfo networkDevice, String[] pdlFormats) {
|
||||
if (pdlFormats == null) return false;
|
||||
|
||||
String pdls = MDnsUtils.getString(networkDevice.getAttributes().get(PDL_ATTRIBUTE));
|
||||
if (pdls != null) {
|
||||
for (String pdl : pdlFormats) {
|
||||
if (pdls.contains(pdl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 String getString(byte[] value) {
|
||||
if (value != null) return new String(value, StandardCharsets.UTF_8);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean containsString(String container, String contained) {
|
||||
return (container != null) && (contained != null) && (container.equalsIgnoreCase(contained) || container.contains(contained + " "));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.xerox;
|
||||
|
||||
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,199 @@
|
||||
/*
|
||||
* 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.xerox;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.text.TextUtils;
|
||||
import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
|
||||
import com.android.printservice.recommendation.util.NsdResolveQueue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
class ServiceResolver {
|
||||
|
||||
private final NsdManager mNSDManager;
|
||||
private final String[] mServiceType;
|
||||
private final Observer mObserver;
|
||||
private final VendorInfo mVendorInfo;
|
||||
private final String[] mPDLs;
|
||||
private final PrinterHashMap mPrinterHashMap = new PrinterHashMap();
|
||||
private final List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
|
||||
private final NsdResolveQueue mNsdResolveQueue;
|
||||
|
||||
public interface Observer {
|
||||
void dataSetChanged();
|
||||
}
|
||||
|
||||
public ServiceResolver(Context context, Observer observer, VendorInfo vendorInfo, String[] serviceTypes, String[] pdls) {
|
||||
mNsdResolveQueue = NsdResolveQueue.getInstance();
|
||||
mObserver = observer;
|
||||
mServiceType = serviceTypes;
|
||||
mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
|
||||
mVendorInfo = vendorInfo;
|
||||
mPDLs = pdls;
|
||||
}
|
||||
|
||||
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) {
|
||||
queueRequest(nsdServiceInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
|
||||
removeRequest(nsdServiceInfo);
|
||||
printerRemoved(nsdServiceInfo);
|
||||
}
|
||||
};
|
||||
DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
|
||||
mListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
for (NsdManager.DiscoveryListener listener : mListeners) {
|
||||
DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
|
||||
}
|
||||
mListeners.clear();
|
||||
clearRequests();
|
||||
}
|
||||
|
||||
//Resolving nsd services
|
||||
private final LinkedList<NsdServiceInfo> mQueue = new LinkedList<>();
|
||||
private final Object mLock = new Object();
|
||||
private NsdServiceInfo mCurrentRequest = null;
|
||||
|
||||
private void queueRequest(NsdServiceInfo serviceInfo) {
|
||||
synchronized (mLock) {
|
||||
if (mQueue.contains(serviceInfo)) return;
|
||||
mQueue.add(serviceInfo);
|
||||
makeNextRequest();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeRequest(NsdServiceInfo serviceInfo) {
|
||||
synchronized (mLock) {
|
||||
mQueue.remove(serviceInfo);
|
||||
if ((mCurrentRequest != null) && serviceInfo.equals(mCurrentRequest))
|
||||
mCurrentRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearRequests() {
|
||||
synchronized (mLock) {
|
||||
mQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void makeNextRequest() {
|
||||
synchronized (mLock) {
|
||||
if (mCurrentRequest != null) return;
|
||||
if (mQueue.isEmpty()) return;
|
||||
mCurrentRequest = mQueue.removeFirst();
|
||||
mNsdResolveQueue.resolve(mNSDManager, mCurrentRequest, 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) {
|
||||
printerFound(nsdServiceInfo);
|
||||
mCurrentRequest = null;
|
||||
}
|
||||
makeNextRequest();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private 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 (String vendorValues : mVendorInfo.mDNSValues) {
|
||||
if (vendor.equalsIgnoreCase(vendorValues)) {
|
||||
vendor = mVendorInfo.mVendorID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((vendor != mVendorInfo.mVendorID) &&
|
||||
MDnsUtils.isVendorPrinter(nsdServiceInfo, mVendorInfo.mDNSValues)) {
|
||||
vendor = mVendorInfo.mVendorID;
|
||||
}
|
||||
|
||||
if (!(vendor == mVendorInfo.mVendorID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MDnsUtils.checkPDLSupport(nsdServiceInfo, mPDLs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mPrinterHashMap.addPrinter(nsdServiceInfo) == null)) {
|
||||
mObserver.dataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void printerRemoved(NsdServiceInfo nsdServiceInfo) {
|
||||
if ((mPrinterHashMap.removePrinter(nsdServiceInfo) != null)) {
|
||||
mObserver.dataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mPrinterHashMap.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.xerox;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
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[]{};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.xerox;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.annotation.NonNull;
|
||||
import com.android.printservice.recommendation.PrintServicePlugin;
|
||||
|
||||
import com.android.printservice.recommendation.R;
|
||||
|
||||
public class XeroxPrintServiceRecommendationPlugin implements PrintServicePlugin, ServiceResolver.Observer {
|
||||
|
||||
protected final Object mLock = new Object();
|
||||
protected PrinterDiscoveryCallback mDiscoveryCallback = null;
|
||||
protected final ServiceResolver mServiceResolver;
|
||||
protected final NsdManager mNSDManager;
|
||||
protected final VendorInfo mVendorInfo;
|
||||
private final int mVendorStringID = R.string.plugin_vendor_xerox;
|
||||
private final String PDL__PDF = "application/pdf";
|
||||
private final String[] mServices = new String[]{"_ipp._tcp"};
|
||||
|
||||
public XeroxPrintServiceRecommendationPlugin(Context context) {
|
||||
mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
|
||||
mVendorInfo = new VendorInfo(context.getResources(), R.array.known_print_vendor_info_for_xerox);
|
||||
mServiceResolver = new ServiceResolver(context, this, mVendorInfo, mServices, new String[]{PDL__PDF});
|
||||
}
|
||||
|
||||
@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) {
|
||||
mDiscoveryCallback = callback;
|
||||
mServiceResolver.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
synchronized (mLock) {
|
||||
mDiscoveryCallback = null;
|
||||
mServiceResolver.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dataSetChanged() {
|
||||
synchronized (mLock) {
|
||||
if (mDiscoveryCallback != null) mDiscoveryCallback.onChanged(getCount());
|
||||
}
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mServiceResolver.getCount();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user