WifiP2pService.java revision bdfce2ec05a3e9ca6acd6711de6133e06f2446e6
155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/*
255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Copyright (C) 2011 The Android Open Source Project
355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Licensed under the Apache License, Version 2.0 (the "License");
555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * you may not use this file except in compliance with the License.
655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * You may obtain a copy of the License at
755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *      http://www.apache.org/licenses/LICENSE-2.0
955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
1055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Unless required by applicable law or agreed to in writing, software
1155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * distributed under the License is distributed on an "AS IS" BASIS,
1255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * See the License for the specific language governing permissions and
1455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * limitations under the License.
1555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
1655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffpackage android.net.wifi.p2p;
1855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.app.Activity;
20bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.app.ActivityManager;
2155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.app.AlertDialog;
22daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriffimport android.app.Notification;
23daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriffimport android.app.NotificationManager;
24daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriffimport android.app.PendingIntent;
25bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.app.ActivityManager.RunningTaskInfo;
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.BroadcastReceiver;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.Context;
2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.DialogInterface;
2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.DialogInterface.OnClickListener;
3055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.Intent;
3155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.IntentFilter;
3255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.pm.PackageManager;
3355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.res.Resources;
34aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.IConnectivityManager;
35aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.ConnectivityManager;
36aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.DhcpInfoInternal;
37aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.DhcpStateMachine;
38aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.InterfaceConfiguration;
39aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.LinkAddress;
40aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.LinkProperties;
41aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.NetworkInfo;
42aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.NetworkUtils;
4355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiManager;
4455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiMonitor;
4555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiNative;
4655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiStateMachine;
47651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriffimport android.net.wifi.WpsInfo;
480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenagaimport android.net.wifi.p2p.WifiP2pGroupList.GroupDeleteListener;
4921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
5021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
5121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
5255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Binder;
53bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.os.Bundle;
5455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.IBinder;
55cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.INetworkManagementService;
5655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Handler;
5755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.HandlerThread;
5855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Message;
59f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport android.os.Messenger;
60bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.os.Parcel;
61bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.os.Parcelable;
627d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriffimport android.os.RemoteException;
63cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.ServiceManager;
64cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.SystemProperties;
655ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
66bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenagaimport android.os.Parcelable.Creator;
679322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriffimport android.provider.Settings;
68618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.text.TextUtils;
6955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Slog;
7021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.util.SparseArray;
7155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.LayoutInflater;
7255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.View;
73618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.view.ViewGroup;
7455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.WindowManager;
7555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.widget.EditText;
76618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.widget.TextView;
7755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
78f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport com.android.internal.R;
79616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriffimport com.android.internal.telephony.TelephonyIntents;
8055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.AsyncChannel;
8155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.Protocol;
8255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.State;
8355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.StateMachine;
8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
85aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.FileDescriptor;
86aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.PrintWriter;
8721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.ArrayList;
88aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.util.Collection;
8921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.HashMap;
9021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.List;
91aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
9255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/**
93de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff * WifiP2pService includes a state machine to perform Wi-Fi p2p operations. Applications
9455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * communicate with this service to issue device discovery and connectivity requests
9555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * through the WifiP2pManager interface. The state machine communicates with the wifi
9655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * driver through wpa_supplicant and handles the event responses through WifiMonitor.
9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
9855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Note that the term Wifi when used without a p2p suffix refers to the client mode
9955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * of Wifi operation
10055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * @hide
10155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
10255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpublic class WifiP2pService extends IWifiP2pManager.Stub {
10355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TAG = "WifiP2pService";
1047d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final boolean DBG = false;
105aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private static final String NETWORKTYPE = "WIFI_P2P";
10655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
10755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private Context mContext;
108cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    private String mInterface;
109daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    private Notification mNotification;
110cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
111cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    INetworkManagementService mNwService;
112aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private DhcpStateMachine mDhcpStateMachine;
11355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
114bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private ActivityManager mActivityMgr;
115bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
11655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private P2pStateMachine mP2pStateMachine;
117ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private AsyncChannel mReplyChannel = new AsyncChannel();
11855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private AsyncChannel mWifiChannel;
11955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
120618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final Boolean JOIN_GROUP = true;
121618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final Boolean FORM_GROUP = false;
122618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final Boolean TRY_REINVOCATION = true;;
1240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final Boolean NO_REINVOCATION = false;
1250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final int CONNECT_FAILURE = -1;
1270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final int CONNECT_SUCCESS = 0;
1280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final int NEEDS_PROVISION_REQ = 1;
1290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
130ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Two minutes comes from the wpa_supplicant setting */
131618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
132618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static int mGroupCreatingTimeoutIndex = 0;
133aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1347d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    /* Set a two minute discover timeout to avoid STA scans from being blocked */
1357d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int DISCOVER_TIMEOUT_S = 120;
1367d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
13755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    /* Idle time after a peer is gone when the group is torn down */
138e0c28d5f1358fc2d4c464f910bd04fed4b283fefIrfan Sheriff    private static final int GROUP_IDLE_TIME_S = 20;
13955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
14055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
14155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
142618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* Delayed message to timeout group creation */
1437d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 1;
14455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
145618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* User accepted a peer request */
1467d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 2;
147618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* User rejected a peer request */
1487d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 3;
149295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff
1503809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff    /* Commands to the WifiStateMachine */
1513809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff    public static final int P2P_CONNECTION_CHANGED         =   BASE + 11;
1523809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff
15355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final boolean mP2pSupported;
154651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
155651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private WifiP2pDevice mThisDevice = new WifiP2pDevice();
1564be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
1574be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    /* When a group has been explicitly created by an app, we persist the group
1584be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * even after all clients have been disconnected until an explicit remove
1594be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * is invoked */
160bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean mAutonomousGroup;
16155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16210ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff    /* Invitation to join an existing p2p group */
16310ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff    private boolean mJoinExistingGroup;
16410ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff
165c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    /* Track whether we are in p2p discovery. This is used to avoid sending duplicate
166c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff     * broadcasts
167c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff     */
168c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private boolean mDiscoveryStarted;
169c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
170aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private NetworkInfo mNetworkInfo;
171aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
17221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* The transaction Id of service discovery request */
17321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private byte mServiceTransactionId = 0;
17421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
17521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* Service discovery request ID of wpa_supplicant.
17621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * null means it's not set yet. */
17721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private String mServiceDiscReqId;
17821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
17921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* clients(application) information list. */
18021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
18121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
182bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /* The foreground application's messenger.
183bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * The connection request is notified only to foreground application  */
184bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private Messenger mForegroundAppMessenger;
185bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
186bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /* the package name of foreground application. */
187bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private String mForegroundAppPkgName;
188bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
189859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    /* Is chosen as a unique range to avoid conflict with
190859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff       the range defined in Tethering.java */
191859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
192859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String SERVER_ADDRESS = "192.168.49.1";
193859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
1940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
1950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Error code definition.
1960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * see the Table.8 in the WiFi Direct specification for the detail.
1970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
1980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public static enum P2pStatus {
1990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Success. */
2000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        SUCCESS,
2010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* The target device is currently unavailable. */
2030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INFORMATION_IS_CURRENTLY_UNAVAILABLE,
2040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Protocol error. */
2060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INCOMPATIBLE_PARAMETERS,
2070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* The target device reached the limit of the number of the connectable device.
2090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga         * For example, device limit or group limit is set. */
2100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        LIMIT_REACHED,
2110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Protocol error. */
2130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INVALID_PARAMETER,
2140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Unable to accommodate request. */
2160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        UNABLE_TO_ACCOMMODATE_REQUEST,
2170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Previous protocol error, or disruptive behavior. */
2190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        PREVIOUS_PROTOCOL_ERROR,
2200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* There is no common channels the both devices can use. */
2220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        NO_COMMON_CHANNE,
2230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
2250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga         *  but device B has removed the specified credential already. */
2260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        UNKNOWN_P2P_GROUP,
2270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
2290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        BOTH_GO_INTENT_15,
2300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Incompatible provisioning method. */
2320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INCOMPATIBLE_PROVISIONING_METHOD,
2330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Rejected by user */
2350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        REJECTED_BY_USER,
2360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Unknown error */
2380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        UNKNOWN;
2390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        public static P2pStatus valueOf(int error) {
2410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            switch(error) {
2420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 0 :
2430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return SUCCESS;
2440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 1:
2450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
2460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 2:
2470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INCOMPATIBLE_PARAMETERS;
2480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 3:
2490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return LIMIT_REACHED;
2500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 4:
2510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INVALID_PARAMETER;
2520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 5:
2530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return UNABLE_TO_ACCOMMODATE_REQUEST;
2540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 6:
2550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return PREVIOUS_PROTOCOL_ERROR;
2560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 7:
2570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return NO_COMMON_CHANNE;
2580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 8:
2590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return UNKNOWN_P2P_GROUP;
2600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 9:
2610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return BOTH_GO_INTENT_15;
2620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 10:
2630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INCOMPATIBLE_PROVISIONING_METHOD;
2640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 11:
2650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return REJECTED_BY_USER;
2660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            default:
2670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return UNKNOWN;
2680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
2690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
2700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
2710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
27255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pService(Context context) {
27355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext = context;
27455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2757d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        //STOPSHIP: get this from native side
276fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mInterface = "p2p0";
277bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mActivityMgr = (ActivityManager)context.getSystemService(Activity.ACTIVITY_SERVICE);
278bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
279aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
280aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
281a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
282a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff                PackageManager.FEATURE_WIFI_DIRECT);
283a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff
284651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.primaryDeviceType = mContext.getResources().getString(
2859322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                com.android.internal.R.string.config_wifi_p2p_device_type);
28655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
28855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine.start();
289aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
29055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
291cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    public void connectivityServiceReady() {
292cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
293cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
294cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    }
295cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
29655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceAccessPermission() {
29755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
29955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceChangePermission() {
30255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
30355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
30455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
30555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
30755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Get a reference to handler. This is used by a client to establish
30855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * an AsyncChannel communication with WifiP2pService
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public Messenger getMessenger() {
31155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceAccessPermission();
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceChangePermission();
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return new Messenger(mP2pStateMachine.getHandler());
31455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    @Override
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
31855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                != PackageManager.PERMISSION_GRANTED) {
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + Binder.getCallingPid()
32255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + ", uid=" + Binder.getCallingUid());
32355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return;
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
32755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Handles interaction with WifiStateMachine
33055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
33155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class P2pStateMachine extends StateMachine {
33255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
33355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private DefaultState mDefaultState = new DefaultState();
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
33555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
33655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
33755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
33855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
33955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Inactive is when p2p is enabled with no connectivity
34055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private InactiveState mInactiveState = new InactiveState();
341618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
342618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private UserAuthorizingInvitationState mUserAuthorizingInvitationState
343618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                = new UserAuthorizingInvitationState();
344618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
34555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
346618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
34755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
348618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
349c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        private OngoingGroupRemovalState mOngoingGroupRemovalState = new OngoingGroupRemovalState();
35055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
351fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private WifiNative mWifiNative = new WifiNative(mInterface);
352fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
35355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
354d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown        private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
355d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown        private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
3560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                new GroupDeleteListener() {
3570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            @Override
3580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            public void onDeleteGroup(int netId) {
3590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (DBG) logd("called onDeleteGroup() netId=" + netId);
3600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                mWifiNative.removeNetwork(netId);
3610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                mWifiNative.saveConfig();
3620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                sendP2pPersistentGroupsChangedBroadcast();
3630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
3640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        });
365d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown        private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
36655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mGroup;
36755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
368618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        // Saved WifiP2pConfig for a peer connection
369618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private WifiP2pConfig mSavedPeerConfig;
37055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
37155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pGroup from invitation request
37255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mSavedP2pGroup;
37355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
374bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        // Saved WifiP2pDevice from provisioning request
375bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        private WifiP2pDevice mSavedProvDiscDevice;
376bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
37755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        P2pStateMachine(String name, boolean p2pSupported) {
37855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            super(name);
37955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
38055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            addState(mDefaultState);
38155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pNotSupportedState, mDefaultState);
38255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisablingState, mDefaultState);
38355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisabledState, mDefaultState);
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnablingState, mDefaultState);
38555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnabledState, mDefaultState);
38655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mInactiveState, mP2pEnabledState);
387618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    addState(mGroupCreatingState, mP2pEnabledState);
388618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mUserAuthorizingInvitationState, mGroupCreatingState);
389618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mProvisionDiscoveryState, mGroupCreatingState);
390618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mGroupNegotiationState, mGroupCreatingState);
39155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupCreatedState, mP2pEnabledState);
392618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
393c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        addState(mOngoingGroupRemovalState, mGroupCreatedState);
39455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
39555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (p2pSupported) {
39655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pDisabledState);
39755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else {
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pNotSupportedState);
39955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
40055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
40155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
40255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class DefaultState extends State {
40355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
40455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
405ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
40655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
40755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
40855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
409ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Full connection with WifiStateMachine established");
41055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = (AsyncChannel) message.obj;
41155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
412ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Full connection failure, error = " + message.arg1);
41355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = null;
41455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
41555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
41655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
41755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
41855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
419ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Send failed, client connection lost");
42055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
421ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Client connection lost with reason: " + message.arg1);
42255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
42355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel = null;
42455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
42555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
42755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    AsyncChannel ac = new AsyncChannel();
42855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    ac.connect(mContext, getHandler(), message.replyTo);
42955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
43055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
4314be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
4324be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
43355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
4347d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
4357d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
4367d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                            WifiP2pManager.BUSY);
4377d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    break;
43821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
43921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
44021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
44121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
44255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
4434be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
4444be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
44555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
446651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
447651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
448651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            WifiP2pManager.BUSY);
449651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    break;
45055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
4514be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
4524be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
45355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
45455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
4554be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
4564be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
45755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
45821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_LOCAL_SERVICE:
45921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
46021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
46121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
46221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
46321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
46421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
46521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
46621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
46721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
46821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
46921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
47021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
47121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
47221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
47321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
47421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
47521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
47621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
47721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
47821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
47921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
48021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
48121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
48221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
48321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
4842bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                case WifiP2pManager.SET_DEVICE_NAME:
4852bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
4862bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                            WifiP2pManager.BUSY);
4872bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    break;
4880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
4890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
4900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            WifiP2pManager.BUSY);
4910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
492ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                case WifiP2pManager.SET_WFD_INFO:
493ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
494ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                            WifiP2pManager.BUSY);
495ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    break;
49655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REQUEST_PEERS:
497d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,
498d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            new WifiP2pDeviceList(mPeers));
499ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
500ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REQUEST_CONNECTION_INFO:
501d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
502d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            new WifiP2pInfo(mWifiP2pInfo));
50355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
5044be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                case WifiP2pManager.REQUEST_GROUP_INFO:
505d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
506d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            mGroup != null ? new WifiP2pGroup(mGroup) : null);
5074be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    break;
5080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
5090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
510d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            new WifiP2pGroupList(mGroups, null));
5110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
512bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                case WifiP2pManager.SET_DIALOG_LISTENER:
513bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    String appPkgName = (String)message.getData().getString(
514bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            WifiP2pManager.APP_PKG_BUNDLE_KEY);
515bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    boolean isReset = message.getData().getBoolean(
516bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            WifiP2pManager.RESET_DIALOG_LISTENER_BUNDLE_KEY);
517bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (setDialogListenerApp(message.replyTo, appPkgName, isReset)) {
518bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.DIALOG_LISTENER_ATTACHED);
519bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    } else {
520bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.DIALOG_LISTENER_DETACHED,
521bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                WifiP2pManager.NOT_IN_FOREGROUND);
522bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
523bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    break;
524295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                    // Ignore
525618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
5267d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SCAN_RESULTS_EVENT:
5277d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUP_CONNECTION_EVENT:
5287d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
5297d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.NETWORK_CONNECTION_EVENT:
5307d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
5317d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
532d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
533d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_SUCCESS_EVENT:
534d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_FAIL_EVENT:
535d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_OVERLAP_EVENT:
536d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_TIMEOUT_EVENT:
53755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
5389cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
5399cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
5409cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
5419cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
5429cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
5439cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
544618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
545618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
546618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case GROUP_CREATING_TIMED_OUT:
547d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
548d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
549d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case DhcpStateMachine.CMD_ON_QUIT:
550c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
55155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
552bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    /* unexpected group created, remove */
55355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
55455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
55555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    loge("Unexpected group creation, remove " + mGroup);
55655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
55755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    break;
558de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // A group formation failure is always followed by
559de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // a group removed event. Flushing things at group formation
560de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // failure causes supplicant issues. Ignore right now.
56155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
56255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    break;
56355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
564ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Unhandled message " + message);
56555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
56655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
56755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
56855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
56955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
57055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
57155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pNotSupportedState extends State {
57255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
57355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
57455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
5757d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case WifiP2pManager.DISCOVER_PEERS:
5767d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
57855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
5797d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
5807d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
581ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
582ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
58321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
58421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
58521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
58621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
587ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CONNECT:
588ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
589ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
590ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
591651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
592651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
593651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
594651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    break;
5957d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case WifiP2pManager.CREATE_GROUP:
596ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
597ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
598ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
599ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
600ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
601ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
602ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
60321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_LOCAL_SERVICE:
60421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
60521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
60621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
607bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                case WifiP2pManager.SET_DIALOG_LISTENER:
608bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.DIALOG_LISTENER_DETACHED,
609bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            WifiP2pManager.P2P_UNSUPPORTED);
610bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    break;
61121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
61221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
61321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
61421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
61521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
61621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
61721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
61821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
61921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
62021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
62121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
62221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
62321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
62421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
62521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
62621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
62721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
62821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
62921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
63021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
63121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
63221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
6332bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                case WifiP2pManager.SET_DEVICE_NAME:
6342bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
6352bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
6362bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    break;
6370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
6380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
6390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            WifiP2pManager.P2P_UNSUPPORTED);
6400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
641ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                case WifiP2pManager.SET_WFD_INFO:
642ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
643ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                            WifiP2pManager.P2P_UNSUPPORTED);
644ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    break;
645ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff               default:
64655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
64755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
64855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
64955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
65055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
65155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
65255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisablingState extends State {
65355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
65455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
655ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
65655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
65755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
6587d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (DBG) logd("p2p socket connection lost");
65955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisabledState);
66055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
6617d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
6627d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
663ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
664ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
66555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
66655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
66755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
66855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
66955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
67055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
67155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
67255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisabledState extends State {
67355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       @Override
67455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
675ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
67655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
67755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
67855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
67955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
680ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
68155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
6827d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
683cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    try {
6847d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        mNwService.setInterfaceUp(mInterface);
6857d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } catch (RemoteException re) {
6867d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        loge("Unable to change interface settings: " + re);
6877d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } catch (IllegalStateException ie) {
6887d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        loge("Unable to change interface settings: " + ie);
68955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
6907d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    mWifiMonitor.startMonitoring();
6917d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    transitionTo(mP2pEnablingState);
69255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
6937d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
6947d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    //Nothing to do
695ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
69655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
69755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
69855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
69955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
70055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
70155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
70255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
70355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnablingState extends State {
70455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
70555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
706ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
70755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
70855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
70955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
71055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
711ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
71255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
71355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
7147d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (DBG) logd("P2p socket connection successful");
71555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
71655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
717ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
7187d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    loge("P2p socket connection failed");
719aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    transitionTo(mP2pDisabledState);
720ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
7217d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
7227d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
723ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
724ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
72555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
72655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
72755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
72855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
72955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
73055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
73155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
73255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnabledState extends State {
73355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
73455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
735ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
73655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(true);
737aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(true);
73855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            sendP2pConnectionChangedBroadcast();
7399322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff            initializeP2pSettings();
74055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
74155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
74255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
74355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
744ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
74555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
7467d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
7477d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    //Nothing to do
748ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
7497d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
750ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
7510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
7520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
7537d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    mWifiNative.closeSupplicantConnection();
75455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisablingState);
75555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
7562bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                case WifiP2pManager.SET_DEVICE_NAME:
757ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                {
7582bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
7592bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
7602bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                        if (DBG) logd("set device name " + d.deviceName);
7612bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
7622bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    } else {
7632bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
7642bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                                WifiP2pManager.ERROR);
7652bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    }
7662bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    break;
767ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                }
768ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                case WifiP2pManager.SET_WFD_INFO:
769ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                {
770ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
771ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    if (d != null && setWfdInfo(d)) {
772ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
773ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    } else {
774ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
775ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                                WifiP2pManager.ERROR);
776ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    }
777ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    break;
778ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                }
77955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
78021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    // do not send service discovery request while normal find operation.
78121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearSupplicantServiceRequest();
7827d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
783ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
784c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                        sendP2pDiscoveryChangedBroadcast(true);
785ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
7864be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
7874be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
788ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
78955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
790c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
791c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                    sendP2pDiscoveryChangedBroadcast(false);
792c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                    break;
7937d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
7947d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (mWifiNative.p2pStopFind()) {
7957d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
7967d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } else {
7977d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
7987d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                                WifiP2pManager.ERROR);
7997d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    }
8007d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    break;
80121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
80221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " discover services");
80321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (!updateSupplicantServiceRequest()) {
80421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
80521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                                WifiP2pManager.NO_SERVICE_REQUESTS);
80621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        break;
80721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
80821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
80921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED);
81021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    } else {
81121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
81221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                                WifiP2pManager.ERROR);
81321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
81421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
81555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
81655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
817651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;
8184be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPeers.update(device);
81955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
82055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
82155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
82255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    device = (WifiP2pDevice) message.obj;
82355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
82455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
82521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff               case WifiP2pManager.ADD_LOCAL_SERVICE:
82621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " add service");
82721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)message.obj;
82821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (addLocalService(message.replyTo, servInfo)) {
82921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
83021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    } else {
83121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED);
83221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
83321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
83421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
83521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " remove service");
83621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    servInfo = (WifiP2pServiceInfo)message.obj;
83721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    removeLocalService(message.replyTo, servInfo);
83821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED);
83921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
84021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
84121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " clear service");
84221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearLocalServices(message.replyTo);
84396aa0db9a997bc214471aa0d114a452aea6daa6dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_SUCCEEDED);
84421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
84521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
84621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " add service request");
84721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (!addServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj)) {
84821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED);
84921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        break;
85021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
85121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED);
85221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
85321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
85421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " remove service request");
85521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    removeServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj);
85621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED);
85721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
85821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
85921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " clear service request");
86021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearServiceRequests(message.replyTo);
86121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED);
86221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
86321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff               case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
86421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " receive service response");
86521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    List<WifiP2pServiceResponse> sdRespList =
86621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        (List<WifiP2pServiceResponse>) message.obj;
86721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    for (WifiP2pServiceResponse resp : sdRespList) {
86821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        WifiP2pDevice dev =
86921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            mPeers.get(resp.getSrcDevice().deviceAddress);
87021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        resp.setSrcDevice(dev);
87121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        sendServiceResponse(resp);
87221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
87321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
8740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga               case WifiP2pManager.DELETE_PERSISTENT_GROUP:
8750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   if (DBG) logd(getName() + " delete persistent group");
8760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   mGroups.remove(message.arg1);
8770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
8780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   break;
87921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                default:
88055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
88155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
88255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
88355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
88455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
88555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
88655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void exit() {
88755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(false);
888aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(false);
88955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
89055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
89155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
89255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class InactiveState extends State {
8934be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        @Override
8944be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        public void enter() {
895ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
8964be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            //Start listening every time we get inactive
8977d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            //TODO: Fix listen after driver behavior is fixed
8987d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            //mWifiNative.p2pListen();
89955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
90055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
90155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
90255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
903ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
90455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
905618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.CONNECT:
906618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd(getName() + " sending connect");
907bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
908bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mAutonomousGroup = false;
909bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
91057e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    /* Update group capability before connect */
91157e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    int gc = mWifiNative.getGroupCapability(config.deviceAddress);
91257e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    mPeers.updateGroupCapability(config.deviceAddress, gc);
9130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    int connectRet = connect(config, TRY_REINVOCATION);
9140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connectRet == CONNECT_FAILURE) {
9150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
9160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
917618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
918bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
919618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    sendP2pPeersChangedBroadcast();
920618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
9210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connectRet == NEEDS_PROVISION_REQ) {
9220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (DBG) logd("Sending prov disc");
9230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mProvisionDiscoveryState);
9240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
9250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
9260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    transitionTo(mGroupNegotiationState);
9270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
9280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.STOP_DISCOVERY:
9290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mWifiNative.p2pStopFind()) {
9300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // When discovery stops in inactive state, flush to clear
9310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // state peer data
9320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mWifiNative.p2pFlush();
9330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mServiceDiscReqId = null;
9340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
9350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    } else {
9360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
9370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                WifiP2pManager.ERROR);
9380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
939618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
94055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
941618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = (WifiP2pConfig) message.obj;
94210ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mAutonomousGroup = false;
94310ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mJoinExistingGroup = false;
944bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
945bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mSavedPeerConfig)) {
946bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        transitionTo(mUserAuthorizingInvitationState);
947bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
948618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
949618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
950618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
951bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    WifiP2pDevice owner = group.getOwner();
952bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
953bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    if (owner == null) {
954bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        if (DBG) loge("Ignored invitation from null owner");
955bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        break;
956bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    }
957bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
958bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
959bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    mSavedPeerConfig.deviceAddress = group.getOwner().deviceAddress;
960bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
961bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    //Check if we have the owner in peer list and use appropriate
962bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    //wps method. Default is to use PBC.
963bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if ((owner = mPeers.get(owner.deviceAddress)) != null) {
964bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        if (owner.wpsPbcSupported()) {
965bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.PBC;
966bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        } else if (owner.wpsKeypadSupported()) {
967bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
968bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        } else if (owner.wpsDisplaySupported()) {
969bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
970bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        }
971bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    }
972bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
97310ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mAutonomousGroup = false;
97410ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mJoinExistingGroup = true;
975bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //TODO In the p2p client case, we should set source address correctly.
976bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
977bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mSavedPeerConfig)) {
978bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        transitionTo(mUserAuthorizingInvitationState);
979bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
980618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
981618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
982618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
983618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
984bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //We let the supplicant handle the provision discovery response
985bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //and wait instead for the GO_NEGOTIATION_REQUEST_EVENT.
986bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //Handling provision discovery and issuing a p2p_connect before
987bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //group negotiation comes through causes issues
988bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                   break;
98955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
990de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                   mAutonomousGroup = true;
9910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   int netId = message.arg1;
9920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   boolean ret = false;
9930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
9940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       // check if the go persistent group is present.
9950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
9960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       if (netId != -1) {
9970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                           ret = mWifiNative.p2pGroupAdd(netId);
9980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       } else {
9990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                           ret = mWifiNative.p2pGroupAdd(true);
10000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       }
10010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   } else {
10020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       ret = mWifiNative.p2pGroupAdd(false);
10030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   }
10040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
10050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   if (ret) {
10060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
10070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       transitionTo(mGroupNegotiationState);
10080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   } else {
10090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
10100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                               WifiP2pManager.ERROR);
10110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       // remain at this state.
10120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   }
10130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   break;
10140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
10150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    mGroup = (WifiP2pGroup) message.obj;
10160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (DBG) logd(getName() + " group started");
10170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
10180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
10190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // This is an invocation case.
10200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mAutonomousGroup = false;
10210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        deferMessage(message);
10220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mGroupNegotiationState);
1023ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
10240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        return NOT_HANDLED;
1025ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
102655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1027618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff               default:
10280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   return NOT_HANDLED;
1029bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            }
1030bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            return HANDLED;
1031bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1032bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff    }
1033bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1034618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class GroupCreatingState extends State {
1035bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1036bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public void enter() {
1037bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName());
1038618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
1039618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
1040bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1041bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1042bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1043bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public boolean processMessage(Message message) {
1044bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName() + message.toString());
10459cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff            boolean ret = HANDLED;
1046bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            switch (message.what) {
1047618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff               case GROUP_CREATING_TIMED_OUT:
1048618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mGroupCreatingTimeoutIndex == message.arg1) {
1049618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Group negotiation timed out");
105055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        handleGroupCreationFailure();
1051618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mInactiveState);
1052618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1053bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
10549cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
10559cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1056ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff
1057ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                    // If we lose a device during an autonomous group creation,
1058ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                    // mSavedPeerConfig can be empty
1059ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                    if (mSavedPeerConfig != null &&
1060ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                            !mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
10619cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                        // Do the regular device lost handling
10629cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                        ret = NOT_HANDLED;
10639cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                        break;
10649cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    }
10659cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    // Do nothing
10669cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    if (DBG) logd("Retain connecting device " + device);
10679cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    break;
1068618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.DISCOVER_PEERS:
1069618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    /* Discovery will break negotiation */
1070618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1071618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            WifiP2pManager.BUSY);
1072bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
1073618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
107455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //Do a supplicant p2p_cancel which only cancels an ongoing
107555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //group negotiation. This will fail for a pending provision
107655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //discovery or for a pending user action, but at the framework
1077de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                    //level, we always treat cancel as succeeded and enter
107855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //an inactive state
107955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pCancelConnect();
108055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    handleGroupCreationFailure();
108155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    transitionTo(mInactiveState);
108255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
108355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1084ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
10859cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    ret = NOT_HANDLED;
108655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
10879cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff            return ret;
108855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
108955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
109055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1091618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class UserAuthorizingInvitationState extends State {
1092bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1093bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public void enter() {
1094bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName());
10950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            notifyInvitationReceived();
1096bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1097bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1098bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1099bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public boolean processMessage(Message message) {
1100bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1101bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            boolean ret = HANDLED;
1102bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            switch (message.what) {
1103618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
11040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connect(mSavedPeerConfig, TRY_REINVOCATION) == CONNECT_FAILURE) {
11050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        handleGroupCreationFailure();
11060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mInactiveState);
11070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
1108618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1109bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1110618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    sendP2pPeersChangedBroadcast();
1111618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupNegotiationState);
1112618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1113618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
1114618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
1115618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1116bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    transitionTo(mInactiveState);
1117bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
1118bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                default:
1119bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    return NOT_HANDLED;
1120bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            }
1121bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return ret;
1122bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1123618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1124618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1125618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void exit() {
1126618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            //TODO: dismiss dialog if not already done
1127618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1128bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff    }
1129bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1130618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class ProvisionDiscoveryState extends State {
1131618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1132618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void enter() {
1133618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName());
1134fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
1135618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1136618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1137618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1138618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public boolean processMessage(Message message) {
1139618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1140618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            WifiP2pProvDiscEvent provDisc;
1141618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            WifiP2pDevice device;
1142618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            switch (message.what) {
1143618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
1144618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1145618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
1146618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1147618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1148618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
1149618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
11504bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1151618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mGroupNegotiationState);
1152618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1153618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1154618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1155618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1156618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
1157618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1158618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1159618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
1160618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1161618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        /* we already have the pin */
1162618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
11634bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff                            p2pConnectWithPinDisplay(mSavedPeerConfig);
1164618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            transitionTo(mGroupNegotiationState);
1165618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        } else {
116610ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                            mJoinExistingGroup = false;
11670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
11680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                    mSavedPeerConfig)) {
11690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                transitionTo(mUserAuthorizingInvitationState);
11700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            }
1171618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        }
1172618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1173618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1174618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1175618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1176618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
1177618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1178618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1179618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
1180618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1181618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
11824bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1183bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (!sendShowPinReqToFrontApp(provDisc.pin)) {
1184bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            notifyInvitationSent(provDisc.pin, device.deviceAddress);
1185bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1186618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mGroupNegotiationState);
1187618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1188618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1189c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
1190c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    loge("provision discovery failed");
1191c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    handleGroupCreationFailure();
1192c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    transitionTo(mInactiveState);
1193c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    break;
1194618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                default:
1195618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    return NOT_HANDLED;
1196618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
1197618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            return HANDLED;
1198618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1199618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
1200bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
120155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupNegotiationState extends State {
1202aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        @Override
1203aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void enter() {
1204ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
120555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
120655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
120755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
120855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
1209ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
121055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
121155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // We ignore these right now, since we get a GROUP_STARTED notification
121255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // afterwards
121355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
121455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
1215ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go success");
121655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1217618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1218618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
1219618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd(getName() + " group started");
12200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
12210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
12220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        /*
12230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                         * update cache information and set network id to mGroup.
12240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                         */
12250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        updatePersistentNetworks();
12260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        String devAddr = mGroup.getOwner().deviceAddress;
12270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
12280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                mGroup.getNetworkName()));
12290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
12300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1231e0c28d5f1358fc2d4c464f910bd04fed4b283fefIrfan Sheriff                    mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
1232618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mGroup.isGroupOwner()) {
1233618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        startDhcpServer(mGroup.getInterface());
1234618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1235618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
1236618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                                P2pStateMachine.this, mGroup.getInterface());
1237618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
1238618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        WifiP2pDevice groupOwner = mGroup.getOwner();
1239c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        /* update group owner details with the ones found at discovery */
1240c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        groupOwner.update(mPeers.get(groupOwner.deviceAddress));
1241bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
1242618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
1243618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1244618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1245618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1246618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
124755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
1248de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1249ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go failure");
125055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    handleGroupCreationFailure();
125155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
125255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1253de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // A group formation failure is always followed by
1254de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // a group removed event. Flushing things at group formation
1255de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // failure causes supplicant issues. Ignore right now.
1256de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
1257de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                    break;
12580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
12590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    P2pStatus status = (P2pStatus)message.obj;
12600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (status == P2pStatus.SUCCESS) {
12610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // invocation was succeeded.
12620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // wait P2P_GROUP_STARTED_EVENT.
12630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
12640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
12650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // target device has already removed the credential.
12660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // So, remove this credential accordingly.
12670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        int netId = mSavedPeerConfig.netId;
12680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (netId >= 0) {
12690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (DBG) logd("Remove unknown client from the list");
12700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
12710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        }
12720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
12730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
12740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    // invocation is failed or deferred. Try another way to connect.
12750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
12760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connect(mSavedPeerConfig, NO_REINVOCATION) == CONNECT_FAILURE) {
12770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        handleGroupCreationFailure();
12780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mInactiveState);
12790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
12800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
128155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
128255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
128355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
128455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
128555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
128655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
128755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1288618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1289618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
129055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupCreatedState extends State {
129155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
129255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
1293ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
1294aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
1295859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
1296651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            updateThisDevice(WifiP2pDevice.CONNECTED);
1297651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
1298859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            //DHCP server has already been started if I am a group owner
1299859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            if (mGroup.isGroupOwner()) {
1300859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS);
1301859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            }
130255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
130355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
130455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
130555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
1306ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
130755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
130855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_CONNECTED_EVENT:
1309bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1310bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    String deviceAddress = device.deviceAddress;
13119322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
1312bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (mSavedProvDiscDevice != null &&
1313bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                deviceAddress.equals(mSavedProvDiscDevice.deviceAddress)) {
1314bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mSavedProvDiscDevice = null;
1315bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1316c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        mGroup.addClient(mPeers.get(deviceAddress));
1317bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED);
13189322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (DBG) logd(getName() + " ap sta connected");
13199322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        sendP2pPeersChangedBroadcast();
13209322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
1321bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        loge("Connect on null device address, ignore");
13229322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    }
1323e0c28d5f1358fc2d4c464f910bd04fed4b283fefIrfan Sheriff                    sendP2pConnectionChangedBroadcast();
132455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
132555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
132661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    device = (WifiP2pDevice) message.obj;
132761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    deviceAddress = device.deviceAddress;
13289322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
1329bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
13309322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (mGroup.removeClient(deviceAddress)) {
13319322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Removed client " + deviceAddress);
1332bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            if (!mAutonomousGroup && mGroup.isClientListEmpty()) {
13334be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
1334fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
13355ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                // We end up sending connection changed broadcast
13365ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                // when this happens at exit()
13375ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                            } else {
13385ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                // Notify when a client disconnects from group
13395ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                sendP2pConnectionChangedBroadcast();
13404be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            }
13419322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        } else {
13429322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Failed to remove client " + deviceAddress);
13439322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            for (WifiP2pDevice c : mGroup.getClientList()) {
13449322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                                if (DBG) logd("client " + c.deviceAddress);
13459322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            }
134655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
13474be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
13480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (DBG) logd(getName() + " ap sta disconnected");
13499322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
135061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        loge("Disconnect on unknown device: " + device);
135155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
135255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1353aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
1354aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
1355ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
1356ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            dhcpInfo != null) {
1357ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("DhcpInfo: " + dhcpInfo);
1358ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
1359aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        sendP2pConnectionChangedBroadcast();
136055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        //Turn on power save on client
136155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
1362ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
136361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        loge("DHCP failed");
1364fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
1365aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
1366aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
136755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
13680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (DBG) logd(getName() + " remove group");
1369fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
1370c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        transitionTo(mOngoingGroupRemovalState);
1371ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
1372ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
1373d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                        handleGroupRemoved();
1374d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                        transitionTo(mInactiveState);
13754be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
13764be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
1377ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
137855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1379d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                /* The supplicant misses the group removed event at times and just
1380d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                 * sends a network disconnect event */
1381d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
138255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
13830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (DBG) logd(getName() + " group removed");
1384d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                    handleGroupRemoved();
138555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
138655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
138755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1388bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    device = (WifiP2pDevice) message.obj;
1389530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    //Device loss for a connected device indicates it is not in discovery any more
1390530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    if (mGroup.contains(device)) {
1391530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                        if (DBG) logd("Lost " + device +" , do nothing");
1392530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                        return HANDLED;
139355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
1394530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    // Do the regular device lost handling
1395530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    return NOT_HANDLED;
13967d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
139755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.REMOVE_GROUP);
139855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
139955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
140055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
140155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
1402bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (config.deviceAddress == null ||
1403bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            (mSavedProvDiscDevice != null &&
1404bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    mSavedProvDiscDevice.deviceAddress.equals(
1405bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                            config.deviceAddress))) {
1406bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (config.wps.setup == WpsInfo.PBC) {
1407bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mWifiNative.startWpsPbc(mGroup.getInterface(), null);
1408bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        } else {
1409bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            if (config.wps.pin == null) {
1410bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
1411bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                try {
1412bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    Integer.parseInt(pin);
1413bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    if (!sendShowPinReqToFrontApp(pin)) {
1414bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                        notifyInvitationSent(pin,
1415bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                                config.deviceAddress != null ?
1416bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                                        config.deviceAddress : "any");
1417bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    }
1418bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                } catch (NumberFormatException ignore) {
1419bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    // do nothing if pin is invalid
1420bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                }
1421bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            } else {
1422bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
1423bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                        config.wps.pin);
1424bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            }
1425bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1426bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (config.deviceAddress != null) {
1427bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
1428bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            sendP2pPeersChangedBroadcast();
1429bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1430ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1431ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
1432bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        logd("Inviting device : " + config.deviceAddress);
14330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mSavedPeerConfig = config;
1434bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
1435bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
1436bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            sendP2pPeersChangedBroadcast();
1437bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1438bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        } else {
1439bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
1440bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    WifiP2pManager.ERROR);
1441bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1442ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
144355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // TODO: figure out updating the status to declined when invitation is rejected
144455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
14450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
14460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    P2pStatus status = (P2pStatus)message.obj;
14470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    logd("===> INVITATION RESULT EVENT : " + status);
14480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (status == P2pStatus.SUCCESS) {
14490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // invocation was succeeded.
14500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
14510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
14520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // target device has already removed the credential.
14530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // So, remove this credential accordingly.
14540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        int netId = mGroup.getNetworkId();
14550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (netId >= 0) {
14560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (DBG) logd("Remove unknown client from the list");
14570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (!removeClientFromList(netId,
14580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                    mSavedPeerConfig.deviceAddress, false)) {
14590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                // not found the client on the list
14600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                Slog.e(TAG, "Already removed the client, ignore");
14610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                break;
14620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            }
14630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            // try invitation.
14640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
14650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        }
14660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
14670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
146855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
146955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1470618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1471618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
1472bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mSavedProvDiscDevice = provDisc.device;
1473618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
1474618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
1475618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
1476618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
1477618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
1478618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
1479618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
1480618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1481618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
1482618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1483bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (!sendConnectNoticeToApp(mSavedProvDiscDevice, mSavedPeerConfig)) {
1484bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        transitionTo(mUserAuthorizingJoinState);
1485bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
148655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
14879322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
14889322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    Slog.e(TAG, "Duplicate group creation event notice, ignore");
14899322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    break;
149055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
149155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
149255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
149355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
149455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
1495aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1496aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void exit() {
1497bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mSavedProvDiscDevice = null;
1498651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            updateThisDevice(WifiP2pDevice.AVAILABLE);
14990a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff            resetWifiP2pInfo();
1500aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
1501ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            sendP2pConnectionChangedBroadcast();
1502aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
150355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
150455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1505618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class UserAuthorizingJoinState extends State {
1506618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1507618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void enter() {
1508618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName());
1509618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            notifyInvitationReceived();
1510618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1511618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1512618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1513618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public boolean processMessage(Message message) {
1514618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1515618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            switch (message.what) {
1516618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
1517618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1518618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1519618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    //Ignore more client requests
1520618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1521618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
1522618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
1523bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mWifiNative.startWpsPbc(mGroup.getInterface(), null);
1524618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1525bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
1526bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                mSavedPeerConfig.wps.pin);
1527618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1528618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1529618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1530618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1531618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
1532618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd("User rejected incoming request");
1533618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1534618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1535618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1536618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                default:
1537618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    return NOT_HANDLED;
1538618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
1539618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            return HANDLED;
1540618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1541618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1542618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1543618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void exit() {
1544618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            //TODO: dismiss dialog if not already done
1545618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1546618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
1547618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1548c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    class OngoingGroupRemovalState extends State {
1549c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        @Override
1550c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        public void enter() {
1551c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            if (DBG) logd(getName());
1552c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        }
1553c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff
1554c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        @Override
1555c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        public boolean processMessage(Message message) {
1556c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1557c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            switch (message.what) {
1558c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // Group removal ongoing. Multiple calls
1559c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // end up removing persisted network. Do nothing.
1560c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
1561c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
1562c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    break;
1563c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // Parent state will transition out of this state
1564c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // when removal is complete
1565c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                default:
1566c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    return NOT_HANDLED;
1567c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            }
1568c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            return HANDLED;
1569c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        }
1570c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    }
1571c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff
157255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pStateChangedBroadcast(boolean enabled) {
157355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
157455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
157555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (enabled) {
157655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
157755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
157855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
157955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
158055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
158155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
15825ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
158355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
158455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1585c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private void sendP2pDiscoveryChangedBroadcast(boolean started) {
1586c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        if (mDiscoveryStarted == started) return;
1587c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        mDiscoveryStarted = started;
1588c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1589c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        if (DBG) logd("discovery change broadcast " + started);
1590c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1591c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
1592c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1593c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, started ?
1594c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED :
1595c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
15965ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1597c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    }
1598c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1599651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void sendThisDeviceChangedBroadcast() {
1600651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
1601651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1602651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
16035ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1604651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
1605651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
160655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pPeersChangedBroadcast() {
160755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
160855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16095ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
161055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
161155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1612aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void sendP2pConnectionChangedBroadcast() {
1613ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (DBG) logd("sending p2p connection changed broadcast");
1614aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
1615aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
1616aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
1617ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
1618aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
16195ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16203809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff        mWifiChannel.sendMessage(WifiP2pService.P2P_CONNECTION_CHANGED,
16213809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                new NetworkInfo(mNetworkInfo));
1622aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1623aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
16240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private void sendP2pPersistentGroupsChangedBroadcast() {
16250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (DBG) logd("sending p2p persistent groups changed broadcast");
16260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
16270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16285ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
16300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1631aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void startDhcpServer(String intf) {
1632aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        InterfaceConfiguration ifcg = null;
1633aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1634aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg = mNwService.getInterfaceConfig(intf);
1635ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
1636ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                        SERVER_ADDRESS), 24));
1637ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            ifcg.setInterfaceUp();
1638aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.setInterfaceConfig(intf, ifcg);
1639aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            /* This starts the dnsmasq server */
1640859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            mNwService.startTethering(DHCP_RANGE);
1641aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1642ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error configuring interface " + intf + ", :" + e);
1643aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1644aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1645aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1646ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Started Dhcp server on " + intf);
1647859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff   }
1648aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1649b81bb9b40881659428f30b4539dd8877f9ea85f9Irfan Sheriff    private void stopDhcpServer(String intf) {
1650aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1651aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.stopTethering();
1652b81bb9b40881659428f30b4539dd8877f9ea85f9Irfan Sheriff            mNwService.clearInterfaceAddresses(intf);
1653aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1654ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error stopping Dhcp server" + e);
1655aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1656aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1657aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1658ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Stopped Dhcp server");
1659aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1660aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
166155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pEnableFailure() {
166255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
166355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
166455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
166555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
166655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
166755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
166855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
166955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
167055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
167155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1672618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void addRowToDialog(ViewGroup group, int stringId, String value) {
167355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1674618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
1675618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                group, false);
1676618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
1677618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ((TextView) row.findViewById(R.id.value)).setText(value);
1678618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        group.addView(row);
167955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
168055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1681618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void notifyInvitationSent(String pin, String peerAddress) {
168255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1683aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
168455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
1685618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                .inflate(R.layout.wifi_p2p_dialog, null);
1686618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1687618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
1688618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
1689618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
169055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
169155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
1692618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
169355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
1694618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setPositiveButton(r.getString(R.string.ok), null)
169555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
169655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
169755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
169855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
169955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1700618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void notifyInvitationReceived() {
170155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1702618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        final WpsInfo wps = mSavedPeerConfig.wps;
170355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
1704618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                .inflate(R.layout.wifi_p2p_dialog, null);
170555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1706618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
1707618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
1708618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mSavedPeerConfig.deviceAddress));
170955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1710618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
171155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
171255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
1713618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
171455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
1715618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
171655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1717618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (wps.setup == WpsInfo.KEYPAD) {
1718618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                                mSavedPeerConfig.wps.pin = pin.getText().toString();
1719618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            }
1720618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
1721618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
1722bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        }
1723bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    })
1724618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
1725bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        @Override
1726bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        public void onClick(DialogInterface dialog, int which) {
1727618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
1728618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            sendMessage(PEER_CONNECTION_USER_REJECT);
172955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
173055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
173110ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff            .setOnCancelListener(new DialogInterface.OnCancelListener() {
173210ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                        @Override
173310ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                        public void onCancel(DialogInterface arg0) {
173410ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
173510ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                            sendMessage(PEER_CONNECTION_USER_REJECT);
173610ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                        }
173710ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    })
173855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
173955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1740618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //make the enter pin area or the display pin area visible
1741618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        switch (wps.setup) {
1742618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.KEYPAD:
1743618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (DBG) logd("Enter pin section visible");
1744618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
1745618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1746618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.DISPLAY:
1747618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (DBG) logd("Shown pin section visible");
1748618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
1749618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1750618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            default:
1751618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1752618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
175355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
175455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
175555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
175655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
175755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
17590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Synchronize the persistent group list between
17600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * wpa_supplicant and mGroups.
17610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
17620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private void updatePersistentNetworks() {
17630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String listStr = mWifiNative.listNetworks();
1764d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (listStr == null) return;
17650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
17660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean isSaveRequired = false;
17670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String[] lines = listStr.split("\n");
1768d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (lines == null) return;
1769d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
17700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        // Skip the first line, which is a header
17710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (int i = 1; i < lines.length; i++) {
17720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String[] result = lines[i].split("\t");
17730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (result == null || result.length < 4) {
17740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
17750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
17760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // network-id | ssid | bssid | flags
17770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = -1;
17780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String ssid = result[1];
17790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String bssid = result[2];
17800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String flags = result[3];
17810879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            try {
17820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                netId = Integer.parseInt(result[0]);
17830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            } catch(NumberFormatException e) {
17840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                e.printStackTrace();
17850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
17860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
17870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
17880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (flags.indexOf("[CURRENT]") != -1) {
17890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
17900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
17910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
17920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                /*
17930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                 * The unused profile is sometimes remained when the p2p group formation is failed.
17940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                 * So, we clean up the p2p group here.
17950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                 */
17960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (DBG) logd("clean up the unused persistent group. netId=" + netId);
17970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                mWifiNative.removeNetwork(netId);
17980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                isSaveRequired = true;
17990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (mGroups.contains(netId)) {
18030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            WifiP2pGroup group = new WifiP2pGroup();
18070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            group.setNetworkId(netId);
18080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            group.setNetworkName(ssid);
18090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String mode = mWifiNative.getNetworkVariable(netId, "mode");
18100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (mode != null && mode.equals("3")) {
18110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                group.setIsGroupOwner(true);
18120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
18140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                group.setOwner(mThisDevice);
18150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            } else {
18160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                WifiP2pDevice device = new WifiP2pDevice();
18170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                device.deviceAddress = bssid;
18180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                group.setOwner(device);
18190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            mGroups.add(group);
18210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            isSaveRequired = true;
18220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (isSaveRequired) {
18250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            sendP2pPersistentGroupsChangedBroadcast();
18260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            mWifiNative.saveConfig();
18270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
18290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
18310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Try to connect to the target device.
18320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     *
18330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Use the persistent credential if it has been stored.
18340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     *
18350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param config
18360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param tryInvocation if true, try to invoke. Otherwise, never try to invoke.
18370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return
18380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
18390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private int connect(WifiP2pConfig config, boolean tryInvocation) {
18400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (config == null) {
18420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            loge("invalid argument.");
18430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return CONNECT_FAILURE;
18440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean isResp = (mSavedPeerConfig != null &&
18470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                config.deviceAddress.equals(mSavedPeerConfig.deviceAddress));
18480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mSavedPeerConfig = config;
18490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        WifiP2pDevice dev = mPeers.get(config.deviceAddress);
18510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (dev == null) {
18520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            loge("target device is not found.");
18530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return CONNECT_FAILURE;
18540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean join = dev.isGroupOwner();
18570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
18580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (DBG) logd("target ssid is " + ssid + " join:" + join);
18590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (join && dev.isGroupLimit()) {
18610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (DBG) logd("target device reaches group limit.");
18620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // if the target group has reached the limit,
18640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // try group formation.
18650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            join = false;
18660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        } else if (join) {
18670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
18680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (netId >= 0) {
18690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                // Skip WPS and start 4way handshake immediately.
18700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (!mWifiNative.p2pGroupAdd(netId)) {
18710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    return CONNECT_FAILURE;
18720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
18730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return CONNECT_SUCCESS;
18740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!join && dev.isDeviceLimit()) {
18780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            loge("target device reaches the device limit.");
18790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return CONNECT_FAILURE;
18800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18810879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!join && tryInvocation && dev.isInvitationCapable()) {
18830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = WifiP2pGroup.PERSISTENT_NET_ID;
18840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (config.netId >= 0) {
18850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
18860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    netId = config.netId;
18870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
18880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            } else {
18890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                netId = mGroups.getNetworkId(dev.deviceAddress);
18900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (netId < 0) {
18920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                netId = getNetworkIdFromClientList(dev.deviceAddress);
18930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
18950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (netId >= 0) {
18960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                // Invoke the persistent group.
1897c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                if (mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
1898c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    // Save network id. It'll be used when an invitation result event is received.
1899c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    mSavedPeerConfig.netId = netId;
1900c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    return CONNECT_SUCCESS;
1901c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                } else {
1902c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    loge("p2pReinvoke() failed, update networks");
1903c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    updatePersistentNetworks();
1904c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    // continue with negotiation
19050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        //Stop discovery before issuing connect
19100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mWifiNative.p2pStopFind();
19110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!isResp) {
19130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return NEEDS_PROVISION_REQ;
19140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19164bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        p2pConnectWithPinDisplay(config);
19170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return CONNECT_SUCCESS;
19180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
19190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
19210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Return the network id of the group owner profile which has the p2p client with
19220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * the specified device address in it's client list.
19230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * If more than one persistent group of the same address is present in its client
19240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * lists, return the first one.
19250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     *
19260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param deviceAddress p2p device address.
19270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return the network id. if not found, return -1.
19280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
19290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private int getNetworkIdFromClientList(String deviceAddress) {
19300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (deviceAddress == null) return -1;
19310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        Collection<WifiP2pGroup> groups = mGroups.getGroupList();
19330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (WifiP2pGroup group : groups) {
19340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = group.getNetworkId();
19350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String[] p2pClientList = getClientList(netId);
19360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (p2pClientList == null) continue;
19370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            for (String client : p2pClientList) {
19380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (deviceAddress.equalsIgnoreCase(client)) {
19390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    return netId;
19400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
1943ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return -1;
1944ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1945ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
19460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
19470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Return p2p client list associated with the specified network id.
19480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param netId network id.
19490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return p2p client list. if not found, return null.
19500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
19510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private String[] getClientList(int netId) {
19520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
19530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (p2pClients == null) {
19540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return null;
19550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return p2pClients.split(" ");
19570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
19580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
19600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Remove the specified p2p client from the specified profile.
19610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param netId network id of the profile.
19620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param addr p2p client address to be removed.
19630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param isRemovable if true, remove the specified profile if its client list becomes empty.
19640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return whether removing the specified p2p client is successful or not.
19650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
19660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
19670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        StringBuilder modifiedClientList =  new StringBuilder();
19680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String[] currentClientList = getClientList(netId);
19690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean isClientRemoved = false;
19700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (currentClientList != null) {
19710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            for (String client : currentClientList) {
19720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (!client.equalsIgnoreCase(addr)) {
19730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    modifiedClientList.append(" ");
19740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    modifiedClientList.append(client);
19750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                } else {
19760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    isClientRemoved = true;
19770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (modifiedClientList.length() == 0 && isRemovable) {
19810879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // the client list is empty. so remove it.
19820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (DBG) logd("Remove unknown network");
19830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            mGroups.remove(netId);
19840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return true;
19850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!isClientRemoved) {
19880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // specified p2p client is not found. already removed.
19890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return false;
19900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (DBG) logd("Modified client list: " + modifiedClientList);
19930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (modifiedClientList.length() == 0) {
19940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            modifiedClientList.append("\"\"");
19950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mWifiNative.setNetworkVariable(netId,
19970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                "p2p_client_list", modifiedClientList.toString());
19980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mWifiNative.saveConfig();
19990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return true;
20000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
20010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2002ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
2003ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = true;
2004ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
2005ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = NetworkUtils.numericToInetAddress(serverAddress);
2006ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2007ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
20080a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff    private void resetWifiP2pInfo() {
2009ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = false;
2010ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = false;
2011ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = null;
2012ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2013ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2014618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private String getDeviceName(String deviceAddress) {
2015bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        WifiP2pDevice d = mPeers.get(deviceAddress);
2016bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (d != null) {
2017618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return d.deviceName;
2018618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
2019618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //Treat the address as name if there is no match
2020618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        return deviceAddress;
2021618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
2022618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
20234bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff    private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
20244bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        WifiP2pDevice dev = mPeers.get(config.deviceAddress);
20254bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        if (dev == null) {
20264bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff            loge("target device is not found " + config.deviceAddress);
20274bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff            return;
20284bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        }
20294bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff
20304bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
2031bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        try {
2032bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            Integer.parseInt(pin);
2033bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (!sendShowPinReqToFrontApp(pin)) {
2034bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                notifyInvitationSent(pin, config.deviceAddress);
2035bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            }
2036bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        } catch (NumberFormatException ignore) {
2037bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            // do nothing if p2pConnect did not return a pin
2038bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        }
2039bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    }
2040bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
20412bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    private String getPersistedDeviceName() {
2042bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        String deviceName = Settings.Global.getString(mContext.getContentResolver(),
2043bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.WIFI_P2P_DEVICE_NAME);
20442bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        if (deviceName == null) {
20452bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            /* We use the 4 digits of the ANDROID_ID to have a friendly
20462bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff             * default that has low likelihood of collision with a peer */
20472bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            String id = Settings.Secure.getString(mContext.getContentResolver(),
20482bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    Settings.Secure.ANDROID_ID);
20492bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            return "Android_" + id.substring(0,4);
20502bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        }
20512bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        return deviceName;
20522bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    }
20532bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
20542bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    private boolean setAndPersistDeviceName(String devName) {
20552bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        if (devName == null) return false;
20562bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
20572bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        if (!mWifiNative.setDeviceName(devName)) {
20582bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            loge("Failed to set device name " + devName);
20592bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            return false;
20602bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        }
20612bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
20622bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        mThisDevice.deviceName = devName;
20632bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
20642bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
2065bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        Settings.Global.putString(mContext.getContentResolver(),
2066bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.WIFI_P2P_DEVICE_NAME, devName);
20672bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        sendThisDeviceChangedBroadcast();
20682bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        return true;
20692bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    }
20702bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
2071ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
2072ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        boolean success;
2073ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
2074ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        if (!wfdInfo.isWfdEnabled()) {
2075ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            success = mWifiNative.setWfdEnable(false);
2076ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        } else {
2077ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            success =
2078ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                mWifiNative.setWfdEnable(true)
2079ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                && mWifiNative.setWfdDeviceInfo(wfdInfo.getDeviceInfoHex());
2080ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        }
2081ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
2082ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        if (!success) {
2083ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            loge("Failed to set wfd properties");
2084ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            return false;
2085ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        }
2086ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
2087ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        mThisDevice.wfdInfo = wfdInfo;
2088ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        sendThisDeviceChangedBroadcast();
2089ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        return true;
2090ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    }
2091ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
20929322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private void initializeP2pSettings() {
2093fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setPersistentReconnect(true);
20942bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        mThisDevice.deviceName = getPersistedDeviceName();
2095fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setDeviceName(mThisDevice.deviceName);
2096de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // DIRECT-XY-DEVICENAME (XY is randomly generated)
2097fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
2098fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
2099de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // Supplicant defaults to using virtual display with display
2100de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // which refers to a remote display. Use physical_display
2101de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        mWifiNative.setConfigMethods("virtual_push_button physical_display keypad");
2102de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // STA has higher priority over P2P
210355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mWifiNative.setConcurrencyPriority("sta");
21044be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
2105fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
2106651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        updateThisDevice(WifiP2pDevice.AVAILABLE);
2107651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        if (DBG) Slog.d(TAG, "DeviceAddress: " + mThisDevice.deviceAddress);
210821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
210921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mClientInfoList.clear();
211021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pFlush();
211121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServiceFlush();
211221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceTransactionId = 0;
211321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = null;
21140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
21150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        updatePersistentNetworks();
2116651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
2117651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
2118651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void updateThisDevice(int status) {
2119651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.status = status;
2120651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        sendThisDeviceChangedBroadcast();
21219322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
21229322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
212355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    private void handleGroupCreationFailure() {
21240a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff        resetWifiP2pInfo();
21250a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.FAILED, null, null);
21260a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff        sendP2pConnectionChangedBroadcast();
212755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mSavedPeerConfig = null;
212855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        /* After cancelling group formation, new connections on existing peers can fail
212955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff         * at supplicant. Flush and restart discovery */
213055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mWifiNative.p2pFlush();
2131de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        mServiceDiscReqId = null;
213255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        sendMessage(WifiP2pManager.DISCOVER_PEERS);
213355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
213455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
2135d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff    private void handleGroupRemoved() {
2136d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        Collection <WifiP2pDevice> devices = mGroup.getClientList();
2137d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        boolean changed = false;
2138d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        for (WifiP2pDevice d : mPeers.getDeviceList()) {
2139d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            if (devices.contains(d) || mGroup.getOwner().equals(d)) {
2140d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                d.status = WifiP2pDevice.AVAILABLE;
2141d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                changed = true;
2142d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            }
2143d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        }
2144d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
2145d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (mGroup.isGroupOwner()) {
2146d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            stopDhcpServer(mGroup.getInterface());
2147d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        } else {
2148d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            if (DBG) logd("stop DHCP client");
2149d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
2150d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            mDhcpStateMachine.doQuit();
2151d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            mDhcpStateMachine = null;
2152d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        }
2153d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
2154d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        mGroup = null;
2155d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        mWifiNative.p2pFlush();
2156d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        mServiceDiscReqId = null;
2157d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (changed) sendP2pPeersChangedBroadcast();
2158d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff    }
2159d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
2160ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //State machine initiated requests can have replyTo set to null indicating
2161de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff    //there are no recipients, we ignore those reply actions
2162ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what) {
2163ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
2164651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
2165651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
2166651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
2167ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2168ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2169f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    private void replyToMessage(Message msg, int what, int arg1) {
2170f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff        if (msg.replyTo == null) return;
2171651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
2172651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
2173651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.arg1 = arg1;
2174651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
2175f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    }
2176f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff
2177ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what, Object obj) {
2178ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
2179651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
2180651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
2181651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.obj = obj;
2182651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
2183651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
2184651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
2185651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /* arg2 on the source message has a hash code that needs to be retained in replies
2186651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff     * see WifiP2pManager for details */
2187651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private Message obtainMessage(Message srcMsg) {
2188651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message msg = Message.obtain();
2189651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        msg.arg2 = srcMsg.arg2;
2190651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        return msg;
2191ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2192ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2193ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void logd(String s) {
2194ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.d(TAG, s);
2195ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2196ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2197ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void loge(String s) {
2198ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.e(TAG, s);
2199ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2200ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
220121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
220221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Update service discovery request to wpa_supplicant.
220321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
220421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean updateSupplicantServiceRequest() {
220521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearSupplicantServiceRequest();
220621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
220721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
220821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c: mClientInfoList.values()) {
220921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int key;
221021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            WifiP2pServiceRequest req;
221121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            for (int i=0; i < c.mReqList.size(); i++) {
22123b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                req = c.mReqList.valueAt(i);
221321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (req != null) {
221421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(req.getSupplicantQuery());
221521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
221621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
221721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
221821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
221921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (sb.length() == 0) {
222021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
222121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
222221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
222321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
222421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
222521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
222621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
222721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
222821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
222921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
223021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
223121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Clear service discovery request in wpa_supplicant
223221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
223321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearSupplicantServiceRequest() {
223421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) return;
223521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
223621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServDiscCancelReq(mServiceDiscReqId);
223721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = null;
223821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
223921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2240de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff    /* TODO: We could track individual service adds separately and avoid
224121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * having to do update all service requests on every new request
224221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
224321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean addServiceRequest(Messenger m, WifiP2pServiceRequest req) {
224421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearClientDeadChannels();
224521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, true);
224621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
224721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
224821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
224921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
22503b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        ++mServiceTransactionId;
22513b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //The Wi-Fi p2p spec says transaction id should be non-zero
22523b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        if (mServiceTransactionId == 0) ++mServiceTransactionId;
22533b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        req.setTransactionId(mServiceTransactionId);
225421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mReqList.put(mServiceTransactionId, req);
225521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
225621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
225721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return true;
225821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
225921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
226021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return updateSupplicantServiceRequest();
226121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
226221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
226321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
226421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
226521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
226621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
226721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
226821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
22693b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //Application does not have transaction id information
22703b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //go through stored requests to remove
22713b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        boolean removed = false;
22720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (int i=0; i<clientInfo.mReqList.size(); i++) {
22733b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            if (req.equals(clientInfo.mReqList.valueAt(i))) {
22743b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                removed = true;
22753b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                clientInfo.mReqList.removeAt(i);
22763b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                break;
22773b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            }
22783b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        }
22793b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
22803b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        if (!removed) return;
228121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
228221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
228321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
228421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
228521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
228621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
228721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
228821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
228921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
229021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
229121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        updateSupplicantServiceRequest();
229221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
229321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
229421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearServiceRequests(Messenger m) {
229521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
229621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
229721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
229821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
229921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
230021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
230121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0) {
230221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
230321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
230421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
230521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mReqList.clear();
230621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
230721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mServList.size() == 0) {
230821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove channel information from framework");
230921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
231021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
231121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
231221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
231321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
231421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
231521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
231621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        updateSupplicantServiceRequest();
231721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
231821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
231921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean addLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
232021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearClientDeadChannels();
232121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, true);
232221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
232321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
232421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
232521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
232621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!clientInfo.mServList.add(servInfo)) {
232721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
232821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
232921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
233021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!mWifiNative.p2pServiceAdd(servInfo)) {
233121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            clientInfo.mServList.remove(servInfo);
233221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
233321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
233421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
233521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
233621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
233721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
233821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void removeLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
233921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
234021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
234121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
234221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
234321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
234421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServiceDel(servInfo);
234521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
234621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mServList.remove(servInfo);
234721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
234821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
234921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
235021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
235121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
235221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
235321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearLocalServices(Messenger m) {
235421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
235521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
235621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
235721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
235821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
235921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (WifiP2pServiceInfo servInfo: clientInfo.mServList) {
236021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mWifiNative.p2pServiceDel(servInfo);
236121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
236221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
236321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mServList.clear();
236421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0) {
236521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
236621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
236721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
236821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
236921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
237021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearClientInfo(Messenger m) {
237121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearLocalServices(m);
237221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearServiceRequests(m);
237321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
237421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
237521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
237621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Send the service response to the WifiP2pManager.Channel.
237721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
237821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param resp
237921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
238021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void sendServiceResponse(WifiP2pServiceResponse resp) {
238121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c : mClientInfoList.values()) {
238221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            WifiP2pServiceRequest req = c.mReqList.get(resp.getTransactionId());
238321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (req != null) {
238421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                Message msg = Message.obtain();
238521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.what = WifiP2pManager.RESPONSE_SERVICE;
238621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.arg1 = 0;
238721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.arg2 = 0;
238821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.obj = resp;
238921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                try {
239021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    c.mMessenger.send(msg);
239121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } catch (RemoteException e) {
239221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd("detect dead channel");
239321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearClientInfo(c.mMessenger);
23943b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                    return;
239521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
239621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
239721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
239821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
239921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
240021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
240121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * We dont get notifications of clients that have gone away.
240221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * We detect this actively when services are added and throw
240321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * them away.
240421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
240521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * TODO: This can be done better with full async channels.
240621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
240721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearClientDeadChannels() {
24083b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
24093b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
241021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c : mClientInfoList.values()) {
241121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            Message msg = Message.obtain();
241221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.what = WifiP2pManager.PING;
241321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.arg1 = 0;
241421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.arg2 = 0;
241521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.obj = null;
241621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            try {
241721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                c.mMessenger.send(msg);
241821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } catch (RemoteException e) {
241921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (DBG) logd("detect dead channel");
24203b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                deadClients.add(c.mMessenger);
242121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
242221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
24233b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
24243b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        for (Messenger m : deadClients) {
24253b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            clearClientInfo(m);
24263b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        }
242721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
242821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
242921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
243021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return the specified ClientInfo.
243121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param m Messenger
243221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param createIfNotExist if true and the specified channel info does not exist,
243321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * create new client info.
243421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return the specified ClientInfo.
243521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
243621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private ClientInfo getClientInfo(Messenger m, boolean createIfNotExist) {
243721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = mClientInfoList.get(m);
243821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
243921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null && createIfNotExist) {
244021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("add a new client");
244121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            clientInfo = new ClientInfo(m);
244221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.put(m, clientInfo);
244321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
244421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
244521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return clientInfo;
244621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
244721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2448bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2449bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send detached message to dialog listener in the foreground application.
2450bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param reason
2451bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2452bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private void sendDetachedMsg(int reason) {
2453bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (mForegroundAppMessenger == null) return;
2454bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2455bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Message msg = Message.obtain();
2456bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.what = WifiP2pManager.DIALOG_LISTENER_DETACHED;
2457bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.arg1 = reason;
2458bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        try {
2459bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger.send(msg);
2460bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        } catch (RemoteException e) {
2461bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2462bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppMessenger = null;
2463bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppPkgName = null;
2464bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2465bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2466bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2467bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send a request to show wps pin to dialog listener in the foreground application.
2468bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param pin WPS pin
2469bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2470bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2471bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean sendShowPinReqToFrontApp(String pin) {
2472bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (!isForegroundApp(mForegroundAppPkgName)) {
2473bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            sendDetachedMsg(WifiP2pManager.NOT_IN_FOREGROUND);
2474bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2475bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2476bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Message msg = Message.obtain();
2477bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.what = WifiP2pManager.SHOW_PIN_REQUESTED;
2478bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Bundle bundle = new Bundle();
2479bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        bundle.putString(WifiP2pManager.WPS_PIN_BUNDLE_KEY, pin);
2480bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.setData(bundle);
2481bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return sendDialogMsgToFrontApp(msg);
2482bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2483bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2484bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2485bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send a request to establish the connection to dialog listener in the foreground
2486bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * application.
2487bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param dev source device
2488bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param config
2489bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2490bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2491bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean sendConnectNoticeToApp(WifiP2pDevice dev, WifiP2pConfig config) {
2492bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (dev == null) {
2493bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            dev = new WifiP2pDevice(config.deviceAddress);
2494bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2495bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2496bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (!isForegroundApp(mForegroundAppPkgName)) {
2497bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (DBG) logd("application is NOT foreground");
2498bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            sendDetachedMsg(WifiP2pManager.NOT_IN_FOREGROUND);
2499bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2500bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2501bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2502bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Message msg = Message.obtain();
2503bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.what = WifiP2pManager.CONNECTION_REQUESTED;
2504bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Bundle bundle = new Bundle();
2505bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        bundle.putParcelable(WifiP2pManager.P2P_DEV_BUNDLE_KEY, dev);
2506bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        bundle.putParcelable(WifiP2pManager.P2P_CONFIG_BUNDLE_KEY, config);
2507bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.setData(bundle);
2508bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return sendDialogMsgToFrontApp(msg);
2509bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2510bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2511bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2512bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send dialog event message to front application's dialog listener.
2513bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param msg
2514bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return true if success.
2515bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2516bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean sendDialogMsgToFrontApp(Message msg) {
2517bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        try {
2518bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger.send(msg);
2519bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        } catch (RemoteException e) {
2520bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger = null;
2521bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppPkgName = null;
2522bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2523bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2524bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return true;
2525bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2526bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2527bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2528bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Set dialog listener application.
2529bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param m
2530bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param appPkgName if null, reset the listener.
2531bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param isReset if true, try to reset.
2532bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2533bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2534bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean setDialogListenerApp(Messenger m,
2535bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            String appPkgName, boolean isReset) {
2536bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2537bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (mForegroundAppPkgName != null && !mForegroundAppPkgName.equals(appPkgName)) {
2538bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (isForegroundApp(mForegroundAppPkgName)) {
2539bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                // The current dialog listener is foreground app's.
2540bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                if (DBG) logd("application is NOT foreground");
2541bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                return false;
2542bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            }
2543bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            // detach an old listener.
2544bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            sendDetachedMsg(WifiP2pManager.NOT_IN_FOREGROUND);
2545bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2546bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2547bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (isReset) {
2548bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (DBG) logd("reset dialog listener");
2549bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger = null;
2550bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppPkgName = null;
2551bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return true;
2552bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2553bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2554bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (!isForegroundApp(appPkgName)) {
2555bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2556bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2557bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2558bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppMessenger = m;
2559bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppPkgName = appPkgName;
2560bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (DBG) logd("set dialog listener. app=" + appPkgName);
2561bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return true;
2562bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2563bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2564bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2565bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Return true if the specified package name is foreground app's.
2566bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     *
2567bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param pkgName application package name.
2568bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2569bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2570bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean isForegroundApp(String pkgName) {
2571bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (pkgName == null) return false;
2572bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2573bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        List<RunningTaskInfo> tasks = mActivityMgr.getRunningTasks(1);
2574bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (tasks.size() == 0) {
2575bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2576bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2577bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2578bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return pkgName.equals(tasks.get(0).baseActivity.getPackageName());
2579bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2580bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
258121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
258221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
258321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
258421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Information about a particular client and we track the service discovery requests
258521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * and the local services registered by the client.
258621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
258721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private class ClientInfo {
258821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
258921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
259021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A reference to WifiP2pManager.Channel handler.
259121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * The response of this request is notified to WifiP2pManager.Channel handler
259221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
259321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private Messenger mMessenger;
259421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
259521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
259621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A service discovery request list.
259721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
259821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private SparseArray<WifiP2pServiceRequest> mReqList;
259921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
260021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
260121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A local service information list.
260221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
260321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private List<WifiP2pServiceInfo> mServList;
260421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
260521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private ClientInfo(Messenger m) {
260621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mMessenger = m;
260721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mReqList = new SparseArray();
260821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mServList = new ArrayList<WifiP2pServiceInfo>();
260921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
261055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
261155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync}
2612