blob: c345a9d77d20fa3dbc4509d699b60f8b79c45af8 [file] [log] [blame]
Daniel Brightf9e945b2020-06-15 16:10:01 -07001/*
2 * Copyright (C) 2020 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
17package android.net;
18
19import android.annotation.NonNull;
20import android.annotation.SystemApi;
21import android.os.Parcel;
22import android.os.ParcelFileDescriptor;
23import android.os.Parcelable;
24
25import java.io.IOException;
26import java.net.InetAddress;
27import java.net.InetSocketAddress;
28import java.net.Socket;
29import java.net.UnknownHostException;
30import java.util.Objects;
31
32/**
33 * Used in conjunction with
34 * {@link ConnectivityManager#registerQosCallback}
35 * in order to receive Qos Sessions related to the local address and port of a bound {@link Socket}.
36 *
37 * @hide
38 */
39@SystemApi
40public final class QosSocketInfo implements Parcelable {
41
42 @NonNull
43 private final Network mNetwork;
44
45 @NonNull
46 private final ParcelFileDescriptor mParcelFileDescriptor;
47
48 @NonNull
49 private final InetSocketAddress mLocalSocketAddress;
50
51 /**
52 * The {@link Network} the socket is on.
53 *
54 * @return the registered {@link Network}
55 */
56 @NonNull
57 public Network getNetwork() {
58 return mNetwork;
59 }
60
61 /**
62 * The parcel file descriptor wrapped around the socket's file descriptor.
63 *
64 * @return the parcel file descriptor of the socket
65 */
66 @NonNull
67 ParcelFileDescriptor getParcelFileDescriptor() {
68 return mParcelFileDescriptor;
69 }
70
71 /**
72 * The local address of the socket passed into {@link QosSocketInfo(Network, Socket)}.
73 * The value does not reflect any changes that occur to the socket after it is first set
74 * in the constructor.
75 *
76 * @return the local address of the socket
77 */
78 @NonNull
79 public InetSocketAddress getLocalSocketAddress() {
80 return mLocalSocketAddress;
81 }
82
83 /**
84 * Creates a {@link QosSocketInfo} given a {@link Network} and bound {@link Socket}. The
85 * {@link Socket} must remain bound in order to receive {@link QosSession}s.
86 *
87 * @param network the network
88 * @param socket the bound {@link Socket}
89 */
90 public QosSocketInfo(@NonNull final Network network, @NonNull final Socket socket)
91 throws IOException {
92 Objects.requireNonNull(socket, "socket cannot be null");
93
94 mNetwork = Objects.requireNonNull(network, "network cannot be null");
95 mParcelFileDescriptor = ParcelFileDescriptor.dup(socket.getFileDescriptor$());
96 mLocalSocketAddress =
97 new InetSocketAddress(socket.getLocalAddress(), socket.getLocalPort());
98 }
99
100 /* Parcelable methods */
101 private QosSocketInfo(final Parcel in) {
102 mNetwork = Objects.requireNonNull(Network.CREATOR.createFromParcel(in));
103 mParcelFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(in);
104
105 final int addressLength = in.readInt();
106 mLocalSocketAddress = readSocketAddress(in, addressLength);
107 }
108
109 private InetSocketAddress readSocketAddress(final Parcel in, final int addressLength) {
110 final byte[] address = new byte[addressLength];
111 in.readByteArray(address);
112 final int port = in.readInt();
113
114 try {
115 return new InetSocketAddress(InetAddress.getByAddress(address), port);
116 } catch (final UnknownHostException e) {
Remi NGUYEN VANd059f212021-03-11 07:43:37 +0000117 /* This can never happen. UnknownHostException will never be thrown
Daniel Brightf9e945b2020-06-15 16:10:01 -0700118 since the address provided is numeric and non-null. */
Remi NGUYEN VANd059f212021-03-11 07:43:37 +0000119 throw new RuntimeException("UnknownHostException on numeric address", e);
Daniel Brightf9e945b2020-06-15 16:10:01 -0700120 }
Daniel Brightf9e945b2020-06-15 16:10:01 -0700121 }
122
123 @Override
124 public int describeContents() {
125 return 0;
126 }
127
128 @Override
129 public void writeToParcel(@NonNull final Parcel dest, final int flags) {
130 mNetwork.writeToParcel(dest, 0);
131 mParcelFileDescriptor.writeToParcel(dest, 0);
132
133 final byte[] address = mLocalSocketAddress.getAddress().getAddress();
134 dest.writeInt(address.length);
135 dest.writeByteArray(address);
136 dest.writeInt(mLocalSocketAddress.getPort());
137 }
138
139 @NonNull
140 public static final Parcelable.Creator<QosSocketInfo> CREATOR =
141 new Parcelable.Creator<QosSocketInfo>() {
142 @NonNull
143 @Override
144 public QosSocketInfo createFromParcel(final Parcel in) {
145 return new QosSocketInfo(in);
146 }
147
148 @NonNull
149 @Override
150 public QosSocketInfo[] newArray(final int size) {
151 return new QosSocketInfo[size];
152 }
153 };
154}