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