• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 android.net.wifi.aware;
18 
19 import android.net.NetworkSpecifier;
20 import android.net.wifi.util.HexEncoding;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.Log;
24 
25 import java.security.MessageDigest;
26 import java.security.NoSuchAlgorithmException;
27 import java.util.Arrays;
28 import java.util.HashSet;
29 import java.util.Set;
30 import java.util.StringJoiner;
31 
32 /**
33  * A network specifier object used to represent the capabilities of an network agent. A collection
34  * of multiple WifiAwareNetworkSpecifier objects whose matching critiera (satisfiedBy) is an OR:
35  * a match on any of the network specifiers in the collection is a match.
36  *
37  * This class is not intended for use in network requests.
38  *
39  * @hide
40  */
41 public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements Parcelable {
42     private static final String TAG = "WifiAwareAgentNs";
43 
44     private static final boolean VDBG = false; // STOPSHIP if true
45 
46     private Set<ByteArrayWrapper> mNetworkSpecifiers = new HashSet<>();
47     private MessageDigest mDigester;
48 
WifiAwareAgentNetworkSpecifier()49     public WifiAwareAgentNetworkSpecifier() {
50         initialize();
51     }
52 
WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier ns)53     public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
54         initialize();
55         mNetworkSpecifiers.add(convert(ns));
56     }
57 
WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier[] nss)58     public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier[] nss) {
59         initialize();
60         for (WifiAwareNetworkSpecifier ns : nss) {
61             mNetworkSpecifiers.add(convert(ns));
62         }
63     }
64 
isEmpty()65     public boolean isEmpty() {
66         return mNetworkSpecifiers.isEmpty();
67     }
68 
69     @Override
describeContents()70     public int describeContents() {
71         return 0;
72     }
73 
74     @Override
writeToParcel(Parcel dest, int flags)75     public void writeToParcel(Parcel dest, int flags) {
76         dest.writeArray(mNetworkSpecifiers.toArray());
77     }
78 
79     public static final @android.annotation.NonNull Creator<WifiAwareAgentNetworkSpecifier> CREATOR =
80             new Creator<WifiAwareAgentNetworkSpecifier>() {
81                 @Override
82                 public WifiAwareAgentNetworkSpecifier createFromParcel(Parcel in) {
83                     WifiAwareAgentNetworkSpecifier agentNs = new WifiAwareAgentNetworkSpecifier();
84                     Object[] objs = in.readArray(null);
85                     for (Object obj : objs) {
86                         agentNs.mNetworkSpecifiers.add((ByteArrayWrapper) obj);
87                     }
88                     return agentNs;
89                 }
90 
91                 @Override
92                 public WifiAwareAgentNetworkSpecifier[] newArray(int size) {
93                     return new WifiAwareAgentNetworkSpecifier[size];
94                 }
95             };
96 
97     @Override
hashCode()98     public int hashCode() {
99         return mNetworkSpecifiers.hashCode();
100     }
101 
102     @Override
equals(Object obj)103     public boolean equals(Object obj) {
104         if (obj == this) {
105             return true;
106         }
107         if (!(obj instanceof WifiAwareAgentNetworkSpecifier)) {
108             return false;
109         }
110         return mNetworkSpecifiers.equals(((WifiAwareAgentNetworkSpecifier) obj).mNetworkSpecifiers);
111     }
112 
113     @Override
toString()114     public String toString() {
115         StringJoiner sj = new StringJoiner(",");
116         for (ByteArrayWrapper baw: mNetworkSpecifiers) {
117             sj.add(baw.toString());
118         }
119         return sj.toString();
120     }
121 
122     @Override
canBeSatisfiedBy(NetworkSpecifier other)123     public boolean canBeSatisfiedBy(NetworkSpecifier other) {
124         if (!(other instanceof WifiAwareAgentNetworkSpecifier)) {
125             return false;
126         }
127         WifiAwareAgentNetworkSpecifier otherNs = (WifiAwareAgentNetworkSpecifier) other;
128 
129         // called as old.satifiedBy(new): satisfied if old contained in new
130         for (ByteArrayWrapper baw: mNetworkSpecifiers) {
131             if (!otherNs.mNetworkSpecifiers.contains(baw)) {
132                 return false;
133             }
134         }
135 
136         return true;
137     }
138 
satisfiesAwareNetworkSpecifier(WifiAwareNetworkSpecifier ns)139     public boolean satisfiesAwareNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
140         if (VDBG) Log.v(TAG, "satisfiesAwareNetworkSpecifier: ns=" + ns);
141         ByteArrayWrapper nsBytes = convert(ns);
142         return mNetworkSpecifiers.contains(nsBytes);
143     }
144 
145     @Override
redact()146     public NetworkSpecifier redact() {
147         return null;
148     }
149 
initialize()150     private void initialize() {
151         try {
152             mDigester = MessageDigest.getInstance("SHA-256");
153         } catch (NoSuchAlgorithmException e) {
154             Log.e(TAG, "Can not instantiate a SHA-256 digester!? Will match nothing.");
155             return;
156         }
157     }
158 
convert(WifiAwareNetworkSpecifier ns)159     private ByteArrayWrapper convert(WifiAwareNetworkSpecifier ns) {
160         if (mDigester == null) {
161             return null;
162         }
163 
164         Parcel parcel = Parcel.obtain();
165         ns.writeToParcel(parcel, 0);
166         byte[] bytes = parcel.marshall();
167         parcel.recycle();
168 
169         mDigester.reset();
170         mDigester.update(bytes);
171         return new ByteArrayWrapper(mDigester.digest());
172     }
173 
174     private static class ByteArrayWrapper implements Parcelable {
175         private byte[] mData;
176 
ByteArrayWrapper(byte[] data)177         ByteArrayWrapper(byte[] data) {
178             mData = data;
179         }
180 
181         @Override
hashCode()182         public int hashCode() {
183             return Arrays.hashCode(mData);
184         }
185 
186         @Override
equals(Object obj)187         public boolean equals(Object obj) {
188             if (obj == this) {
189                 return true;
190             }
191             if (!(obj instanceof ByteArrayWrapper)) {
192                 return false;
193             }
194             return Arrays.equals(((ByteArrayWrapper) obj).mData, mData);
195         }
196 
197         @Override
describeContents()198         public int describeContents() {
199             return 0;
200         }
201 
202         @Override
writeToParcel(Parcel dest, int flags)203         public void writeToParcel(Parcel dest, int flags) {
204             dest.writeByteArray(mData);
205         }
206 
207         public static final @android.annotation.NonNull Creator<ByteArrayWrapper> CREATOR =
208                 new Creator<ByteArrayWrapper>() {
209                     @Override
210                     public ByteArrayWrapper createFromParcel(Parcel in) {
211                         return new ByteArrayWrapper(in.createByteArray());
212                     }
213 
214                     @Override
215                     public ByteArrayWrapper[] newArray(int size) {
216                         return new ByteArrayWrapper[size];
217                     }
218                 };
219 
220         @Override
toString()221         public String toString() {
222             return new String(HexEncoding.encode(mData));
223         }
224     }
225 }
226