OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / wifi / java / android / net / wifi / p2p / WifiP2pGroup.java
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.os.Parcelable;
20 import android.os.Parcel;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.regex.Pattern;
27 import java.util.regex.Matcher;
28
29 /**
30  * A class representing a Wi-Fi P2p group. A p2p group consists of a single group
31  * owner and one or more clients. In the case of a group with only two devices, one
32  * will be the group owner and the other will be a group client.
33  *
34  * {@see WifiP2pManager}
35  */
36 public class WifiP2pGroup implements Parcelable {
37
38     /** The temporary network id.
39      * {@hide} */
40     public static final int TEMPORARY_NET_ID = -1;
41
42     /** The persistent network id.
43      * If a matching persistent profile is found, use it.
44      * Otherwise, create a new persistent profile.
45      * {@hide} */
46     public static final int PERSISTENT_NET_ID = -2;
47
48     /** The network name */
49     private String mNetworkName;
50
51     /** Group owner */
52     private WifiP2pDevice mOwner;
53
54     /** Device is group owner */
55     private boolean mIsGroupOwner;
56
57     /** Group clients */
58     private List<WifiP2pDevice> mClients = new ArrayList<WifiP2pDevice>();
59
60     /** The passphrase used for WPA2-PSK */
61     private String mPassphrase;
62
63     private String mInterface;
64
65     /** The network id in the wpa_supplicant */
66     private int mNetId;
67
68     /** P2P group started string pattern */
69     private static final Pattern groupStartedPattern = Pattern.compile(
70         "ssid=\"(.+)\" " +
71         "freq=(\\d+) " +
72         "(?:psk=)?([0-9a-fA-F]{64})?" +
73         "(?:passphrase=)?(?:\"(.{0,63})\")? " +
74         "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})" +
75         " ?(\\[PERSISTENT\\])?"
76     );
77
78     public WifiP2pGroup() {
79     }
80
81     /**
82      * @param supplicantEvent formats supported include
83      *
84      *  P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
85      *  [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|
86      *  passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT]
87      *
88      *  P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
89      *
90      *  P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
91      *  bssid=fa:7b:7a:42:82:13 unknown-network
92      *
93      *  P2P-INVITATION-RECEIVED sa=b8:f9:34:2a:c7:9d persistent=0
94      *
95      *  Note: The events formats can be looked up in the wpa_supplicant code
96      *  @hide
97      */
98     public WifiP2pGroup(String supplicantEvent) throws IllegalArgumentException {
99
100         String[] tokens = supplicantEvent.split(" ");
101
102         if (tokens.length < 3) {
103             throw new IllegalArgumentException("Malformed supplicant event");
104         }
105
106         if (tokens[0].startsWith("P2P-GROUP")) {
107             mInterface = tokens[1];
108             mIsGroupOwner = tokens[2].equals("GO");
109
110             Matcher match = groupStartedPattern.matcher(supplicantEvent);
111             if (!match.find()) {
112                 return;
113             }
114
115             mNetworkName = match.group(1);
116             //freq and psk are unused right now
117             //int freq = Integer.parseInt(match.group(2));
118             //String psk = match.group(3);
119             mPassphrase = match.group(4);
120             mOwner = new WifiP2pDevice(match.group(5));
121             if (match.group(6) != null) {
122                 mNetId = PERSISTENT_NET_ID;
123             } else {
124                 mNetId = TEMPORARY_NET_ID;
125             }
126         } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
127             String sa = null;
128             mNetId = PERSISTENT_NET_ID;
129             for (String token : tokens) {
130                 String[] nameValue = token.split("=");
131                 if (nameValue.length != 2) continue;
132
133                 if (nameValue[0].equals("sa")) {
134                     sa = nameValue[1];
135
136                     // set source address into the client list.
137                     WifiP2pDevice dev = new WifiP2pDevice();
138                     dev.deviceAddress = nameValue[1];
139                     mClients.add(dev);
140                     continue;
141                 }
142
143                 if (nameValue[0].equals("go_dev_addr")) {
144                     mOwner = new WifiP2pDevice(nameValue[1]);
145                     continue;
146                 }
147
148                 if (nameValue[0].equals("persistent")) {
149                     mNetId = Integer.parseInt(nameValue[1]);
150                     continue;
151                 }
152             }
153         } else {
154             throw new IllegalArgumentException("Malformed supplicant event");
155         }
156     }
157
158     /** @hide */
159     public void setNetworkName(String networkName) {
160         mNetworkName = networkName;
161     }
162
163     /**
164      * Get the network name (SSID) of the group. Legacy Wi-Fi clients will discover
165      * the p2p group using the network name.
166      */
167     public String getNetworkName() {
168         return mNetworkName;
169     }
170
171     /** @hide */
172     public void setIsGroupOwner(boolean isGo) {
173         mIsGroupOwner = isGo;
174     }
175
176     /** Check whether this device is the group owner of the created p2p group */
177     public boolean isGroupOwner() {
178         return mIsGroupOwner;
179     }
180
181     /** @hide */
182     public void setOwner(WifiP2pDevice device) {
183         mOwner = device;
184     }
185
186     /** Get the details of the group owner as a {@link WifiP2pDevice} object */
187     public WifiP2pDevice getOwner() {
188         return mOwner;
189     }
190
191     /** @hide */
192     public void addClient(String address) {
193         addClient(new WifiP2pDevice(address));
194     }
195
196     /** @hide */
197     public void addClient(WifiP2pDevice device) {
198         for (WifiP2pDevice client : mClients) {
199             if (client.equals(device)) return;
200         }
201         mClients.add(device);
202     }
203
204     /** @hide */
205     public boolean removeClient(String address) {
206         return mClients.remove(new WifiP2pDevice(address));
207     }
208
209     /** @hide */
210     public boolean removeClient(WifiP2pDevice device) {
211         return mClients.remove(device);
212     }
213
214     /** @hide */
215     public boolean isClientListEmpty() {
216         return mClients.size() == 0;
217     }
218
219     /** @hide Returns {@code true} if the device is part of the group */
220     public boolean contains(WifiP2pDevice device) {
221         if (mOwner.equals(device) || mClients.contains(device)) return true;
222         return false;
223     }
224
225     /** Get the list of clients currently part of the p2p group */
226     public Collection<WifiP2pDevice> getClientList() {
227         return Collections.unmodifiableCollection(mClients);
228     }
229
230     /** @hide */
231     public void setPassphrase(String passphrase) {
232         mPassphrase = passphrase;
233     }
234
235     /**
236      * Get the passphrase of the group. This function will return a valid passphrase only
237      * at the group owner. Legacy Wi-Fi clients will need this passphrase alongside
238      * network name obtained from {@link #getNetworkName()} to join the group
239      */
240     public String getPassphrase() {
241         return mPassphrase;
242     }
243
244     /** @hide */
245     public void setInterface(String intf) {
246         mInterface = intf;
247     }
248
249     /** Get the interface name on which the group is created */
250     public String getInterface() {
251         return mInterface;
252     }
253
254     /** @hide */
255     public int getNetworkId() {
256         return mNetId;
257     }
258
259     /** @hide */
260     public void setNetworkId(int netId) {
261         this.mNetId = netId;
262     }
263
264     public String toString() {
265         StringBuffer sbuf = new StringBuffer();
266         sbuf.append("network: ").append(mNetworkName);
267         sbuf.append("\n isGO: ").append(mIsGroupOwner);
268         sbuf.append("\n GO: ").append(mOwner);
269         for (WifiP2pDevice client : mClients) {
270             sbuf.append("\n Client: ").append(client);
271         }
272         sbuf.append("\n interface: ").append(mInterface);
273         sbuf.append("\n networkId: ").append(mNetId);
274         return sbuf.toString();
275     }
276
277     /** Implement the Parcelable interface */
278     public int describeContents() {
279         return 0;
280     }
281
282     /** copy constructor */
283     public WifiP2pGroup(WifiP2pGroup source) {
284         if (source != null) {
285             mNetworkName = source.getNetworkName();
286             mOwner = new WifiP2pDevice(source.getOwner());
287             mIsGroupOwner = source.mIsGroupOwner;
288             for (WifiP2pDevice d : source.getClientList()) mClients.add(d);
289             mPassphrase = source.getPassphrase();
290             mInterface = source.getInterface();
291             mNetId = source.getNetworkId();
292         }
293     }
294
295     /** Implement the Parcelable interface */
296     public void writeToParcel(Parcel dest, int flags) {
297         dest.writeString(mNetworkName);
298         dest.writeParcelable(mOwner, flags);
299         dest.writeByte(mIsGroupOwner ? (byte) 1: (byte) 0);
300         dest.writeInt(mClients.size());
301         for (WifiP2pDevice client : mClients) {
302             dest.writeParcelable(client, flags);
303         }
304         dest.writeString(mPassphrase);
305         dest.writeString(mInterface);
306         dest.writeInt(mNetId);
307     }
308
309     /** Implement the Parcelable interface */
310     public static final Creator<WifiP2pGroup> CREATOR =
311         new Creator<WifiP2pGroup>() {
312             public WifiP2pGroup createFromParcel(Parcel in) {
313                 WifiP2pGroup group = new WifiP2pGroup();
314                 group.setNetworkName(in.readString());
315                 group.setOwner((WifiP2pDevice)in.readParcelable(null));
316                 group.setIsGroupOwner(in.readByte() == (byte)1);
317                 int clientCount = in.readInt();
318                 for (int i=0; i<clientCount; i++) {
319                     group.addClient((WifiP2pDevice) in.readParcelable(null));
320                 }
321                 group.setPassphrase(in.readString());
322                 group.setInterface(in.readString());
323                 group.setNetworkId(in.readInt());
324                 return group;
325             }
326
327             public WifiP2pGroup[] newArray(int size) {
328                 return new WifiP2pGroup[size];
329             }
330         };
331 }