WifiP2pService.java revision 41de2404658c7c6faf6c78e777ba50af11784f5c
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
126ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff    private static final Boolean RELOAD = true;
127ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff    private static final Boolean NO_RELOAD = false;
128ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff
1290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final int CONNECT_FAILURE = -1;
1300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final int CONNECT_SUCCESS = 0;
1310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private static final int NEEDS_PROVISION_REQ = 1;
1320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
133ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Two minutes comes from the wpa_supplicant setting */
134618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
135618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static int mGroupCreatingTimeoutIndex = 0;
136aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1377d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    /* Set a two minute discover timeout to avoid STA scans from being blocked */
1387d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int DISCOVER_TIMEOUT_S = 120;
1397d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
14055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    /* Idle time after a peer is gone when the group is torn down */
141ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff    private static final int GROUP_IDLE_TIME_S = 10;
14255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
14355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
14455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
145618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* Delayed message to timeout group creation */
1467d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 1;
14755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
148618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* User accepted a peer request */
1497d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 2;
150618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* User rejected a peer request */
1517d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 3;
152295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff
1533809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff    /* Commands to the WifiStateMachine */
1543809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff    public static final int P2P_CONNECTION_CHANGED         =   BASE + 11;
1553809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff
15655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final boolean mP2pSupported;
157651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
158651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private WifiP2pDevice mThisDevice = new WifiP2pDevice();
1594be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
1604be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    /* When a group has been explicitly created by an app, we persist the group
1614be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * even after all clients have been disconnected until an explicit remove
1624be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * is invoked */
163bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean mAutonomousGroup;
16455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16510ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff    /* Invitation to join an existing p2p group */
16610ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff    private boolean mJoinExistingGroup;
16710ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff
168c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    /* Track whether we are in p2p discovery. This is used to avoid sending duplicate
169c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff     * broadcasts
170c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff     */
171c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private boolean mDiscoveryStarted;
172c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
173aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private NetworkInfo mNetworkInfo;
174aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
17521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* The transaction Id of service discovery request */
17621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private byte mServiceTransactionId = 0;
17721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
17821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* Service discovery request ID of wpa_supplicant.
17921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * null means it's not set yet. */
18021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private String mServiceDiscReqId;
18121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
18221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* clients(application) information list. */
18321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
18421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
185bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /* The foreground application's messenger.
186bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * The connection request is notified only to foreground application  */
187bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private Messenger mForegroundAppMessenger;
188bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
189bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /* the package name of foreground application. */
190bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private String mForegroundAppPkgName;
191bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
192859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    /* Is chosen as a unique range to avoid conflict with
193859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff       the range defined in Tethering.java */
194859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
195859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String SERVER_ADDRESS = "192.168.49.1";
196859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
1970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
1980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Error code definition.
1990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * see the Table.8 in the WiFi Direct specification for the detail.
2000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
2010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public static enum P2pStatus {
2020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Success. */
2030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        SUCCESS,
2040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* The target device is currently unavailable. */
2060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INFORMATION_IS_CURRENTLY_UNAVAILABLE,
2070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Protocol error. */
2090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INCOMPATIBLE_PARAMETERS,
2100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* The target device reached the limit of the number of the connectable device.
2120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga         * For example, device limit or group limit is set. */
2130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        LIMIT_REACHED,
2140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Protocol error. */
2160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INVALID_PARAMETER,
2170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Unable to accommodate request. */
2190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        UNABLE_TO_ACCOMMODATE_REQUEST,
2200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Previous protocol error, or disruptive behavior. */
2220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        PREVIOUS_PROTOCOL_ERROR,
2230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* There is no common channels the both devices can use. */
2250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        NO_COMMON_CHANNE,
2260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
2280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga         *  but device B has removed the specified credential already. */
2290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        UNKNOWN_P2P_GROUP,
2300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
2320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        BOTH_GO_INTENT_15,
2330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Incompatible provisioning method. */
2350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        INCOMPATIBLE_PROVISIONING_METHOD,
2360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Rejected by user */
2380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        REJECTED_BY_USER,
2390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        /* Unknown error */
2410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        UNKNOWN;
2420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        public static P2pStatus valueOf(int error) {
2440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            switch(error) {
2450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 0 :
2460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return SUCCESS;
2470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 1:
2480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
2490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 2:
2500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INCOMPATIBLE_PARAMETERS;
2510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 3:
2520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return LIMIT_REACHED;
2530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 4:
2540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INVALID_PARAMETER;
2550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 5:
2560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return UNABLE_TO_ACCOMMODATE_REQUEST;
2570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 6:
2580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return PREVIOUS_PROTOCOL_ERROR;
2590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 7:
2600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return NO_COMMON_CHANNE;
2610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 8:
2620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return UNKNOWN_P2P_GROUP;
2630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 9:
2640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return BOTH_GO_INTENT_15;
2650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 10:
2660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return INCOMPATIBLE_PROVISIONING_METHOD;
2670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            case 11:
2680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return REJECTED_BY_USER;
2690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            default:
2700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return UNKNOWN;
2710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
2720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
2730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
2740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
27555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pService(Context context) {
27655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext = context;
27755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2787d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        //STOPSHIP: get this from native side
279fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mInterface = "p2p0";
280bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mActivityMgr = (ActivityManager)context.getSystemService(Activity.ACTIVITY_SERVICE);
281bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
282aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
283aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
284a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
285a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff                PackageManager.FEATURE_WIFI_DIRECT);
286a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff
287651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.primaryDeviceType = mContext.getResources().getString(
2889322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                com.android.internal.R.string.config_wifi_p2p_device_type);
28955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
29055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
29155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine.start();
292aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
29355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
294cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    public void connectivityServiceReady() {
295cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
296cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
297cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    }
298cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
29955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceAccessPermission() {
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
30255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
30355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceChangePermission() {
30555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
30755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
30855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Get a reference to handler. This is used by a client to establish
31155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * an AsyncChannel communication with WifiP2pService
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public Messenger getMessenger() {
31455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceAccessPermission();
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceChangePermission();
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return new Messenger(mP2pStateMachine.getHandler());
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
31855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    @Override
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
32255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                != PackageManager.PERMISSION_GRANTED) {
32355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + Binder.getCallingPid()
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + ", uid=" + Binder.getCallingUid());
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return;
32755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
33055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
33155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
33255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Handles interaction with WifiStateMachine
33355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class P2pStateMachine extends StateMachine {
33555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
33655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private DefaultState mDefaultState = new DefaultState();
33755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
33855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
33955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
34055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
34155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
34255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Inactive is when p2p is enabled with no connectivity
34355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private InactiveState mInactiveState = new InactiveState();
344618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
345618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private UserAuthorizingInvitationState mUserAuthorizingInvitationState
346618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                = new UserAuthorizingInvitationState();
347618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
349618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
35055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
351618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
352c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        private OngoingGroupRemovalState mOngoingGroupRemovalState = new OngoingGroupRemovalState();
35355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
354fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private WifiNative mWifiNative = new WifiNative(mInterface);
355fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
35655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
357d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown        private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
35841de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff        /* During a connection, supplicant can tell us that a device was lost. From a supplicant's
35941de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         * perspective, the discovery stops during connection and it purges device since it does
36041de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         * not get latest updates about the device without being in discovery state.
36141de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         *
36241de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         * From the framework perspective, the device is still there since we are connecting or
36341de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         * connected to it. so we keep these devices in a seperate list, so that they are removed
36441de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         * when connection is cancelled or lost
36541de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff         */
36641de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff        private final WifiP2pDeviceList mPeersLostDuringConnection = new WifiP2pDeviceList();
367d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown        private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
3680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                new GroupDeleteListener() {
3690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            @Override
3700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            public void onDeleteGroup(int netId) {
3710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (DBG) logd("called onDeleteGroup() netId=" + netId);
3720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                mWifiNative.removeNetwork(netId);
3730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                mWifiNative.saveConfig();
3740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                sendP2pPersistentGroupsChangedBroadcast();
3750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
3760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        });
377d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown        private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
37855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mGroup;
37955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
380618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        // Saved WifiP2pConfig for a peer connection
381618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private WifiP2pConfig mSavedPeerConfig;
38255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
38355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pGroup from invitation request
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mSavedP2pGroup;
38555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
386bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        // Saved WifiP2pDevice from provisioning request
387bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        private WifiP2pDevice mSavedProvDiscDevice;
388bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
38955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        P2pStateMachine(String name, boolean p2pSupported) {
39055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            super(name);
39155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
39255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            addState(mDefaultState);
39355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pNotSupportedState, mDefaultState);
39455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisablingState, mDefaultState);
39555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisabledState, mDefaultState);
39655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnablingState, mDefaultState);
39755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnabledState, mDefaultState);
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mInactiveState, mP2pEnabledState);
399618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    addState(mGroupCreatingState, mP2pEnabledState);
400618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mUserAuthorizingInvitationState, mGroupCreatingState);
401618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mProvisionDiscoveryState, mGroupCreatingState);
402618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mGroupNegotiationState, mGroupCreatingState);
40355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupCreatedState, mP2pEnabledState);
404618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
405c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        addState(mOngoingGroupRemovalState, mGroupCreatedState);
40655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
40755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (p2pSupported) {
40855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pDisabledState);
40955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else {
41055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pNotSupportedState);
41155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
41255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
41355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
41455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class DefaultState extends State {
41555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
41655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
417ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
41855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
41955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
42055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
421ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Full connection with WifiStateMachine established");
42255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = (AsyncChannel) message.obj;
42355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
424ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Full connection failure, error = " + message.arg1);
42555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = null;
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
42755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
42855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
42955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
43055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
431ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Send failed, client connection lost");
43255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
433ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Client connection lost with reason: " + message.arg1);
43455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
43555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel = null;
43655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
43755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
43855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
43955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    AsyncChannel ac = new AsyncChannel();
44055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    ac.connect(mContext, getHandler(), message.replyTo);
44155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
44255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
4434be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
4444be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
44555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
4467d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
4477d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
4487d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                            WifiP2pManager.BUSY);
4497d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    break;
45021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
45121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
45221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
45321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
45455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
4554be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
4564be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
45755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
458651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
459651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
460651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            WifiP2pManager.BUSY);
461651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    break;
46255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
4634be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
4644be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
46555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
46655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
4674be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
4684be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
46955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
47021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_LOCAL_SERVICE:
47121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
47221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
47321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
47421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
47521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
47621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
47721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
47821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
47921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
48021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
48121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
48221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
48321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
48421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
48521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
48621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
48721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
48821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
48921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
49021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
49121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
49221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
49321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
49421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
49521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
4962bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                case WifiP2pManager.SET_DEVICE_NAME:
4972bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
4982bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                            WifiP2pManager.BUSY);
4992bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    break;
5000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
5010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
5020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            WifiP2pManager.BUSY);
5030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
504ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                case WifiP2pManager.SET_WFD_INFO:
505ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
506ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                            WifiP2pManager.BUSY);
507ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    break;
50855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REQUEST_PEERS:
509d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,
510d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            new WifiP2pDeviceList(mPeers));
511ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
512ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REQUEST_CONNECTION_INFO:
513d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
514d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            new WifiP2pInfo(mWifiP2pInfo));
51555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
5164be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                case WifiP2pManager.REQUEST_GROUP_INFO:
517d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
518d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            mGroup != null ? new WifiP2pGroup(mGroup) : null);
5194be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    break;
5200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
5210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
522d8544a51482c86b12da3ac82ea77b83045f689b7Jeff Brown                            new WifiP2pGroupList(mGroups, null));
5230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
524bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                case WifiP2pManager.SET_DIALOG_LISTENER:
525bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    String appPkgName = (String)message.getData().getString(
526bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            WifiP2pManager.APP_PKG_BUNDLE_KEY);
527bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    boolean isReset = message.getData().getBoolean(
528bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            WifiP2pManager.RESET_DIALOG_LISTENER_BUNDLE_KEY);
529bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (setDialogListenerApp(message.replyTo, appPkgName, isReset)) {
530bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.DIALOG_LISTENER_ATTACHED);
531bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    } else {
532bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.DIALOG_LISTENER_DETACHED,
533bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                WifiP2pManager.NOT_IN_FOREGROUND);
534bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
535bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    break;
536295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                    // Ignore
537618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
5387d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SCAN_RESULTS_EVENT:
5397d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUP_CONNECTION_EVENT:
5407d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
5417d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.NETWORK_CONNECTION_EVENT:
5427d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
5437d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
544d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
545d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_SUCCESS_EVENT:
546d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_FAIL_EVENT:
547d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_OVERLAP_EVENT:
548d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.WPS_TIMEOUT_EVENT:
54955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
5509cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
5519cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
5529cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
5539cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
5549cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
5559cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
556618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
557618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
558618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case GROUP_CREATING_TIMED_OUT:
559d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
560d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
561d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case DhcpStateMachine.CMD_ON_QUIT:
562c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
56355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
564bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    /* unexpected group created, remove */
56555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
56655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
56755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    loge("Unexpected group creation, remove " + mGroup);
56855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
56955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    break;
570de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // A group formation failure is always followed by
571de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // a group removed event. Flushing things at group formation
572de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // failure causes supplicant issues. Ignore right now.
57355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
57455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    break;
57555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
576ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Unhandled message " + message);
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
57855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
57955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
58055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
58155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
58255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
58355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pNotSupportedState extends State {
58455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
58555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
58655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
5877d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case WifiP2pManager.DISCOVER_PEERS:
5887d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
58955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
59055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
5917d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
5927d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
593ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
594ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
59521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
59621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
59721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
59821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
599ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CONNECT:
600ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
601ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
602ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
603651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
604651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
605651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
606651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    break;
6077d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case WifiP2pManager.CREATE_GROUP:
608ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
609ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
610ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
611ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
612ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
613ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
614ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
61521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_LOCAL_SERVICE:
61621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
61721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
61821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
619bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                case WifiP2pManager.SET_DIALOG_LISTENER:
620bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.DIALOG_LISTENER_DETACHED,
621bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            WifiP2pManager.P2P_UNSUPPORTED);
622bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    break;
62321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
62421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
62521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
62621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
62721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
62821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
62921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
63021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
63121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
63221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
63321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
63421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
63521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
63621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
63721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
63821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
63921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
64021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
64121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
64221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
64321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
64421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
6452bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                case WifiP2pManager.SET_DEVICE_NAME:
6462bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
6472bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
6482bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    break;
6490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
6500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
6510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            WifiP2pManager.P2P_UNSUPPORTED);
6520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
653ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                case WifiP2pManager.SET_WFD_INFO:
654ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
655ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                            WifiP2pManager.P2P_UNSUPPORTED);
656ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    break;
657ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff               default:
65855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
65955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
66055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
66155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
66255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
66355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
66455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisablingState extends State {
66555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
66655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
667ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
66855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
66955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
6707d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (DBG) logd("p2p socket connection lost");
67155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisabledState);
67255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
6737d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
6747d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
675ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
676ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
67755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
67855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
67955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
68055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
68155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
68255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
68355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
68455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisabledState extends State {
68555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       @Override
68655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
687ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
68855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
68955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
69055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
69155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
692ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
69355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
6947d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
695cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    try {
6967d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        mNwService.setInterfaceUp(mInterface);
6977d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } catch (RemoteException re) {
6987d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        loge("Unable to change interface settings: " + re);
6997d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } catch (IllegalStateException ie) {
7007d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        loge("Unable to change interface settings: " + ie);
70155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
7027d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    mWifiMonitor.startMonitoring();
7037d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    transitionTo(mP2pEnablingState);
70455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
7057d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
7067d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    //Nothing to do
707ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
70855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
70955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
71055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
71155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
71255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
71355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
71455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
71555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnablingState extends State {
71655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
71755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
718ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
71955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
72055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
72155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
72255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
723ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
72455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
72555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
7267d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (DBG) logd("P2p socket connection successful");
72755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
72855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
729ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
7307d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    loge("P2p socket connection failed");
731aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    transitionTo(mP2pDisabledState);
732ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
7337d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
7347d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
735ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
736ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
73755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
73855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
73955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
74055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
74155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
74255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
74355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
74455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnabledState extends State {
74555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
74655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
747ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
74855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(true);
749aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(true);
75055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            sendP2pConnectionChangedBroadcast();
7519322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff            initializeP2pSettings();
75255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
75355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
75455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
75555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
756ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
75755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
75841de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
75941de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                    loge("Unexpected loss of p2p socket connection");
76041de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                    transitionTo(mP2pDisabledState);
76141de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                    break;
7627d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
7637d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    //Nothing to do
764ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
7657d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
766ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
7670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
7680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
7697d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    mWifiNative.closeSupplicantConnection();
77055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisablingState);
77155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
7722bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                case WifiP2pManager.SET_DEVICE_NAME:
773ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                {
7742bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
7752bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
7762bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                        if (DBG) logd("set device name " + d.deviceName);
7772bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
7782bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    } else {
7792bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
7802bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                                WifiP2pManager.ERROR);
7812bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    }
7822bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    break;
783ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                }
784ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                case WifiP2pManager.SET_WFD_INFO:
785ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                {
786ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
787ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    if (d != null && setWfdInfo(d)) {
788ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
789ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    } else {
790ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
791ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                                WifiP2pManager.ERROR);
792ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    }
793ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    break;
794ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                }
79555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
79621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    // do not send service discovery request while normal find operation.
79721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearSupplicantServiceRequest();
7987d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
799ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
800c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                        sendP2pDiscoveryChangedBroadcast(true);
801ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
8024be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
8034be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
804ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
80555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
806c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
807c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                    sendP2pDiscoveryChangedBroadcast(false);
808c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                    break;
8097d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
8107d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (mWifiNative.p2pStopFind()) {
8117d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
8127d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } else {
8137d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
8147d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                                WifiP2pManager.ERROR);
8157d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    }
8167d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    break;
81721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
81821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " discover services");
81921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (!updateSupplicantServiceRequest()) {
82021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
82121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                                WifiP2pManager.NO_SERVICE_REQUESTS);
82221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        break;
82321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
82421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
82521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED);
82621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    } else {
82721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
82821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                                WifiP2pManager.ERROR);
82921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
83021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
83155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
83255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
833651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;
8344be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPeers.update(device);
83555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
83655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
83755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
83855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    device = (WifiP2pDevice) message.obj;
83955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
84055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
84121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff               case WifiP2pManager.ADD_LOCAL_SERVICE:
84221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " add service");
84321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)message.obj;
84421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (addLocalService(message.replyTo, servInfo)) {
84521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
84621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    } else {
84721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED);
84821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
84921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
85021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
85121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " remove service");
85221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    servInfo = (WifiP2pServiceInfo)message.obj;
85321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    removeLocalService(message.replyTo, servInfo);
85421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED);
85521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
85621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
85721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " clear service");
85821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearLocalServices(message.replyTo);
85996aa0db9a997bc214471aa0d114a452aea6daa6dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_SUCCEEDED);
86021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
86121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
86221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " add service request");
86321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (!addServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj)) {
86421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED);
86521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        break;
86621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
86721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED);
86821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
86921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
87021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " remove service request");
87121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    removeServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj);
87221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED);
87321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
87421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
87521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " clear service request");
87621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearServiceRequests(message.replyTo);
87721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED);
87821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
87921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff               case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
88021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " receive service response");
88121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    List<WifiP2pServiceResponse> sdRespList =
88221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        (List<WifiP2pServiceResponse>) message.obj;
88321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    for (WifiP2pServiceResponse resp : sdRespList) {
88421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        WifiP2pDevice dev =
88521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            mPeers.get(resp.getSrcDevice().deviceAddress);
88621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        resp.setSrcDevice(dev);
88721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        sendServiceResponse(resp);
88821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
88921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
8900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga               case WifiP2pManager.DELETE_PERSISTENT_GROUP:
8910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   if (DBG) logd(getName() + " delete persistent group");
8920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   mGroups.remove(message.arg1);
8930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
8940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   break;
89521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                default:
89655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
89755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
89855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
89955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
90055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
90155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
90255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void exit() {
90355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(false);
904aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(false);
90555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
90655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
90755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
90855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class InactiveState extends State {
9094be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        @Override
9104be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        public void enter() {
911ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
9124be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            //Start listening every time we get inactive
9137d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            //TODO: Fix listen after driver behavior is fixed
9147d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            //mWifiNative.p2pListen();
91555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
91655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
91755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
91855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
919ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
92055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
921618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.CONNECT:
922618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd(getName() + " sending connect");
923bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
924bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mAutonomousGroup = false;
925bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
92657e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    /* Update group capability before connect */
92757e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    int gc = mWifiNative.getGroupCapability(config.deviceAddress);
92857e42f4117e92c03d39f1e1e572f53ef5bb821b8Irfan Sheriff                    mPeers.updateGroupCapability(config.deviceAddress, gc);
9290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    int connectRet = connect(config, TRY_REINVOCATION);
9300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connectRet == CONNECT_FAILURE) {
9310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
9320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
933618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
934bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
935618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    sendP2pPeersChangedBroadcast();
936618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
9370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connectRet == NEEDS_PROVISION_REQ) {
9380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (DBG) logd("Sending prov disc");
9390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mProvisionDiscoveryState);
9400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
9410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
9420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    transitionTo(mGroupNegotiationState);
9430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
9440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiP2pManager.STOP_DISCOVERY:
9450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mWifiNative.p2pStopFind()) {
9460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // When discovery stops in inactive state, flush to clear
9470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // state peer data
9480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mWifiNative.p2pFlush();
9490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mServiceDiscReqId = null;
9500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
9510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    } else {
9520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
9530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                WifiP2pManager.ERROR);
9540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
955618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
95655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
957618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = (WifiP2pConfig) message.obj;
95810ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mAutonomousGroup = false;
95910ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mJoinExistingGroup = false;
960bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
961bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mSavedPeerConfig)) {
962bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        transitionTo(mUserAuthorizingInvitationState);
963bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
964618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
965618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
966618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
967bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    WifiP2pDevice owner = group.getOwner();
968bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
969bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    if (owner == null) {
970bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        if (DBG) loge("Ignored invitation from null owner");
971bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        break;
972bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    }
973bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
974bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
975bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    mSavedPeerConfig.deviceAddress = group.getOwner().deviceAddress;
976bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
977bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    //Check if we have the owner in peer list and use appropriate
978bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    //wps method. Default is to use PBC.
979bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if ((owner = mPeers.get(owner.deviceAddress)) != null) {
980bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        if (owner.wpsPbcSupported()) {
981bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.PBC;
982bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        } else if (owner.wpsKeypadSupported()) {
983bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
984bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        } else if (owner.wpsDisplaySupported()) {
985bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
986bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        }
987bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    }
988bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
98910ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mAutonomousGroup = false;
99010ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    mJoinExistingGroup = true;
991bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //TODO In the p2p client case, we should set source address correctly.
992bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
993bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mSavedPeerConfig)) {
994bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        transitionTo(mUserAuthorizingInvitationState);
995bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
996618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
997618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
998618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
999618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1000bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //We let the supplicant handle the provision discovery response
1001bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //and wait instead for the GO_NEGOTIATION_REQUEST_EVENT.
1002bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //Handling provision discovery and issuing a p2p_connect before
1003bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    //group negotiation comes through causes issues
1004bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                   break;
100555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
1006de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                   mAutonomousGroup = true;
10070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   int netId = message.arg1;
10080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   boolean ret = false;
10090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
10100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       // check if the go persistent group is present.
10110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
10120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       if (netId != -1) {
10130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                           ret = mWifiNative.p2pGroupAdd(netId);
10140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       } else {
10150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                           ret = mWifiNative.p2pGroupAdd(true);
10160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       }
10170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   } else {
10180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       ret = mWifiNative.p2pGroupAdd(false);
10190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   }
10200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
10210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   if (ret) {
10220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
10230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       transitionTo(mGroupNegotiationState);
10240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   } else {
10250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
10260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                               WifiP2pManager.ERROR);
10270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                       // remain at this state.
10280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   }
10290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   break;
10300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
10310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    mGroup = (WifiP2pGroup) message.obj;
10320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (DBG) logd(getName() + " group started");
10330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
10340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
10350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // This is an invocation case.
10360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mAutonomousGroup = false;
10370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        deferMessage(message);
10380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mGroupNegotiationState);
1039ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
10400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        return NOT_HANDLED;
1041ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
104255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1043618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff               default:
10440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                   return NOT_HANDLED;
1045bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            }
1046bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            return HANDLED;
1047bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1048bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff    }
1049bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1050618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class GroupCreatingState extends State {
1051bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1052bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public void enter() {
1053bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName());
1054618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
1055618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
1056bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1057bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1058bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1059bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public boolean processMessage(Message message) {
1060bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName() + message.toString());
10619cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff            boolean ret = HANDLED;
1062bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            switch (message.what) {
1063618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff               case GROUP_CREATING_TIMED_OUT:
1064618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mGroupCreatingTimeoutIndex == message.arg1) {
1065618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Group negotiation timed out");
106655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        handleGroupCreationFailure();
1067618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mInactiveState);
1068618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1069bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
10709cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
10719cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1072ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff
1073ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                    // If we lose a device during an autonomous group creation,
1074ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                    // mSavedPeerConfig can be empty
1075ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                    if (mSavedPeerConfig != null &&
1076ba5065eaf3bd633aa30e0eb00b8a76b7bf33d36dIrfan Sheriff                            !mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
10779cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                        // Do the regular device lost handling
10789cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                        ret = NOT_HANDLED;
10799cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                        break;
10809cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    }
10819cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    // Do nothing
108241de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                    if (DBG) logd("Add device to lost list " + device);
108341de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                    mPeersLostDuringConnection.update(device);
10849cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    break;
1085618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.DISCOVER_PEERS:
1086618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    /* Discovery will break negotiation */
1087618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1088618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            WifiP2pManager.BUSY);
1089bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
1090618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
109155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //Do a supplicant p2p_cancel which only cancels an ongoing
109255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //group negotiation. This will fail for a pending provision
109355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //discovery or for a pending user action, but at the framework
1094de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                    //level, we always treat cancel as succeeded and enter
109555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //an inactive state
109655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pCancelConnect();
109755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    handleGroupCreationFailure();
109855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    transitionTo(mInactiveState);
109955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
110055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1101ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
11029cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff                    ret = NOT_HANDLED;
110355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
11049cb980422ac53b81d6ad15242b0de35b5f3ce13cIrfan Sheriff            return ret;
110555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
110655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
110755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1108618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class UserAuthorizingInvitationState extends State {
1109bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1110bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public void enter() {
1111bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName());
11120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            notifyInvitationReceived();
1113bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1114bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1115bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
1116bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public boolean processMessage(Message message) {
1117bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1118bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            boolean ret = HANDLED;
1119bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            switch (message.what) {
1120618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
11210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (connect(mSavedPeerConfig, TRY_REINVOCATION) == CONNECT_FAILURE) {
11220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        handleGroupCreationFailure();
11230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mInactiveState);
11240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
1125618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1126bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1127618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    sendP2pPeersChangedBroadcast();
1128618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupNegotiationState);
1129618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1130618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
1131618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
1132618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1133bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    transitionTo(mInactiveState);
1134bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
1135bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                default:
1136bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    return NOT_HANDLED;
1137bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            }
1138bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return ret;
1139bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
1140618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1141618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1142618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void exit() {
1143618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            //TODO: dismiss dialog if not already done
1144618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1145bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff    }
1146bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
1147618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class ProvisionDiscoveryState extends State {
1148618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1149618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void enter() {
1150618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName());
1151fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
1152618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1153618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1154618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1155618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public boolean processMessage(Message message) {
1156618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1157618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            WifiP2pProvDiscEvent provDisc;
1158618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            WifiP2pDevice device;
1159618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            switch (message.what) {
1160618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
1161618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1162618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
1163618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1164618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1165618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
1166618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
11674bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1168618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mGroupNegotiationState);
1169618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1170618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1171618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1172618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1173618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
1174618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1175618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1176618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
1177618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1178618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        /* we already have the pin */
1179618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
11804bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff                            p2pConnectWithPinDisplay(mSavedPeerConfig);
1181618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            transitionTo(mGroupNegotiationState);
1182618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        } else {
118310ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                            mJoinExistingGroup = false;
11840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
11850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                    mSavedPeerConfig)) {
11860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                transitionTo(mUserAuthorizingInvitationState);
11870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            }
1188618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        }
1189618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1190618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1191618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1192618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1193618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
1194618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1195618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1196618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
1197618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1198618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
11994bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1200bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (!sendShowPinReqToFrontApp(provDisc.pin)) {
1201bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            notifyInvitationSent(provDisc.pin, device.deviceAddress);
1202bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1203618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mGroupNegotiationState);
1204618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1205618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1206c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
1207c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    loge("provision discovery failed");
1208c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    handleGroupCreationFailure();
1209c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    transitionTo(mInactiveState);
1210c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    break;
1211618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                default:
1212618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    return NOT_HANDLED;
1213618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
1214618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            return HANDLED;
1215618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1216618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
1217bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
121855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupNegotiationState extends State {
1219aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        @Override
1220aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void enter() {
1221ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
122255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
122355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
122455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
122555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
1226ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
122755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
122855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // We ignore these right now, since we get a GROUP_STARTED notification
122955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // afterwards
123055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
123155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
1232ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go success");
123355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1234618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1235618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
1236618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd(getName() + " group started");
12370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
12380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
12390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        /*
12400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                         * update cache information and set network id to mGroup.
12410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                         */
1242ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                        updatePersistentNetworks(NO_RELOAD);
12430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        String devAddr = mGroup.getOwner().deviceAddress;
12440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
12450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                mGroup.getNetworkName()));
12460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
12470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1248618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mGroup.isGroupOwner()) {
1249ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                        /* Setting an idle time out on GO causes issues with certain scenarios
1250ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                         * on clients where it can be off-channel for longer and with the power
1251ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                         * save modes used.
1252ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                         *
1253ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                         * TODO: Verify multi-channel scenarios and supplicant behavior are
1254ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                         * better before adding a time out in future
1255ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                         */
1256618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        startDhcpServer(mGroup.getInterface());
1257618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1258ce6fc8d7a49d1b246e37c4e87fd5e715e408bca2Irfan Sheriff                        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
1259618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
1260618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                                P2pStateMachine.this, mGroup.getInterface());
1261618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
1262618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        WifiP2pDevice groupOwner = mGroup.getOwner();
1263c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        /* update group owner details with the ones found at discovery */
1264c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        groupOwner.update(mPeers.get(groupOwner.deviceAddress));
1265bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
1266618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
1267618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1268618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1269618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1270618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
127155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
1272de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1273ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go failure");
127455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    handleGroupCreationFailure();
127555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
127655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1277de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // A group formation failure is always followed by
1278de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // a group removed event. Flushing things at group formation
1279de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                // failure causes supplicant issues. Ignore right now.
1280de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
1281de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff                    break;
12820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
12830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    P2pStatus status = (P2pStatus)message.obj;
12840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (status == P2pStatus.SUCCESS) {
12850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // invocation was succeeded.
12860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // wait P2P_GROUP_STARTED_EVENT.
12870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
12880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
12890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // target device has already removed the credential.
12900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // So, remove this credential accordingly.
12910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        int netId = mSavedPeerConfig.netId;
12920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (netId >= 0) {
12930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (DBG) logd("Remove unknown client from the list");
12940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
12950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        }
12960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1297ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                        // invocation is failed or deferred. Try another way to connect.
1298ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
1299ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                        if (connect(mSavedPeerConfig, NO_REINVOCATION) == CONNECT_FAILURE) {
1300ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                            handleGroupCreationFailure();
1301ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                            transitionTo(mInactiveState);
1302ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                        }
1303ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                    } else {
13040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        handleGroupCreationFailure();
13050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        transitionTo(mInactiveState);
13060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
13070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
130855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
130955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
131055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
131155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
131255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
131355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
131455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1315618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1316618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
131755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupCreatedState extends State {
131855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
131955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
1320ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
1321aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
1322859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
1323651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            updateThisDevice(WifiP2pDevice.CONNECTED);
1324651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
1325859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            //DHCP server has already been started if I am a group owner
1326859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            if (mGroup.isGroupOwner()) {
1327859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS);
1328859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            }
132955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
133055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
133155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
133255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
1333ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
133455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
133555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_CONNECTED_EVENT:
1336bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1337bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    String deviceAddress = device.deviceAddress;
13389322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
1339bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (mSavedProvDiscDevice != null &&
1340bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                deviceAddress.equals(mSavedProvDiscDevice.deviceAddress)) {
1341bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mSavedProvDiscDevice = null;
1342bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1343c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        mGroup.addClient(mPeers.get(deviceAddress));
1344bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED);
13459322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (DBG) logd(getName() + " ap sta connected");
13469322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        sendP2pPeersChangedBroadcast();
13479322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
1348bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        loge("Connect on null device address, ignore");
13499322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    }
1350e0c28d5f1358fc2d4c464f910bd04fed4b283fefIrfan Sheriff                    sendP2pConnectionChangedBroadcast();
135155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
135255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
135361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    device = (WifiP2pDevice) message.obj;
135461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    deviceAddress = device.deviceAddress;
13559322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
1356bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
13579322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (mGroup.removeClient(deviceAddress)) {
13589322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Removed client " + deviceAddress);
1359bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            if (!mAutonomousGroup && mGroup.isClientListEmpty()) {
13604be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
1361fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
13625ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                // We end up sending connection changed broadcast
13635ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                // when this happens at exit()
13645ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                            } else {
13655ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                // Notify when a client disconnects from group
13665ef9c59fffce221fcfd3f2fcea8f45a41341fa42Irfan Sheriff                                sendP2pConnectionChangedBroadcast();
13674be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            }
13689322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        } else {
13699322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Failed to remove client " + deviceAddress);
13709322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            for (WifiP2pDevice c : mGroup.getClientList()) {
13719322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                                if (DBG) logd("client " + c.deviceAddress);
13729322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            }
137355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
13744be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
13750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (DBG) logd(getName() + " ap sta disconnected");
13769322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
137761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        loge("Disconnect on unknown device: " + device);
137855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
137955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1380aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
1381aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
1382ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
1383ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            dhcpInfo != null) {
1384ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("DhcpInfo: " + dhcpInfo);
1385ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
1386aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        sendP2pConnectionChangedBroadcast();
138755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        //Turn on power save on client
138855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
1389ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
139061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        loge("DHCP failed");
1391fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
1392aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
1393aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
139455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
13950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (DBG) logd(getName() + " remove group");
1396fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
1397c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                        transitionTo(mOngoingGroupRemovalState);
1398ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
1399ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
1400d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                        handleGroupRemoved();
1401d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                        transitionTo(mInactiveState);
14024be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
14034be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
1404ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
140555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1406d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                /* The supplicant misses the group removed event at times and just
1407d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                 * sends a network disconnect event */
1408d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
140955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
14100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (DBG) logd(getName() + " group removed");
1411d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                    handleGroupRemoved();
141255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
141355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
141455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1415bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    device = (WifiP2pDevice) message.obj;
1416530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    //Device loss for a connected device indicates it is not in discovery any more
1417530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    if (mGroup.contains(device)) {
141841de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                        if (DBG) logd("Add device to lost list " + device);
141941de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff                        mPeersLostDuringConnection.update(device);
1420530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                        return HANDLED;
142155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
1422530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    // Do the regular device lost handling
1423530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    return NOT_HANDLED;
14247d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
142555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.REMOVE_GROUP);
142655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
142755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
142855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
142955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
1430bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (config.deviceAddress == null ||
1431bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            (mSavedProvDiscDevice != null &&
1432bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    mSavedProvDiscDevice.deviceAddress.equals(
1433bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                            config.deviceAddress))) {
1434bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (config.wps.setup == WpsInfo.PBC) {
1435bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mWifiNative.startWpsPbc(mGroup.getInterface(), null);
1436bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        } else {
1437bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            if (config.wps.pin == null) {
1438bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
1439bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                try {
1440bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    Integer.parseInt(pin);
1441bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    if (!sendShowPinReqToFrontApp(pin)) {
1442bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                        notifyInvitationSent(pin,
1443bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                                config.deviceAddress != null ?
1444bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                                        config.deviceAddress : "any");
1445bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    }
1446bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                } catch (NumberFormatException ignore) {
1447bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    // do nothing if pin is invalid
1448bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                }
1449bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            } else {
1450bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
1451bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                        config.wps.pin);
1452bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            }
1453bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1454bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (config.deviceAddress != null) {
1455bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
1456bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            sendP2pPeersChangedBroadcast();
1457bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1458ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1459ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
1460bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        logd("Inviting device : " + config.deviceAddress);
14610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        mSavedPeerConfig = config;
1462bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
1463bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
1464bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            sendP2pPeersChangedBroadcast();
1465bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1466bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        } else {
1467bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                            replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
1468bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                    WifiP2pManager.ERROR);
1469bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        }
1470ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
147155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // TODO: figure out updating the status to declined when invitation is rejected
147255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
14730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
14740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    P2pStatus status = (P2pStatus)message.obj;
14750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    logd("===> INVITATION RESULT EVENT : " + status);
14760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    if (status == P2pStatus.SUCCESS) {
14770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // invocation was succeeded.
14780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        break;
14790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
14800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // target device has already removed the credential.
14810879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        // So, remove this credential accordingly.
14820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        int netId = mGroup.getNetworkId();
14830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        if (netId >= 0) {
14840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (DBG) logd("Remove unknown client from the list");
14850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            if (!removeClientFromList(netId,
14860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                    mSavedPeerConfig.deviceAddress, false)) {
14870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                // not found the client on the list
14880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                Slog.e(TAG, "Already removed the client, ignore");
14890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                                break;
14900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            }
14910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            // try invitation.
14920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                            sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
14930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                        }
14940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    }
14950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    break;
149655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
149755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1498618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1499618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
1500bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    mSavedProvDiscDevice = provDisc.device;
1501618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
1502618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
1503618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
1504618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
1505618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
1506618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
1507618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
1508618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1509618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
1510618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1511bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    if (!sendConnectNoticeToApp(mSavedProvDiscDevice, mSavedPeerConfig)) {
1512bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        transitionTo(mUserAuthorizingJoinState);
1513bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                    }
151455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
15159322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
15169322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    Slog.e(TAG, "Duplicate group creation event notice, ignore");
15179322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    break;
151855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
151955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
152055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
152155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
152255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
1523aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1524aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void exit() {
1525bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mSavedProvDiscDevice = null;
1526651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            updateThisDevice(WifiP2pDevice.AVAILABLE);
15270a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff            resetWifiP2pInfo();
1528aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
1529ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            sendP2pConnectionChangedBroadcast();
1530aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
153155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
153255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1533618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class UserAuthorizingJoinState extends State {
1534618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1535618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void enter() {
1536618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName());
1537618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            notifyInvitationReceived();
1538618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1539618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1540618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1541618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public boolean processMessage(Message message) {
1542618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1543618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            switch (message.what) {
1544618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
1545618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1546618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1547618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    //Ignore more client requests
1548618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1549618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
1550618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
1551bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mWifiNative.startWpsPbc(mGroup.getInterface(), null);
1552618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1553bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                        mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
1554bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                                mSavedPeerConfig.wps.pin);
1555618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1556618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1557618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1558618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1559618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
1560618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd("User rejected incoming request");
1561618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1562618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1563618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1564618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                default:
1565618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    return NOT_HANDLED;
1566618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
1567618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            return HANDLED;
1568618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1569618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1570618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1571618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void exit() {
1572618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            //TODO: dismiss dialog if not already done
1573618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1574618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
1575618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1576c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    class OngoingGroupRemovalState extends State {
1577c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        @Override
1578c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        public void enter() {
1579c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            if (DBG) logd(getName());
1580c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        }
1581c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff
1582c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        @Override
1583c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        public boolean processMessage(Message message) {
1584c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1585c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            switch (message.what) {
1586c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // Group removal ongoing. Multiple calls
1587c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // end up removing persisted network. Do nothing.
1588c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
1589c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
1590c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    break;
1591c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // Parent state will transition out of this state
1592c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                // when removal is complete
1593c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                default:
1594c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    return NOT_HANDLED;
1595c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            }
1596c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            return HANDLED;
1597c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        }
1598c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    }
1599c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff
160055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pStateChangedBroadcast(boolean enabled) {
160155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
160255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
160355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (enabled) {
160455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
160555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
160655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
160755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
160855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
160955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
16105ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
161155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
161255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1613c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private void sendP2pDiscoveryChangedBroadcast(boolean started) {
1614c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        if (mDiscoveryStarted == started) return;
1615c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        mDiscoveryStarted = started;
1616c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1617c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        if (DBG) logd("discovery change broadcast " + started);
1618c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1619c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
1620c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1621c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, started ?
1622c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED :
1623c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
16245ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1625c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    }
1626c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1627651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void sendThisDeviceChangedBroadcast() {
1628651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
1629651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1630651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
16315ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1632651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
1633651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
163455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pPeersChangedBroadcast() {
163555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
163655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16375ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
163855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
163955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1640aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void sendP2pConnectionChangedBroadcast() {
1641ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (DBG) logd("sending p2p connection changed broadcast");
1642aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
1643aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
1644aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
1645ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
1646aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
16475ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16483809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff        mWifiChannel.sendMessage(WifiP2pService.P2P_CONNECTION_CHANGED,
16493809f500c3411af2ab5ab6c706cdb4373940123eIrfan Sheriff                new NetworkInfo(mNetworkInfo));
1650aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1651aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
16520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private void sendP2pPersistentGroupsChangedBroadcast() {
16530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (DBG) logd("sending p2p persistent groups changed broadcast");
16540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
16550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
16565ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
16580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1659aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void startDhcpServer(String intf) {
1660aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        InterfaceConfiguration ifcg = null;
1661aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1662aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg = mNwService.getInterfaceConfig(intf);
1663ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
1664ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                        SERVER_ADDRESS), 24));
1665ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            ifcg.setInterfaceUp();
1666aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.setInterfaceConfig(intf, ifcg);
1667aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            /* This starts the dnsmasq server */
1668859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            mNwService.startTethering(DHCP_RANGE);
1669aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1670ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error configuring interface " + intf + ", :" + e);
1671aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1672aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1673aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1674ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Started Dhcp server on " + intf);
1675859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff   }
1676aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1677b81bb9b40881659428f30b4539dd8877f9ea85f9Irfan Sheriff    private void stopDhcpServer(String intf) {
1678aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1679aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.stopTethering();
1680aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1681ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error stopping Dhcp server" + e);
1682aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1683aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1684aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1685ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Stopped Dhcp server");
1686aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1687aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
168855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pEnableFailure() {
168955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
169055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
169155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
169255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
169355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
169455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
169555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
169655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
169755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
169855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1699618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void addRowToDialog(ViewGroup group, int stringId, String value) {
170055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1701618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
1702618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                group, false);
1703618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
1704618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ((TextView) row.findViewById(R.id.value)).setText(value);
1705618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        group.addView(row);
170655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
170755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1708618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void notifyInvitationSent(String pin, String peerAddress) {
170955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1710aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
171155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
1712618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                .inflate(R.layout.wifi_p2p_dialog, null);
1713618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1714618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
1715618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
1716618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
171755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
171855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
1719618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
172055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
1721618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setPositiveButton(r.getString(R.string.ok), null)
172255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
172355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
172455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
172555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
172655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1727618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void notifyInvitationReceived() {
172855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1729618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        final WpsInfo wps = mSavedPeerConfig.wps;
173055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
1731618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                .inflate(R.layout.wifi_p2p_dialog, null);
173255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1733618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
1734618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
1735618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mSavedPeerConfig.deviceAddress));
173655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1737618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
173855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
173955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
1740618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
174155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
1742618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
174355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1744618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (wps.setup == WpsInfo.KEYPAD) {
1745618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                                mSavedPeerConfig.wps.pin = pin.getText().toString();
1746618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            }
1747618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
1748618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
1749bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        }
1750bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    })
1751618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
1752bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        @Override
1753bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        public void onClick(DialogInterface dialog, int which) {
1754618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
1755618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            sendMessage(PEER_CONNECTION_USER_REJECT);
175655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
175755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
175810ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff            .setOnCancelListener(new DialogInterface.OnCancelListener() {
175910ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                        @Override
176010ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                        public void onCancel(DialogInterface arg0) {
176110ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
176210ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                            sendMessage(PEER_CONNECTION_USER_REJECT);
176310ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                        }
176410ca870d3b58ec6fd62b85466ec1211fca77d33eIrfan Sheriff                    })
176555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
176655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1767618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //make the enter pin area or the display pin area visible
1768618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        switch (wps.setup) {
1769618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.KEYPAD:
1770618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (DBG) logd("Enter pin section visible");
1771618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
1772618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1773618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.DISPLAY:
1774618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (DBG) logd("Shown pin section visible");
1775618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
1776618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1777618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            default:
1778618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1779618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
178055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
178155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
178255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
178355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
178455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
17860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Synchronize the persistent group list between
17870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * wpa_supplicant and mGroups.
17880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
1789ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff    private void updatePersistentNetworks(boolean reload) {
17900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String listStr = mWifiNative.listNetworks();
1791d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (listStr == null) return;
17920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
17930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean isSaveRequired = false;
17940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String[] lines = listStr.split("\n");
1795d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (lines == null) return;
1796d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
1797ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff        if (reload) mGroups.clear();
1798ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff
17990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        // Skip the first line, which is a header
18000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (int i = 1; i < lines.length; i++) {
18010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String[] result = lines[i].split("\t");
18020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (result == null || result.length < 4) {
18030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // network-id | ssid | bssid | flags
18060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = -1;
18070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String ssid = result[1];
18080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String bssid = result[2];
18090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String flags = result[3];
18100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            try {
18110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                netId = Integer.parseInt(result[0]);
18120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            } catch(NumberFormatException e) {
18130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                e.printStackTrace();
18140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (flags.indexOf("[CURRENT]") != -1) {
18180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
18210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                /*
18220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                 * The unused profile is sometimes remained when the p2p group formation is failed.
18230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                 * So, we clean up the p2p group here.
18240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                 */
18250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (DBG) logd("clean up the unused persistent group. netId=" + netId);
18260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                mWifiNative.removeNetwork(netId);
18270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                isSaveRequired = true;
18280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18310879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (mGroups.contains(netId)) {
18320879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                continue;
18330879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            WifiP2pGroup group = new WifiP2pGroup();
18360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            group.setNetworkId(netId);
18370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            group.setNetworkName(ssid);
18380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String mode = mWifiNative.getNetworkVariable(netId, "mode");
18390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (mode != null && mode.equals("3")) {
18400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                group.setIsGroupOwner(true);
18410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
18430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                group.setOwner(mThisDevice);
18440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            } else {
18450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                WifiP2pDevice device = new WifiP2pDevice();
18460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                device.deviceAddress = bssid;
18470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                group.setOwner(device);
18480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
18490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            mGroups.add(group);
18500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            isSaveRequired = true;
18510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
1853ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff        if (reload || isSaveRequired) {
18540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            mWifiNative.saveConfig();
1855ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff            sendP2pPersistentGroupsChangedBroadcast();
18560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
18580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
18600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Try to connect to the target device.
18610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     *
18620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Use the persistent credential if it has been stored.
18630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     *
18640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param config
18650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param tryInvocation if true, try to invoke. Otherwise, never try to invoke.
18660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return
18670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
18680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private int connect(WifiP2pConfig config, boolean tryInvocation) {
18690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (config == null) {
187141de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff            loge("config is null");
18720879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return CONNECT_FAILURE;
18730879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18740879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean isResp = (mSavedPeerConfig != null &&
18760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                config.deviceAddress.equals(mSavedPeerConfig.deviceAddress));
18770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mSavedPeerConfig = config;
18780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        WifiP2pDevice dev = mPeers.get(config.deviceAddress);
18800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (dev == null) {
188141de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff            loge("target device not found " + config.deviceAddress);
18820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return CONNECT_FAILURE;
18830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
18840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean join = dev.isGroupOwner();
18860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
18870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (DBG) logd("target ssid is " + ssid + " join:" + join);
18880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (join && dev.isGroupLimit()) {
18900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (DBG) logd("target device reaches group limit.");
18910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
18920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // if the target group has reached the limit,
18930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // try group formation.
18940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            join = false;
18950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        } else if (join) {
18960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
18970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (netId >= 0) {
18980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                // Skip WPS and start 4way handshake immediately.
18990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (!mWifiNative.p2pGroupAdd(netId)) {
19000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    return CONNECT_FAILURE;
19010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                return CONNECT_SUCCESS;
19030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!join && dev.isDeviceLimit()) {
19070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            loge("target device reaches the device limit.");
19080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return CONNECT_FAILURE;
19090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!join && tryInvocation && dev.isInvitationCapable()) {
19120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = WifiP2pGroup.PERSISTENT_NET_ID;
19130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (config.netId >= 0) {
19140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
19150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    netId = config.netId;
19160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            } else {
19180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                netId = mGroups.getNetworkId(dev.deviceAddress);
19190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (netId < 0) {
19210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                netId = getNetworkIdFromClientList(dev.deviceAddress);
19220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
19240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (netId >= 0) {
19250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                // Invoke the persistent group.
1926c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                if (mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
1927c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    // Save network id. It'll be used when an invitation result event is received.
1928c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    mSavedPeerConfig.netId = netId;
1929c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    return CONNECT_SUCCESS;
1930c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                } else {
1931c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    loge("p2pReinvoke() failed, update networks");
1932ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff                    updatePersistentNetworks(RELOAD);
1933c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                    // continue with negotiation
19340879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19350879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19360879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19370879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19380879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        //Stop discovery before issuing connect
19390879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mWifiNative.p2pStopFind();
19400879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19410879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!isResp) {
19420879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return NEEDS_PROVISION_REQ;
19430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19454bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        p2pConnectWithPinDisplay(config);
19460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return CONNECT_SUCCESS;
19470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
19480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
19500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Return the network id of the group owner profile which has the p2p client with
19510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * the specified device address in it's client list.
19520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * If more than one persistent group of the same address is present in its client
19530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * lists, return the first one.
19540879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     *
19550879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param deviceAddress p2p device address.
19560879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return the network id. if not found, return -1.
19570879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
19580879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private int getNetworkIdFromClientList(String deviceAddress) {
19590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (deviceAddress == null) return -1;
19600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        Collection<WifiP2pGroup> groups = mGroups.getGroupList();
19620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (WifiP2pGroup group : groups) {
19630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            int netId = group.getNetworkId();
19640879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            String[] p2pClientList = getClientList(netId);
19650879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (p2pClientList == null) continue;
19660879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            for (String client : p2pClientList) {
19670879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (deviceAddress.equalsIgnoreCase(client)) {
19680879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    return netId;
19690879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
19700879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
19710879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
1972ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return -1;
1973ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1974ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
19750879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
19760879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Return p2p client list associated with the specified network id.
19770879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param netId network id.
19780879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return p2p client list. if not found, return null.
19790879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
19800879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private String[] getClientList(int netId) {
19810879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
19820879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (p2pClients == null) {
19830879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return null;
19840879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
19850879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return p2pClients.split(" ");
19860879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
19870879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
19880879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /**
19890879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * Remove the specified p2p client from the specified profile.
19900879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param netId network id of the profile.
19910879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param addr p2p client address to be removed.
19920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @param isRemovable if true, remove the specified profile if its client list becomes empty.
19930879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     * @return whether removing the specified p2p client is successful or not.
19940879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga     */
19950879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
19960879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        StringBuilder modifiedClientList =  new StringBuilder();
19970879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        String[] currentClientList = getClientList(netId);
19980879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        boolean isClientRemoved = false;
19990879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (currentClientList != null) {
20000879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            for (String client : currentClientList) {
20010879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                if (!client.equalsIgnoreCase(addr)) {
20020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    modifiedClientList.append(" ");
20030879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    modifiedClientList.append(client);
20040879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                } else {
20050879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                    isClientRemoved = true;
20060879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                }
20070879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            }
20080879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
20090879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (modifiedClientList.length() == 0 && isRemovable) {
20100879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // the client list is empty. so remove it.
20110879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            if (DBG) logd("Remove unknown network");
20120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            mGroups.remove(netId);
20130879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return true;
20140879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
20150879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
20160879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (!isClientRemoved) {
20170879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            // specified p2p client is not found. already removed.
20180879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            return false;
20190879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
20200879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
20210879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (DBG) logd("Modified client list: " + modifiedClientList);
20220879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        if (modifiedClientList.length() == 0) {
20230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga            modifiedClientList.append("\"\"");
20240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        }
20250879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mWifiNative.setNetworkVariable(netId,
20260879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga                "p2p_client_list", modifiedClientList.toString());
20270879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        mWifiNative.saveConfig();
20280879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return true;
20290879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
20300879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2031ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
2032ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = true;
2033ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
2034ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = NetworkUtils.numericToInetAddress(serverAddress);
2035ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2036ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
20370a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff    private void resetWifiP2pInfo() {
2038ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = false;
2039ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = false;
2040ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = null;
2041ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2042ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2043618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private String getDeviceName(String deviceAddress) {
2044bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        WifiP2pDevice d = mPeers.get(deviceAddress);
2045bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (d != null) {
2046618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return d.deviceName;
2047618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
2048618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //Treat the address as name if there is no match
2049618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        return deviceAddress;
2050618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
2051618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
20524bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff    private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
20534bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        WifiP2pDevice dev = mPeers.get(config.deviceAddress);
20544bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        if (dev == null) {
20554bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff            loge("target device is not found " + config.deviceAddress);
20564bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff            return;
20574bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        }
20584bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff
20594bbb13976e54f6325cb013882891c02adea61ec5Irfan Sheriff        String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
2060bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        try {
2061bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            Integer.parseInt(pin);
2062bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (!sendShowPinReqToFrontApp(pin)) {
2063bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                notifyInvitationSent(pin, config.deviceAddress);
2064bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            }
2065bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        } catch (NumberFormatException ignore) {
2066bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            // do nothing if p2pConnect did not return a pin
2067bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        }
2068bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    }
2069bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
20702bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    private String getPersistedDeviceName() {
2071bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        String deviceName = Settings.Global.getString(mContext.getContentResolver(),
2072bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.WIFI_P2P_DEVICE_NAME);
20732bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        if (deviceName == null) {
20742bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            /* We use the 4 digits of the ANDROID_ID to have a friendly
20752bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff             * default that has low likelihood of collision with a peer */
20762bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            String id = Settings.Secure.getString(mContext.getContentResolver(),
20772bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff                    Settings.Secure.ANDROID_ID);
20782bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            return "Android_" + id.substring(0,4);
20792bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        }
20802bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        return deviceName;
20812bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    }
20822bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
20832bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    private boolean setAndPersistDeviceName(String devName) {
20842bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        if (devName == null) return false;
20852bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
20862bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        if (!mWifiNative.setDeviceName(devName)) {
20872bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            loge("Failed to set device name " + devName);
20882bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff            return false;
20892bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        }
20902bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
20912bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        mThisDevice.deviceName = devName;
20922bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
20932bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
2094bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        Settings.Global.putString(mContext.getContentResolver(),
2095bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.WIFI_P2P_DEVICE_NAME, devName);
20962bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        sendThisDeviceChangedBroadcast();
20972bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        return true;
20982bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff    }
20992bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff
2100ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
2101ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        boolean success;
2102ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
2103ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        if (!wfdInfo.isWfdEnabled()) {
2104ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            success = mWifiNative.setWfdEnable(false);
2105ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        } else {
2106ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            success =
2107ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                mWifiNative.setWfdEnable(true)
2108ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                && mWifiNative.setWfdDeviceInfo(wfdInfo.getDeviceInfoHex());
2109ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        }
2110ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
2111ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        if (!success) {
2112ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            loge("Failed to set wfd properties");
2113ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            return false;
2114ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        }
2115ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
2116ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        mThisDevice.wfdInfo = wfdInfo;
2117ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        sendThisDeviceChangedBroadcast();
2118ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        return true;
2119ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    }
2120ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
21219322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private void initializeP2pSettings() {
2122fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setPersistentReconnect(true);
21232bdefcab74d4ee21ad4bc1e90b30aeb7eac589e0Irfan Sheriff        mThisDevice.deviceName = getPersistedDeviceName();
2124fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setDeviceName(mThisDevice.deviceName);
2125de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // DIRECT-XY-DEVICENAME (XY is randomly generated)
2126fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
2127fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
2128de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // Supplicant defaults to using virtual display with display
2129de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // which refers to a remote display. Use physical_display
2130de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        mWifiNative.setConfigMethods("virtual_push_button physical_display keypad");
2131de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        // STA has higher priority over P2P
213255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mWifiNative.setConcurrencyPriority("sta");
21334be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
2134fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
2135651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        updateThisDevice(WifiP2pDevice.AVAILABLE);
2136651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        if (DBG) Slog.d(TAG, "DeviceAddress: " + mThisDevice.deviceAddress);
213721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
213821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mClientInfoList.clear();
213921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pFlush();
214021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServiceFlush();
214121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceTransactionId = 0;
214221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = null;
21430879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2144ca1269fcb8265c36660b3b47e5c06180e94e6485Irfan Sheriff        updatePersistentNetworks(RELOAD);
2145651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
2146651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
2147651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void updateThisDevice(int status) {
2148651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.status = status;
2149651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        sendThisDeviceChangedBroadcast();
21509322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
21519322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
215255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    private void handleGroupCreationFailure() {
21530a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff        resetWifiP2pInfo();
21540a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.FAILED, null, null);
21550a66763744db9c9215567ed70051add7f55d53c7Irfan Sheriff        sendP2pConnectionChangedBroadcast();
215655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mSavedPeerConfig = null;
215755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        /* After cancelling group formation, new connections on existing peers can fail
215855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff         * at supplicant. Flush and restart discovery */
215955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mWifiNative.p2pFlush();
216041de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff        if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast();
216141de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff        mPeersLostDuringConnection.clear();
2162de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff        mServiceDiscReqId = null;
216355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        sendMessage(WifiP2pManager.DISCOVER_PEERS);
216455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
216555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
2166d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff    private void handleGroupRemoved() {
2167d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        Collection <WifiP2pDevice> devices = mGroup.getClientList();
2168d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        boolean changed = false;
2169d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        for (WifiP2pDevice d : mPeers.getDeviceList()) {
2170d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            if (devices.contains(d) || mGroup.getOwner().equals(d)) {
2171d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                d.status = WifiP2pDevice.AVAILABLE;
2172d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff                changed = true;
2173d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            }
2174d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        }
2175d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
2176d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (mGroup.isGroupOwner()) {
2177d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            stopDhcpServer(mGroup.getInterface());
2178d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        } else {
2179d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            if (DBG) logd("stop DHCP client");
2180d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
2181d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            mDhcpStateMachine.doQuit();
2182d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff            mDhcpStateMachine = null;
2183d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        }
2184d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
21850befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff        try {
21860befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff            mNwService.clearInterfaceAddresses(mGroup.getInterface());
21870befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff        } catch (Exception e) {
21880befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff            loge("Failed to clear addresses " + e);
21890befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff        }
21900befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff        NetworkUtils.resetConnections(mGroup.getInterface(), NetworkUtils.RESET_ALL_ADDRESSES);
21910befeb29bcdf05b913a332edb4f222e11b4817acIrfan Sheriff
2192d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        mGroup = null;
2193d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        mWifiNative.p2pFlush();
219441de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff        if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast();
219541de2404658c7c6faf6c78e777ba50af11784f5cIrfan Sheriff        mPeersLostDuringConnection.clear();
2196d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        mServiceDiscReqId = null;
2197d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff        if (changed) sendP2pPeersChangedBroadcast();
2198d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff    }
2199d36adc31ce0335635b536174299e15b9f099c9adIrfan Sheriff
2200ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //State machine initiated requests can have replyTo set to null indicating
2201de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff    //there are no recipients, we ignore those reply actions
2202ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what) {
2203ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
2204651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
2205651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
2206651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
2207ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2208ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2209f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    private void replyToMessage(Message msg, int what, int arg1) {
2210f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff        if (msg.replyTo == null) return;
2211651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
2212651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
2213651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.arg1 = arg1;
2214651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
2215f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    }
2216f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff
2217ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what, Object obj) {
2218ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
2219651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
2220651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
2221651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.obj = obj;
2222651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
2223651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
2224651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
2225651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /* arg2 on the source message has a hash code that needs to be retained in replies
2226651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff     * see WifiP2pManager for details */
2227651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private Message obtainMessage(Message srcMsg) {
2228651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message msg = Message.obtain();
2229651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        msg.arg2 = srcMsg.arg2;
2230651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        return msg;
2231ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2232ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2233ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void logd(String s) {
2234ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.d(TAG, s);
2235ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2236ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
2237ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void loge(String s) {
2238ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.e(TAG, s);
2239ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
2240ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
224121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
224221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Update service discovery request to wpa_supplicant.
224321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
224421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean updateSupplicantServiceRequest() {
224521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearSupplicantServiceRequest();
224621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
224721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
224821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c: mClientInfoList.values()) {
224921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int key;
225021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            WifiP2pServiceRequest req;
225121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            for (int i=0; i < c.mReqList.size(); i++) {
22523b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                req = c.mReqList.valueAt(i);
225321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (req != null) {
225421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(req.getSupplicantQuery());
225521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
225621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
225721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
225821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
225921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (sb.length() == 0) {
226021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
226121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
226221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
226321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
226421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
226521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
226621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
226721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
226821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
226921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
227021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
227121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Clear service discovery request in wpa_supplicant
227221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
227321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearSupplicantServiceRequest() {
227421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) return;
227521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
227621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServDiscCancelReq(mServiceDiscReqId);
227721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = null;
227821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
227921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2280de1e9fa9fbc4b7f4b08415d805a6e5212e655d95Irfan Sheriff    /* TODO: We could track individual service adds separately and avoid
228121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * having to do update all service requests on every new request
228221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
228321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean addServiceRequest(Messenger m, WifiP2pServiceRequest req) {
228421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearClientDeadChannels();
228521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, true);
228621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
228721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
228821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
228921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
22903b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        ++mServiceTransactionId;
22913b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //The Wi-Fi p2p spec says transaction id should be non-zero
22923b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        if (mServiceTransactionId == 0) ++mServiceTransactionId;
22933b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        req.setTransactionId(mServiceTransactionId);
229421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mReqList.put(mServiceTransactionId, req);
229521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
229621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
229721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return true;
229821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
229921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
230021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return updateSupplicantServiceRequest();
230121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
230221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
230321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
230421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
230521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
230621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
230721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
230821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
23093b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //Application does not have transaction id information
23103b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //go through stored requests to remove
23113b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        boolean removed = false;
23120879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        for (int i=0; i<clientInfo.mReqList.size(); i++) {
23133b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            if (req.equals(clientInfo.mReqList.valueAt(i))) {
23143b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                removed = true;
23153b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                clientInfo.mReqList.removeAt(i);
23163b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                break;
23173b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            }
23183b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        }
23193b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
23203b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        if (!removed) return;
232121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
232221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
232321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
232421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
232521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
232621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
232721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
232821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
232921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
233021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
233121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        updateSupplicantServiceRequest();
233221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
233321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
233421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearServiceRequests(Messenger m) {
233521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
233621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
233721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
233821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
233921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
234021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
234121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0) {
234221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
234321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
234421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
234521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mReqList.clear();
234621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
234721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mServList.size() == 0) {
234821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove channel information from framework");
234921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
235021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
235121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
235221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
235321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
235421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
235521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
235621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        updateSupplicantServiceRequest();
235721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
235821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
235921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean addLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
236021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearClientDeadChannels();
236121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, true);
236221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
236321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
236421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
236521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
236621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!clientInfo.mServList.add(servInfo)) {
236721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
236821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
236921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
237021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!mWifiNative.p2pServiceAdd(servInfo)) {
237121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            clientInfo.mServList.remove(servInfo);
237221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
237321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
237421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
237521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
237621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
237721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
237821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void removeLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
237921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
238021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
238121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
238221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
238321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
238421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServiceDel(servInfo);
238521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
238621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mServList.remove(servInfo);
238721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
238821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
238921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
239021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
239121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
239221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
239321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearLocalServices(Messenger m) {
239421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
239521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
239621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
239721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
239821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
239921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (WifiP2pServiceInfo servInfo: clientInfo.mServList) {
240021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mWifiNative.p2pServiceDel(servInfo);
240121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
240221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
240321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mServList.clear();
240421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0) {
240521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
240621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
240721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
240821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
240921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
241021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearClientInfo(Messenger m) {
241121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearLocalServices(m);
241221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearServiceRequests(m);
241321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
241421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
241521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
241621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Send the service response to the WifiP2pManager.Channel.
241721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
241821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param resp
241921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
242021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void sendServiceResponse(WifiP2pServiceResponse resp) {
242121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c : mClientInfoList.values()) {
242221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            WifiP2pServiceRequest req = c.mReqList.get(resp.getTransactionId());
242321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (req != null) {
242421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                Message msg = Message.obtain();
242521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.what = WifiP2pManager.RESPONSE_SERVICE;
242621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.arg1 = 0;
242721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.arg2 = 0;
242821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.obj = resp;
242921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                try {
243021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    c.mMessenger.send(msg);
243121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } catch (RemoteException e) {
243221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd("detect dead channel");
243321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearClientInfo(c.mMessenger);
24343b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                    return;
243521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
243621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
243721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
243821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
243921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
244021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
244121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * We dont get notifications of clients that have gone away.
244221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * We detect this actively when services are added and throw
244321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * them away.
244421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
244521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * TODO: This can be done better with full async channels.
244621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
244721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearClientDeadChannels() {
24483b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
24493b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
245021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c : mClientInfoList.values()) {
245121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            Message msg = Message.obtain();
245221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.what = WifiP2pManager.PING;
245321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.arg1 = 0;
245421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.arg2 = 0;
245521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.obj = null;
245621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            try {
245721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                c.mMessenger.send(msg);
245821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } catch (RemoteException e) {
245921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (DBG) logd("detect dead channel");
24603b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                deadClients.add(c.mMessenger);
246121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
246221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
24633b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
24643b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        for (Messenger m : deadClients) {
24653b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            clearClientInfo(m);
24663b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        }
246721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
246821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
246921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
247021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return the specified ClientInfo.
247121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param m Messenger
247221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param createIfNotExist if true and the specified channel info does not exist,
247321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * create new client info.
247421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return the specified ClientInfo.
247521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
247621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private ClientInfo getClientInfo(Messenger m, boolean createIfNotExist) {
247721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = mClientInfoList.get(m);
247821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
247921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null && createIfNotExist) {
248021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("add a new client");
248121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            clientInfo = new ClientInfo(m);
248221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.put(m, clientInfo);
248321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
248421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
248521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return clientInfo;
248621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
248721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
2488bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2489bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send detached message to dialog listener in the foreground application.
2490bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param reason
2491bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2492bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private void sendDetachedMsg(int reason) {
2493bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (mForegroundAppMessenger == null) return;
2494bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2495bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Message msg = Message.obtain();
2496bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.what = WifiP2pManager.DIALOG_LISTENER_DETACHED;
2497bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.arg1 = reason;
2498bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        try {
2499bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger.send(msg);
2500bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        } catch (RemoteException e) {
2501bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2502bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppMessenger = null;
2503bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppPkgName = null;
2504bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2505bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2506bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2507bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send a request to show wps pin to dialog listener in the foreground application.
2508bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param pin WPS pin
2509bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2510bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2511bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean sendShowPinReqToFrontApp(String pin) {
2512bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (!isForegroundApp(mForegroundAppPkgName)) {
2513bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            sendDetachedMsg(WifiP2pManager.NOT_IN_FOREGROUND);
2514bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2515bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2516bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Message msg = Message.obtain();
2517bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.what = WifiP2pManager.SHOW_PIN_REQUESTED;
2518bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Bundle bundle = new Bundle();
2519bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        bundle.putString(WifiP2pManager.WPS_PIN_BUNDLE_KEY, pin);
2520bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.setData(bundle);
2521bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return sendDialogMsgToFrontApp(msg);
2522bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2523bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2524bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2525bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send a request to establish the connection to dialog listener in the foreground
2526bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * application.
2527bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param dev source device
2528bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param config
2529bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2530bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2531bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean sendConnectNoticeToApp(WifiP2pDevice dev, WifiP2pConfig config) {
2532bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (dev == null) {
2533bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            dev = new WifiP2pDevice(config.deviceAddress);
2534bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2535bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2536bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (!isForegroundApp(mForegroundAppPkgName)) {
2537bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (DBG) logd("application is NOT foreground");
2538bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            sendDetachedMsg(WifiP2pManager.NOT_IN_FOREGROUND);
2539bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2540bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2541bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2542bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Message msg = Message.obtain();
2543bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.what = WifiP2pManager.CONNECTION_REQUESTED;
2544bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        Bundle bundle = new Bundle();
2545bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        bundle.putParcelable(WifiP2pManager.P2P_DEV_BUNDLE_KEY, dev);
2546bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        bundle.putParcelable(WifiP2pManager.P2P_CONFIG_BUNDLE_KEY, config);
2547bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        msg.setData(bundle);
2548bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return sendDialogMsgToFrontApp(msg);
2549bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2550bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2551bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2552bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Send dialog event message to front application's dialog listener.
2553bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param msg
2554bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return true if success.
2555bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2556bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean sendDialogMsgToFrontApp(Message msg) {
2557bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        try {
2558bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger.send(msg);
2559bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        } catch (RemoteException e) {
2560bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger = null;
2561bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppPkgName = null;
2562bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2563bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2564bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return true;
2565bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2566bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2567bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2568bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Set dialog listener application.
2569bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param m
2570bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param appPkgName if null, reset the listener.
2571bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param isReset if true, try to reset.
2572bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2573bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2574bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean setDialogListenerApp(Messenger m,
2575bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            String appPkgName, boolean isReset) {
2576bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2577bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (mForegroundAppPkgName != null && !mForegroundAppPkgName.equals(appPkgName)) {
2578bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (isForegroundApp(mForegroundAppPkgName)) {
2579bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                // The current dialog listener is foreground app's.
2580bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                if (DBG) logd("application is NOT foreground");
2581bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga                return false;
2582bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            }
2583bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            // detach an old listener.
2584bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            sendDetachedMsg(WifiP2pManager.NOT_IN_FOREGROUND);
2585bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2586bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2587bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (isReset) {
2588bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            if (DBG) logd("reset dialog listener");
2589bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppMessenger = null;
2590bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            mForegroundAppPkgName = null;
2591bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return true;
2592bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2593bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2594bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (!isForegroundApp(appPkgName)) {
2595bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2596bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2597bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2598bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppMessenger = m;
2599bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        mForegroundAppPkgName = appPkgName;
2600bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (DBG) logd("set dialog listener. app=" + appPkgName);
2601bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return true;
2602bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2603bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2604bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    /**
2605bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * Return true if the specified package name is foreground app's.
2606bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     *
2607bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @param pkgName application package name.
2608bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     * @return
2609bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga     */
2610bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    private boolean isForegroundApp(String pkgName) {
2611bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (pkgName == null) return false;
2612bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2613bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        List<RunningTaskInfo> tasks = mActivityMgr.getRunningTasks(1);
2614bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        if (tasks.size() == 0) {
2615bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga            return false;
2616bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        }
2617bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
2618bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga        return pkgName.equals(tasks.get(0).baseActivity.getPackageName());
2619bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga    }
2620bfb27bbefb013220af699881d486cc04be5ec1f5Yoshihiko Ikenaga
262121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
262221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
262321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
262421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Information about a particular client and we track the service discovery requests
262521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * and the local services registered by the client.
262621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
262721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private class ClientInfo {
262821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
262921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
263021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A reference to WifiP2pManager.Channel handler.
263121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * The response of this request is notified to WifiP2pManager.Channel handler
263221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
263321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private Messenger mMessenger;
263421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
263521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
263621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A service discovery request list.
263721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
263821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private SparseArray<WifiP2pServiceRequest> mReqList;
263921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
264021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
264121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A local service information list.
264221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
264321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private List<WifiP2pServiceInfo> mServList;
264421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
264521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private ClientInfo(Messenger m) {
264621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mMessenger = m;
264721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mReqList = new SparseArray();
264821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mServList = new ArrayList<WifiP2pServiceInfo>();
264921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
265055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
265155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync}
2652