1 /*
2  * Copyright (C) 2012 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.wifi.p2p;
17 
18 import java.util.Collection;
19 import java.util.Map;
20 
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.LruCache;
24 
25 
26 /**
27  * A class representing a Wi-Fi P2p group list
28  *
29  * {@see WifiP2pManager}
30  * @hide
31  */
32 public class WifiP2pGroupList implements Parcelable {
33 
34     private static final int CREDENTIAL_MAX_NUM             =   32;
35 
36     private final LruCache<Integer, WifiP2pGroup> mGroups;
37     private final GroupDeleteListener mListener;
38 
39     private boolean isClearCalled = false;
40 
41     public interface GroupDeleteListener {
onDeleteGroup(int netId)42         public void onDeleteGroup(int netId);
43     }
44 
45     /** @hide */
WifiP2pGroupList()46     public WifiP2pGroupList() {
47         this(null, null);
48     }
49 
50     /** @hide */
WifiP2pGroupList(WifiP2pGroupList source, GroupDeleteListener listener)51     public WifiP2pGroupList(WifiP2pGroupList source, GroupDeleteListener listener) {
52         mListener = listener;
53         mGroups = new LruCache<Integer, WifiP2pGroup>(CREDENTIAL_MAX_NUM) {
54             @Override
55             protected void entryRemoved(boolean evicted, Integer netId,
56                     WifiP2pGroup oldValue, WifiP2pGroup newValue) {
57                 if (mListener != null && !isClearCalled) {
58                     mListener.onDeleteGroup(oldValue.getNetworkId());
59                 }
60             }
61         };
62 
63         if (source != null) {
64             for (Map.Entry<Integer, WifiP2pGroup> item : source.mGroups.snapshot().entrySet()) {
65                 mGroups.put(item.getKey(), item.getValue());
66             }
67         }
68     }
69 
70     /**
71      * Return the list of p2p group.
72      *
73      * @return the list of p2p group.
74      */
getGroupList()75     public Collection<WifiP2pGroup> getGroupList() {
76         return mGroups.snapshot().values();
77     }
78 
79     /**
80      * Add the specified group to this group list.
81      *
82      * @param group
83      * @hide
84      */
add(WifiP2pGroup group)85     public void add(WifiP2pGroup group) {
86         mGroups.put(group.getNetworkId(), group);
87     }
88 
89     /**
90      * Remove the group with the specified network id from this group list.
91      *
92      * @param netId
93      * @hide
94      */
remove(int netId)95     public void remove(int netId) {
96         mGroups.remove(netId);
97     }
98 
99     /**
100      * Remove the group with the specified device address from this group list.
101      *
102      * @param deviceAddress
103      */
remove(String deviceAddress)104     void remove(String deviceAddress) {
105         remove(getNetworkId(deviceAddress));
106     }
107 
108     /**
109      * Clear the group.
110      * @hide
111      */
clear()112     public boolean clear() {
113         if (mGroups.size() == 0) return false;
114         isClearCalled = true;
115         mGroups.evictAll();
116         isClearCalled = false;
117         return true;
118     }
119 
120     /**
121      * Return the network id of the group owner profile with the specified p2p device
122      * address.
123      * If more than one persistent group of the same address is present in the list,
124      * return the first one.
125      *
126      * @param deviceAddress p2p device address.
127      * @return the network id. if not found, return -1.
128      * @hide
129      */
getNetworkId(String deviceAddress)130     public int getNetworkId(String deviceAddress) {
131         if (deviceAddress == null) return -1;
132 
133         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
134         for (WifiP2pGroup grp: groups) {
135             if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress)) {
136                 // update cache ordered.
137                 mGroups.get(grp.getNetworkId());
138                 return grp.getNetworkId();
139             }
140         }
141         return -1;
142     }
143 
144     /**
145      * Return the network id of the group with the specified p2p device address
146      * and the ssid.
147      *
148      * @param deviceAddress p2p device address.
149      * @param ssid ssid.
150      * @return the network id. if not found, return -1.
151      * @hide
152      */
getNetworkId(String deviceAddress, String ssid)153     public int getNetworkId(String deviceAddress, String ssid) {
154         if (deviceAddress == null || ssid == null) {
155             return -1;
156         }
157 
158         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
159         for (WifiP2pGroup grp: groups) {
160             if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress) &&
161                     ssid.equals(grp.getNetworkName())) {
162                 // update cache ordered.
163                 mGroups.get(grp.getNetworkId());
164                 return grp.getNetworkId();
165             }
166         }
167 
168         return -1;
169     }
170 
171     /**
172      * Return the group owner address of the group with the specified network id
173      *
174      * @param netId network id.
175      * @return the address. if not found, return null.
176      * @hide
177      */
getOwnerAddr(int netId)178     public String getOwnerAddr(int netId) {
179         WifiP2pGroup grp = mGroups.get(netId);
180         if (grp != null) {
181             return grp.getOwner().deviceAddress;
182         }
183         return null;
184     }
185 
186     /**
187      * Return true if this group list contains the specified network id.
188      * This function does NOT update LRU information.
189      * It means the internal queue is NOT reordered.
190      *
191      * @param netId network id.
192      * @return true if the specified network id is present in this group list.
193      * @hide
194      */
contains(int netId)195     public boolean contains(int netId) {
196         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
197         for (WifiP2pGroup grp: groups) {
198             if (netId == grp.getNetworkId()) {
199                 return true;
200             }
201         }
202         return false;
203     }
204 
toString()205     public String toString() {
206         StringBuffer sbuf = new StringBuffer();
207 
208         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
209         for (WifiP2pGroup grp: groups) {
210             sbuf.append(grp).append("\n");
211         }
212         return sbuf.toString();
213     }
214 
215     /** Implement the Parcelable interface */
describeContents()216     public int describeContents() {
217         return 0;
218     }
219 
220     /** Implement the Parcelable interface */
writeToParcel(Parcel dest, int flags)221     public void writeToParcel(Parcel dest, int flags) {
222         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
223         dest.writeInt(groups.size());
224         for(WifiP2pGroup group : groups) {
225             dest.writeParcelable(group, flags);
226         }
227     }
228 
229     /** Implement the Parcelable interface */
230     public static final Creator<WifiP2pGroupList> CREATOR =
231         new Creator<WifiP2pGroupList>() {
232             public WifiP2pGroupList createFromParcel(Parcel in) {
233                 WifiP2pGroupList grpList = new WifiP2pGroupList();
234 
235                 int deviceCount = in.readInt();
236                 for (int i = 0; i < deviceCount; i++) {
237                     grpList.add((WifiP2pGroup)in.readParcelable(null));
238                 }
239                 return grpList;
240             }
241 
242             public WifiP2pGroupList[] newArray(int size) {
243                 return new WifiP2pGroupList[size];
244             }
245         };
246 }
247