1/*
2 * (c) Copyright 2016 Mopria Alliance, Inc.
3 * (c) Copyright 2016 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.printservice.recommendation.plugin.mdnsFilter;
19
20import android.annotation.NonNull;
21import android.net.nsd.NsdServiceInfo;
22
23import java.nio.charset.StandardCharsets;
24import java.util.Map;
25import java.util.Set;
26
27/**
28 * Utils for dealing with mDNS attributes
29 */
30class MDNSUtils {
31    public static final String ATTRIBUTE_TY = "ty";
32    public static final String ATTRIBUTE_PRODUCT = "product";
33    public static final String ATTRIBUTE_USB_MFG = "usb_mfg";
34    public static final String ATTRIBUTE_MFG = "mfg";
35
36    /**
37     * Check if the service has any of a set of vendor names.
38     *
39     * @param serviceInfo The service
40     * @param vendorNames The vendors
41     *
42     * @return true iff the has any of the set of vendor names
43     */
44    public static boolean isVendorPrinter(@NonNull NsdServiceInfo serviceInfo,
45            @NonNull Set<String> vendorNames) {
46        for (Map.Entry<String, byte[]> entry : serviceInfo.getAttributes().entrySet()) {
47            // keys are case insensitive
48            String key = entry.getKey().toLowerCase();
49
50            switch (key) {
51                case ATTRIBUTE_TY:
52                case ATTRIBUTE_PRODUCT:
53                case ATTRIBUTE_USB_MFG:
54                case ATTRIBUTE_MFG:
55                    if (entry.getValue() != null) {
56                        if (containsVendor(new String(entry.getValue(), StandardCharsets.UTF_8),
57                                vendorNames)) {
58                            return true;
59                        }
60                    }
61                    break;
62                default:
63                    break;
64            }
65        }
66
67        return false;
68    }
69
70    /**
71     * Check if the attribute matches any of the vendor names, ignoring capitalization.
72     *
73     * @param attr        The attribute
74     * @param vendorNames The vendor names
75     *
76     * @return true iff the attribute matches any of the vendor names
77     */
78    private static boolean containsVendor(@NonNull String attr, @NonNull Set<String> vendorNames) {
79        for (String name : vendorNames) {
80            if (containsString(attr.toLowerCase(), name.toLowerCase())) {
81                return true;
82            }
83        }
84        return false;
85    }
86
87    /**
88     * Check if a string in another string.
89     *
90     * @param container The string that contains the string
91     * @param contained The string that is contained
92     *
93     * @return true if the string is contained in the other
94     */
95    private static boolean containsString(@NonNull String container, @NonNull String contained) {
96        return container.equalsIgnoreCase(contained) || container.contains(contained + " ");
97    }
98}
99