• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package android.net.nsd;
17 
18 import android.annotation.FlaggedApi;
19 import android.annotation.LongDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.net.nsd.NsdManager.ProtocolType;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import com.android.net.flags.Flags;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.time.Duration;
31 import java.util.Objects;
32 
33 /**
34  * Encapsulates parameters for {@link NsdManager#registerService}.
35  */
36 @FlaggedApi(Flags.FLAG_IPV6_OVER_BLE)
37 public final class AdvertisingRequest implements Parcelable {
38 
39     /**
40      * Only update the registration without sending exit and re-announcement.
41      * @hide
42      */
43     public static final long NSD_ADVERTISING_UPDATE_ONLY = 1;
44 
45     // TODO: if apps are allowed to set hostnames, the below doc should be updated to mention that
46     // passed in hostnames must also be known unique to use this flag.
47     /**
48      * Skip the probing step when advertising.
49      *
50      * <p>This must only be used when the service name ({@link NsdServiceInfo#getServiceName()} is
51      * known to be unique and cannot possibly be used by any other device on the network.
52      */
53     public static final long FLAG_SKIP_PROBING = 1 << 1;
54 
55     /** @hide */
56     @Retention(RetentionPolicy.SOURCE)
57     @LongDef(flag = true, prefix = {"FLAG_"}, value = {
58             FLAG_SKIP_PROBING,
59     })
60     public @interface AdvertisingFlags {}
61 
62     @NonNull
63     public static final Creator<AdvertisingRequest> CREATOR =
64             new Creator<>() {
65                 @Override
66                 public AdvertisingRequest createFromParcel(Parcel in) {
67                     final NsdServiceInfo serviceInfo = in.readParcelable(
68                             NsdServiceInfo.class.getClassLoader(), NsdServiceInfo.class);
69                     final int protocolType = in.readInt();
70                     final long advertiseConfig = in.readLong();
71                     final long ttlSeconds = in.readLong();
72                     final Duration ttl = ttlSeconds < 0 ? null : Duration.ofSeconds(ttlSeconds);
73                     return new AdvertisingRequest(serviceInfo, protocolType, advertiseConfig, ttl);
74                 }
75 
76                 @Override
77                 public AdvertisingRequest[] newArray(int size) {
78                     return new AdvertisingRequest[size];
79                 }
80             };
81     @NonNull
82     private final NsdServiceInfo mServiceInfo;
83     private final int mProtocolType;
84     // Bitmask of @AdvertisingConfig flags. Uses a long to allow 64 possible flags in the future.
85     private final long mAdvertisingConfig;
86 
87     @Nullable
88     private final Duration mTtl;
89 
90     /**
91      * @hide
92      */
93     @Retention(RetentionPolicy.SOURCE)
94     @LongDef(flag = true, prefix = {"NSD_ADVERTISING"}, value = {
95             NSD_ADVERTISING_UPDATE_ONLY,
96     })
97     @interface AdvertisingConfig {}
98 
99     /**
100      * The constructor for the advertiseRequest
101      */
AdvertisingRequest(@onNull NsdServiceInfo serviceInfo, @ProtocolType int protocolType, long advertisingConfig, @NonNull Duration ttl)102     private AdvertisingRequest(@NonNull NsdServiceInfo serviceInfo, @ProtocolType int protocolType,
103             long advertisingConfig, @NonNull Duration ttl) {
104         mServiceInfo = serviceInfo;
105         mProtocolType = protocolType;
106         mAdvertisingConfig = advertisingConfig;
107         mTtl = ttl;
108     }
109 
110     /**
111      * @return the {@link NsdServiceInfo} describing the service to advertise.
112      */
113     @NonNull
getServiceInfo()114     public NsdServiceInfo getServiceInfo() {
115         return mServiceInfo;
116     }
117 
118     /**
119      * @return the service advertisement protocol.
120      */
121     @ProtocolType
getProtocolType()122     public int getProtocolType() {
123         return mProtocolType;
124     }
125 
126     /**
127      * @return the flags affecting advertising behavior.
128      */
129     @AdvertisingFlags
getFlags()130     public long getFlags() {
131         return mAdvertisingConfig;
132     }
133 
134     /**
135      * Returns the time interval that the resource records may be cached on a DNS resolver.
136      *
137      * The value will be {@code null} if it's not specified with the {@link #Builder}.
138      *
139      * @hide
140      */
141     // @FlaggedApi(NsdManager.Flags.NSD_CUSTOM_TTL_ENABLED)
142     @Nullable
getTtl()143     public Duration getTtl() {
144         return mTtl;
145     }
146 
147     @Override
toString()148     public String toString() {
149         StringBuilder sb = new StringBuilder();
150         sb.append("serviceInfo: ").append(mServiceInfo)
151                 .append(", protocolType: ").append(mProtocolType)
152                 .append(", advertisingConfig: ").append(mAdvertisingConfig)
153                 .append(", ttl: ").append(mTtl);
154         return sb.toString();
155     }
156 
157     @Override
equals(Object other)158     public boolean equals(Object other) {
159         if (this == other) {
160             return true;
161         } else if (!(other instanceof AdvertisingRequest)) {
162             return false;
163         } else {
164             final AdvertisingRequest otherRequest = (AdvertisingRequest) other;
165             return mServiceInfo.equals(otherRequest.mServiceInfo)
166                     && mProtocolType == otherRequest.mProtocolType
167                     && mAdvertisingConfig == otherRequest.mAdvertisingConfig
168                     && Objects.equals(mTtl, otherRequest.mTtl);
169         }
170     }
171 
172     @Override
hashCode()173     public int hashCode() {
174         return Objects.hash(mServiceInfo, mProtocolType, mAdvertisingConfig, mTtl);
175     }
176 
177     @Override
describeContents()178     public int describeContents() {
179         return 0;
180     }
181 
182     @Override
writeToParcel(@onNull Parcel dest, int flags)183     public void writeToParcel(@NonNull Parcel dest, int flags) {
184         dest.writeParcelable(mServiceInfo, flags);
185         dest.writeInt(mProtocolType);
186         dest.writeLong(mAdvertisingConfig);
187         dest.writeLong(mTtl == null ? -1L : mTtl.getSeconds());
188     }
189 
190     /**
191      * A builder for creating new {@link AdvertisingRequest} objects.
192      */
193     @FlaggedApi(Flags.FLAG_IPV6_OVER_BLE)
194     public static final class Builder {
195         @NonNull
196         private final NsdServiceInfo mServiceInfo;
197         private int mProtocolType;
198         private long mAdvertisingConfig;
199         @Nullable
200         private Duration mTtl;
201 
202         /**
203          * Creates a new {@link Builder} object.
204          * @param serviceInfo the {@link NsdServiceInfo} describing the service to advertise.
205          * @param protocolType the advertising protocol to use.
206          * @hide
207          */
Builder(@onNull NsdServiceInfo serviceInfo, @ProtocolType int protocolType)208         public Builder(@NonNull NsdServiceInfo serviceInfo, @ProtocolType int protocolType) {
209             mServiceInfo = serviceInfo;
210             mProtocolType = protocolType;
211         }
212 
213         /**
214          * Creates a new {@link Builder} object.
215          * @param serviceInfo the {@link NsdServiceInfo} describing the service to advertise.
216          */
Builder(@onNull NsdServiceInfo serviceInfo)217         public Builder(@NonNull NsdServiceInfo serviceInfo) {
218             this(serviceInfo, NsdManager.PROTOCOL_DNS_SD);
219         }
220 
221         /**
222          * Sets advertising configuration flags.
223          *
224          * @param flags flags to use for advertising.
225          */
226         @NonNull
setFlags(@dvertisingFlags long flags)227         public Builder setFlags(@AdvertisingFlags long flags) {
228             mAdvertisingConfig = flags;
229             return this;
230         }
231 
232         /**
233          * Sets the time interval that the resource records may be cached on a DNS resolver.
234          *
235          * If this method is not called or {@code ttl} is {@code null}, default TTL values
236          * will be used for the service when it's registered. Otherwise, the {@code ttl}
237          * will be used for all resource records of this service.
238          *
239          * When registering a service, {@link NsdManager#FAILURE_BAD_PARAMETERS} will be returned
240          * if {@code ttl} is smaller than 30 seconds.
241          *
242          * Note: the value after the decimal point (in unit of seconds) will be discarded. For
243          * example, {@code 30} seconds will be used when {@code Duration.ofSeconds(30L, 50_000L)}
244          * is provided.
245          *
246          * @param ttl the maximum duration that the DNS resource records will be cached
247          *
248          * @see AdvertisingRequest#getTtl
249          * @hide
250          */
251         // @FlaggedApi(NsdManager.Flags.NSD_CUSTOM_TTL_ENABLED)
252         @NonNull
setTtl(@ullable Duration ttl)253         public Builder setTtl(@Nullable Duration ttl) {
254             if (ttl == null) {
255                 mTtl = null;
256                 return this;
257             }
258             final long ttlSeconds = ttl.getSeconds();
259             if (ttlSeconds < 0 || ttlSeconds > 0xffffffffL) {
260                 throw new IllegalArgumentException(
261                         "ttlSeconds exceeds the allowed range (value = " + ttlSeconds
262                                 + ", allowedRanged = [0, 0xffffffffL])");
263             }
264             mTtl = Duration.ofSeconds(ttlSeconds);
265             return this;
266         }
267 
268         /**
269          * Sets the protocol to use for advertising.
270          * @param protocolType the advertising protocol to use.
271          */
272         @NonNull
setProtocolType(@rotocolType int protocolType)273         public Builder setProtocolType(@ProtocolType int protocolType) {
274             mProtocolType = protocolType;
275             return this;
276         }
277 
278         /** Creates a new {@link AdvertisingRequest} object. */
279         @NonNull
build()280         public AdvertisingRequest build() {
281             return new AdvertisingRequest(mServiceInfo, mProtocolType, mAdvertisingConfig, mTtl);
282         }
283     }
284 }
285