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
17package android.net.wifi.p2p;
18
19import android.os.Parcelable;
20import android.os.Parcel;
21import android.net.wifi.p2p.WifiP2pDevice;
22import android.text.TextUtils;
23import android.util.Log;
24
25import java.util.ArrayList;
26import java.util.Collection;
27import java.util.Collections;
28import java.util.HashMap;
29
30/**
31 * A class representing a Wi-Fi P2p device list.
32 *
33 * Note that the operations are not thread safe.
34 * {@see WifiP2pManager}
35 */
36public class WifiP2pDeviceList implements Parcelable {
37
38    private final HashMap<String, WifiP2pDevice> mDevices = new HashMap<String, WifiP2pDevice>();
39
40    public WifiP2pDeviceList() {
41    }
42
43    /** copy constructor */
44    public WifiP2pDeviceList(WifiP2pDeviceList source) {
45        if (source != null) {
46            for (WifiP2pDevice d : source.getDeviceList()) {
47                mDevices.put(d.deviceAddress, new WifiP2pDevice(d));
48            }
49        }
50    }
51
52    /** @hide */
53    public WifiP2pDeviceList(ArrayList<WifiP2pDevice> devices) {
54        for (WifiP2pDevice device : devices) {
55            if (device.deviceAddress != null) {
56                mDevices.put(device.deviceAddress, new WifiP2pDevice(device));
57            }
58        }
59    }
60
61    private void validateDevice(WifiP2pDevice device) {
62        if (device == null) throw new IllegalArgumentException("Null device");
63        if (TextUtils.isEmpty(device.deviceAddress)) {
64            throw new IllegalArgumentException("Empty deviceAddress");
65        }
66    }
67
68    private void validateDeviceAddress(String deviceAddress) {
69        if (TextUtils.isEmpty(deviceAddress)) {
70            throw new IllegalArgumentException("Empty deviceAddress");
71        }
72    }
73
74    /** Clear the list @hide */
75    public boolean clear() {
76        if (mDevices.isEmpty()) return false;
77        mDevices.clear();
78        return true;
79    }
80
81    /**
82     * Add/update a device to the list. If the device is not found, a new device entry
83     * is created. If the device is already found, the device details are updated
84     * @param device to be updated
85     * @hide
86     */
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 */
93    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 */
111    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 */
120    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     */
133    public WifiP2pDevice get(String deviceAddress) {
134        validateDeviceAddress(deviceAddress);
135        return mDevices.get(deviceAddress);
136    }
137
138    /** @hide */
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    public WifiP2pDevice remove(String deviceAddress) {
151        validateDeviceAddress(deviceAddress);
152        return mDevices.remove(deviceAddress);
153    }
154
155    /** Returns true if any device the list was removed @hide */
156    public boolean remove(WifiP2pDeviceList list) {
157        boolean ret = false;
158        for (WifiP2pDevice d : list.mDevices.values()) {
159            if (remove(d)) ret = true;
160        }
161        return ret;
162    }
163
164    /** Get the list of devices */
165    public Collection<WifiP2pDevice> getDeviceList() {
166        return Collections.unmodifiableCollection(mDevices.values());
167    }
168
169    /** @hide */
170    public boolean isGroupOwner(String deviceAddress) {
171        validateDeviceAddress(deviceAddress);
172        WifiP2pDevice device = mDevices.get(deviceAddress);
173        if (device == null) {
174            throw new IllegalArgumentException("Device not found " + deviceAddress);
175        }
176        return device.isGroupOwner();
177    }
178
179    public String toString() {
180        StringBuffer sbuf = new StringBuffer();
181        for (WifiP2pDevice device : mDevices.values()) {
182            sbuf.append("\n").append(device);
183        }
184        return sbuf.toString();
185    }
186
187    /** Implement the Parcelable interface */
188    public int describeContents() {
189        return 0;
190    }
191
192    /** Implement the Parcelable interface */
193    public void writeToParcel(Parcel dest, int flags) {
194        dest.writeInt(mDevices.size());
195        for(WifiP2pDevice device : mDevices.values()) {
196            dest.writeParcelable(device, flags);
197        }
198    }
199
200    /** Implement the Parcelable interface */
201    public static final Creator<WifiP2pDeviceList> CREATOR =
202        new Creator<WifiP2pDeviceList>() {
203            public WifiP2pDeviceList createFromParcel(Parcel in) {
204                WifiP2pDeviceList deviceList = new WifiP2pDeviceList();
205
206                int deviceCount = in.readInt();
207                for (int i = 0; i < deviceCount; i++) {
208                    deviceList.update((WifiP2pDevice)in.readParcelable(null));
209                }
210                return deviceList;
211            }
212
213            public WifiP2pDeviceList[] newArray(int size) {
214                return new WifiP2pDeviceList[size];
215            }
216        };
217}
218