• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.connectivity.mdns;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.net.Network;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.text.TextUtils;
25 import android.util.ArraySet;
26 
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Objects;
31 import java.util.Set;
32 
33 /**
34  * API configuration parameters for searching the mDNS service.
35  *
36  * <p>Use {@link MdnsSearchOptions.Builder} to create {@link MdnsSearchOptions}.
37  *
38  * @hide
39  */
40 public class MdnsSearchOptions implements Parcelable {
41 
42     /** @hide */
43     public static final Parcelable.Creator<MdnsSearchOptions> CREATOR =
44             new Parcelable.Creator<MdnsSearchOptions>() {
45                 @Override
46                 public MdnsSearchOptions createFromParcel(Parcel source) {
47                     return new MdnsSearchOptions(source.createStringArrayList(),
48                             source.readBoolean(), source.readBoolean(),
49                             source.readParcelable(null),
50                             source.readString());
51                 }
52 
53                 @Override
54                 public MdnsSearchOptions[] newArray(int size) {
55                     return new MdnsSearchOptions[size];
56                 }
57             };
58     private static MdnsSearchOptions defaultOptions;
59     private final List<String> subtypes;
60     @Nullable
61     private final String resolveInstanceName;
62 
63     private final boolean isPassiveMode;
64     private final boolean removeExpiredService;
65     // The target network for searching. Null network means search on all possible interfaces.
66     @Nullable private final Network mNetwork;
67 
68     /** Parcelable constructs for a {@link MdnsSearchOptions}. */
MdnsSearchOptions(List<String> subtypes, boolean isPassiveMode, boolean removeExpiredService, @Nullable Network network, @Nullable String resolveInstanceName)69     MdnsSearchOptions(List<String> subtypes, boolean isPassiveMode, boolean removeExpiredService,
70             @Nullable Network network, @Nullable String resolveInstanceName) {
71         this.subtypes = new ArrayList<>();
72         if (subtypes != null) {
73             this.subtypes.addAll(subtypes);
74         }
75         this.isPassiveMode = isPassiveMode;
76         this.removeExpiredService = removeExpiredService;
77         mNetwork = network;
78         this.resolveInstanceName = resolveInstanceName;
79     }
80 
81     /** Returns a {@link Builder} for {@link MdnsSearchOptions}. */
newBuilder()82     public static Builder newBuilder() {
83         return new Builder();
84     }
85 
86     /** Returns a default search options. */
getDefaultOptions()87     public static synchronized MdnsSearchOptions getDefaultOptions() {
88         if (defaultOptions == null) {
89             defaultOptions = newBuilder().build();
90         }
91         return defaultOptions;
92     }
93 
94     /** @return the list of subtypes to search. */
getSubtypes()95     public List<String> getSubtypes() {
96         return subtypes;
97     }
98 
99     /**
100      * @return {@code true} if the passive mode is used. The passive mode scans less frequently in
101      * order to conserve battery and produce less network traffic.
102      */
isPassiveMode()103     public boolean isPassiveMode() {
104         return isPassiveMode;
105     }
106 
107     /** Returns {@code true} if service will be removed after its TTL expires. */
removeExpiredService()108     public boolean removeExpiredService() {
109         return removeExpiredService;
110     }
111 
112     /**
113      * Returns the network which the mdns query should target on.
114      *
115      * @return the target network or null if search on all possible interfaces.
116      */
117     @Nullable
getNetwork()118     public Network getNetwork() {
119         return mNetwork;
120     }
121 
122     /**
123      * If non-null, queries should try to resolve all records of this specific service, rather than
124      * discovering all services.
125      */
126     @Nullable
getResolveInstanceName()127     public String getResolveInstanceName() {
128         return resolveInstanceName;
129     }
130 
131     @Override
describeContents()132     public int describeContents() {
133         return 0;
134     }
135 
136     @Override
writeToParcel(Parcel out, int flags)137     public void writeToParcel(Parcel out, int flags) {
138         out.writeStringList(subtypes);
139         out.writeBoolean(isPassiveMode);
140         out.writeBoolean(removeExpiredService);
141         out.writeParcelable(mNetwork, 0);
142         out.writeString(resolveInstanceName);
143     }
144 
145     /** A builder to create {@link MdnsSearchOptions}. */
146     public static final class Builder {
147         private final Set<String> subtypes;
148         private boolean isPassiveMode = true;
149         private boolean removeExpiredService;
150         private Network mNetwork;
151         private String resolveInstanceName;
152 
Builder()153         private Builder() {
154             subtypes = new ArraySet<>();
155         }
156 
157         /**
158          * Adds a subtype to search.
159          *
160          * @param subtype the subtype to add.
161          */
addSubtype(@onNull String subtype)162         public Builder addSubtype(@NonNull String subtype) {
163             if (TextUtils.isEmpty(subtype)) {
164                 throw new IllegalArgumentException("Empty subtype");
165             }
166             subtypes.add(subtype);
167             return this;
168         }
169 
170         /**
171          * Adds a set of subtypes to search.
172          *
173          * @param subtypes The list of subtypes to add.
174          */
addSubtypes(@onNull Collection<String> subtypes)175         public Builder addSubtypes(@NonNull Collection<String> subtypes) {
176             this.subtypes.addAll(Objects.requireNonNull(subtypes));
177             return this;
178         }
179 
180         /**
181          * Sets if the passive mode scan should be used. The passive mode scans less frequently in
182          * order to conserve battery and produce less network traffic.
183          *
184          * @param isPassiveMode If set to {@code true}, passive mode will be used. If set to {@code
185          *                      false}, active mode will be used.
186          */
setIsPassiveMode(boolean isPassiveMode)187         public Builder setIsPassiveMode(boolean isPassiveMode) {
188             this.isPassiveMode = isPassiveMode;
189             return this;
190         }
191 
192         /**
193          * Sets if the service should be removed after TTL.
194          *
195          * @param removeExpiredService If set to {@code true}, the service will be removed after TTL
196          */
setRemoveExpiredService(boolean removeExpiredService)197         public Builder setRemoveExpiredService(boolean removeExpiredService) {
198             this.removeExpiredService = removeExpiredService;
199             return this;
200         }
201 
202         /**
203          * Sets if the mdns query should target on specific network.
204          *
205          * @param network the mdns query will target on given network.
206          */
setNetwork(Network network)207         public Builder setNetwork(Network network) {
208             mNetwork = network;
209             return this;
210         }
211 
212         /**
213          * Set the instance name to resolve.
214          *
215          * If non-null, queries should try to resolve all records of this specific service,
216          * rather than discovering all services.
217          * @param name The instance name.
218          */
setResolveInstanceName(String name)219         public Builder setResolveInstanceName(String name) {
220             resolveInstanceName = name;
221             return this;
222         }
223 
224         /** Builds a {@link MdnsSearchOptions} with the arguments supplied to this builder. */
build()225         public MdnsSearchOptions build() {
226             return new MdnsSearchOptions(new ArrayList<>(subtypes), isPassiveMode,
227                     removeExpiredService, mNetwork, resolveInstanceName);
228         }
229     }
230 }