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