1 /*
2  * Copyright (C) 2011 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.p2p;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.text.TextUtils;
23 
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 
29 /**
30  * A class representing a Wi-Fi P2p device list.
31  *
32  * Note that the operations are not thread safe.
33  * {@see WifiP2pManager}
34  */
35 public class WifiP2pDeviceList implements Parcelable {
36 
37     private final HashMap<String, WifiP2pDevice> mDevices = new HashMap<String, WifiP2pDevice>();
38 
WifiP2pDeviceList()39     public WifiP2pDeviceList() {
40     }
41 
42     /** copy constructor */
WifiP2pDeviceList(WifiP2pDeviceList source)43     public WifiP2pDeviceList(WifiP2pDeviceList source) {
44         if (source != null) {
45             for (WifiP2pDevice d : source.getDeviceList()) {
46                 mDevices.put(d.deviceAddress, new WifiP2pDevice(d));
47             }
48         }
49     }
50 
51     /** @hide */
WifiP2pDeviceList(ArrayList<WifiP2pDevice> devices)52     public WifiP2pDeviceList(ArrayList<WifiP2pDevice> devices) {
53         for (WifiP2pDevice device : devices) {
54             if (device.deviceAddress != null) {
55                 mDevices.put(device.deviceAddress, new WifiP2pDevice(device));
56             }
57         }
58     }
59 
validateDevice(WifiP2pDevice device)60     private void validateDevice(WifiP2pDevice device) {
61         if (device == null) throw new IllegalArgumentException("Null device");
62         if (TextUtils.isEmpty(device.deviceAddress)) {
63             throw new IllegalArgumentException("Empty deviceAddress");
64         }
65     }
66 
validateDeviceAddress(String deviceAddress)67     private void validateDeviceAddress(String deviceAddress) {
68         if (TextUtils.isEmpty(deviceAddress)) {
69             throw new IllegalArgumentException("Empty deviceAddress");
70         }
71     }
72 
73     /** Clear the list @hide */
clear()74     public boolean clear() {
75         if (mDevices.isEmpty()) return false;
76         mDevices.clear();
77         return true;
78     }
79 
80     /**
81      * Add/update a device to the list. If the device is not found, a new device entry
82      * is created. If the device is already found, the device details are updated
83      * @param device to be updated
84      * @hide
85      */
86     @UnsupportedAppUsage
update(WifiP2pDevice device)87     public void update(WifiP2pDevice device) {
88         updateSupplicantDetails(device);
89         mDevices.get(device.deviceAddress).status = device.status;
90     }
91 
92     /** Only updates details fetched from the supplicant @hide */
updateSupplicantDetails(WifiP2pDevice device)93     public void updateSupplicantDetails(WifiP2pDevice device) {
94         validateDevice(device);
95         WifiP2pDevice d = mDevices.get(device.deviceAddress);
96         if (d != null) {
97             d.deviceName = device.deviceName;
98             d.primaryDeviceType = device.primaryDeviceType;
99             d.secondaryDeviceType = device.secondaryDeviceType;
100             d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
101             d.deviceCapability = device.deviceCapability;
102             d.groupCapability = device.groupCapability;
103             d.wfdInfo = device.wfdInfo;
104             return;
105         }
106         //Not found, add a new one
107         mDevices.put(device.deviceAddress, device);
108     }
109 
110     /** @hide */
updateGroupCapability(String deviceAddress, int groupCapab)111     public void updateGroupCapability(String deviceAddress, int groupCapab) {
112         validateDeviceAddress(deviceAddress);
113         WifiP2pDevice d = mDevices.get(deviceAddress);
114         if (d != null) {
115             d.groupCapability = groupCapab;
116         }
117     }
118 
119     /** @hide */
updateStatus(String deviceAddress, int status)120     public void updateStatus(String deviceAddress, int status) {
121         validateDeviceAddress(deviceAddress);
122         WifiP2pDevice d = mDevices.get(deviceAddress);
123         if (d != null) {
124             d.status = status;
125         }
126     }
127 
128     /**
129      * Fetch a device from the list
130      * @param deviceAddress is the address of the device
131      * @return WifiP2pDevice device found, or null if none found
132      */
get(String deviceAddress)133     public WifiP2pDevice get(String deviceAddress) {
134         validateDeviceAddress(deviceAddress);
135         return mDevices.get(deviceAddress);
136     }
137 
138     /** @hide */
remove(WifiP2pDevice device)139     public boolean remove(WifiP2pDevice device) {
140         validateDevice(device);
141         return mDevices.remove(device.deviceAddress) != null;
142     }
143 
144     /**
145      * Remove a device from the list
146      * @param deviceAddress is the address of the device
147      * @return WifiP2pDevice device removed, or null if none removed
148      * @hide
149      */
150     @UnsupportedAppUsage
remove(String deviceAddress)151     public WifiP2pDevice remove(String deviceAddress) {
152         validateDeviceAddress(deviceAddress);
153         return mDevices.remove(deviceAddress);
154     }
155 
156     /** Returns true if any device the list was removed @hide */
remove(WifiP2pDeviceList list)157     public boolean remove(WifiP2pDeviceList list) {
158         boolean ret = false;
159         for (WifiP2pDevice d : list.mDevices.values()) {
160             if (remove(d)) ret = true;
161         }
162         return ret;
163     }
164 
165     /** Get the list of devices */
getDeviceList()166     public Collection<WifiP2pDevice> getDeviceList() {
167         return Collections.unmodifiableCollection(mDevices.values());
168     }
169 
170     /** @hide */
isGroupOwner(String deviceAddress)171     public boolean isGroupOwner(String deviceAddress) {
172         validateDeviceAddress(deviceAddress);
173         WifiP2pDevice device = mDevices.get(deviceAddress);
174         if (device == null) {
175             throw new IllegalArgumentException("Device not found " + deviceAddress);
176         }
177         return device.isGroupOwner();
178     }
179 
toString()180     public String toString() {
181         StringBuffer sbuf = new StringBuffer();
182         for (WifiP2pDevice device : mDevices.values()) {
183             sbuf.append("\n").append(device);
184         }
185         return sbuf.toString();
186     }
187 
188     /** Implement the Parcelable interface */
describeContents()189     public int describeContents() {
190         return 0;
191     }
192 
193     /** Implement the Parcelable interface */
writeToParcel(Parcel dest, int flags)194     public void writeToParcel(Parcel dest, int flags) {
195         dest.writeInt(mDevices.size());
196         for(WifiP2pDevice device : mDevices.values()) {
197             dest.writeParcelable(device, flags);
198         }
199     }
200 
201     /** Implement the Parcelable interface */
202     public static final @android.annotation.NonNull Creator<WifiP2pDeviceList> CREATOR =
203         new Creator<WifiP2pDeviceList>() {
204             public WifiP2pDeviceList createFromParcel(Parcel in) {
205                 WifiP2pDeviceList deviceList = new WifiP2pDeviceList();
206 
207                 int deviceCount = in.readInt();
208                 for (int i = 0; i < deviceCount; i++) {
209                     deviceList.update((WifiP2pDevice)in.readParcelable(null));
210                 }
211                 return deviceList;
212             }
213 
214             public WifiP2pDeviceList[] newArray(int size) {
215                 return new WifiP2pDeviceList[size];
216             }
217         };
218 }
219