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