WifiP2pService.java revision 3b8be87f89e2f98345980954994bdde82b7ee9ad
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
1955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.app.AlertDialog;
20daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriffimport android.app.Notification;
21daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriffimport android.app.NotificationManager;
22daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriffimport android.app.PendingIntent;
2355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.BroadcastReceiver;
2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.Context;
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.DialogInterface;
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.DialogInterface.OnClickListener;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.Intent;
2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.IntentFilter;
2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.pm.PackageManager;
3055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.res.Resources;
31aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.IConnectivityManager;
32aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.ConnectivityManager;
33aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.DhcpInfoInternal;
34aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.DhcpStateMachine;
35aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.InterfaceConfiguration;
36aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.LinkAddress;
37aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.LinkProperties;
38aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.NetworkInfo;
39aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.NetworkUtils;
4055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiManager;
4155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiMonitor;
4255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiNative;
4355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiStateMachine;
44651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriffimport android.net.wifi.WpsInfo;
4521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
4621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
4721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
4855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Binder;
4955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.IBinder;
50cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.INetworkManagementService;
5155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Handler;
5255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.HandlerThread;
5355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Message;
54f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport android.os.Messenger;
557d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriffimport android.os.RemoteException;
56cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.ServiceManager;
57cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.SystemProperties;
589322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriffimport android.provider.Settings;
59618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.text.TextUtils;
6055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Slog;
6121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.util.SparseArray;
6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.LayoutInflater;
6355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.View;
64618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.view.ViewGroup;
6555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.WindowManager;
6655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.widget.EditText;
67618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.widget.TextView;
6855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
69f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport com.android.internal.R;
70616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriffimport com.android.internal.telephony.TelephonyIntents;
7155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.AsyncChannel;
7255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.Protocol;
7355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.State;
7455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.StateMachine;
7555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
76aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.FileDescriptor;
77aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.PrintWriter;
7821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.ArrayList;
79aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.util.Collection;
8021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.HashMap;
8121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.List;
82aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
8355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/**
8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * WifiP2pService inclues a state machine to perform Wi-Fi p2p operations. Applications
8555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * communicate with this service to issue device discovery and connectivity requests
8655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * through the WifiP2pManager interface. The state machine communicates with the wifi
8755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * driver through wpa_supplicant and handles the event responses through WifiMonitor.
8855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
8955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Note that the term Wifi when used without a p2p suffix refers to the client mode
9055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * of Wifi operation
9155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * @hide
9255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
9355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpublic class WifiP2pService extends IWifiP2pManager.Stub {
9455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TAG = "WifiP2pService";
957d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final boolean DBG = false;
96aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private static final String NETWORKTYPE = "WIFI_P2P";
9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
9855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private Context mContext;
99cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    private String mInterface;
100daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    private Notification mNotification;
101cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
102cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    INetworkManagementService mNwService;
103aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private DhcpStateMachine mDhcpStateMachine;
10455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
10555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private P2pStateMachine mP2pStateMachine;
106ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private AsyncChannel mReplyChannel = new AsyncChannel();
10755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private AsyncChannel mWifiChannel;
10855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
109618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final Boolean JOIN_GROUP = true;
110618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final Boolean FORM_GROUP = false;
111618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
112ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Two minutes comes from the wpa_supplicant setting */
113618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
114618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static int mGroupCreatingTimeoutIndex = 0;
115aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1167d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    /* Set a two minute discover timeout to avoid STA scans from being blocked */
1177d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int DISCOVER_TIMEOUT_S = 120;
1187d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff
11955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    /* Idle time after a peer is gone when the group is torn down */
12055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    private static final int GROUP_IDLE_TIME_S = 2;
12155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
122ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /**
123ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     * Delay between restarts upon failure to setup connection with supplicant
124ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     */
125ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int P2P_RESTART_INTERVAL_MSECS = 5000;
126ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
127ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /**
128ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     * Number of times we attempt to restart p2p
129ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     */
130ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int P2P_RESTART_TRIES = 5;
131ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
132ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private int mP2pRestartCount = 0;
133ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
13455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
13555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
136618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* Delayed message to timeout group creation */
1377d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 1;
13855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
139618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* User accepted a peer request */
1407d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 2;
141618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* User rejected a peer request */
1427d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 3;
143295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff
14455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final boolean mP2pSupported;
145651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
146651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private WifiP2pDevice mThisDevice = new WifiP2pDevice();
1474be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
1484be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    /* When a group has been explicitly created by an app, we persist the group
1494be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * even after all clients have been disconnected until an explicit remove
1504be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * is invoked */
1514be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    private boolean mPersistGroup;
15255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
153c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    /* Track whether we are in p2p discovery. This is used to avoid sending duplicate
154c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff     * broadcasts
155c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff     */
156c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private boolean mDiscoveryStarted;
157c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
158aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private NetworkInfo mNetworkInfo;
159aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
16021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* The transaction Id of service discovery request */
16121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private byte mServiceTransactionId = 0;
16221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
16321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* Service discovery request ID of wpa_supplicant.
16421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * null means it's not set yet. */
16521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private String mServiceDiscReqId;
16621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
16721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* clients(application) information list. */
16821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
16921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
170859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    /* Is chosen as a unique range to avoid conflict with
171859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff       the range defined in Tethering.java */
172859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
173859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String SERVER_ADDRESS = "192.168.49.1";
174859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pService(Context context) {
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext = context;
17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1787d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff        //STOPSHIP: get this from native side
179fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mInterface = "p2p0";
180aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
181aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
182a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
183a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff                PackageManager.FEATURE_WIFI_DIRECT);
184a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff
185651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.primaryDeviceType = mContext.getResources().getString(
1869322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                com.android.internal.R.string.config_wifi_p2p_device_type);
187651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.deviceName = getDefaultDeviceName();
18855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
19055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine.start();
191aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
19255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
193cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    public void connectivityServiceReady() {
194cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
195cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
196cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    }
197cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceAccessPermission() {
19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
20155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
20255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceChangePermission() {
20455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2089322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    /* We use the 4 digits of the ANDROID_ID to have a friendly
2099322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff     * default that has low likelihood of collision with a peer */
2109322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private String getDefaultDeviceName() {
2119322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        String id = Settings.Secure.getString(mContext.getContentResolver(),
2129322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    Settings.Secure.ANDROID_ID);
2139322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        return "Android_" + id.substring(0,4);
2149322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
2159322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Get a reference to handler. This is used by a client to establish
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * an AsyncChannel communication with WifiP2pService
21955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
22055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public Messenger getMessenger() {
22155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceAccessPermission();
22255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceChangePermission();
22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return new Messenger(mP2pStateMachine.getHandler());
22455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
22555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
22655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    @Override
22755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
22955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                != PackageManager.PERMISSION_GRANTED) {
23055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
23155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + Binder.getCallingPid()
23255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + ", uid=" + Binder.getCallingUid());
23355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return;
23455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
23555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
23655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
23955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Handles interaction with WifiStateMachine
24055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
24155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class P2pStateMachine extends StateMachine {
24255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
24355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private DefaultState mDefaultState = new DefaultState();
24455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
24555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
24655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
24755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
24855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
24955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Inactive is when p2p is enabled with no connectivity
25055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private InactiveState mInactiveState = new InactiveState();
251618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
252618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private UserAuthorizingInvitationState mUserAuthorizingInvitationState
253618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                = new UserAuthorizingInvitationState();
254618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
25555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
256618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
25755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
258618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
25955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
260fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private WifiNative mWifiNative = new WifiNative(mInterface);
261fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
26255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
26355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
264ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
26555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mGroup;
26655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
267618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        // Saved WifiP2pConfig for a peer connection
268618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        private WifiP2pConfig mSavedPeerConfig;
26955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pGroup from invitation request
27155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mSavedP2pGroup;
27255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        P2pStateMachine(String name, boolean p2pSupported) {
27455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            super(name);
27555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            addState(mDefaultState);
27755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pNotSupportedState, mDefaultState);
27855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisablingState, mDefaultState);
27955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisabledState, mDefaultState);
28055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnablingState, mDefaultState);
28155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnabledState, mDefaultState);
28255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mInactiveState, mP2pEnabledState);
283618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    addState(mGroupCreatingState, mP2pEnabledState);
284618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mUserAuthorizingInvitationState, mGroupCreatingState);
285618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mProvisionDiscoveryState, mGroupCreatingState);
286618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mGroupNegotiationState, mGroupCreatingState);
28755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupCreatedState, mP2pEnabledState);
288618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
28955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
29055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (p2pSupported) {
29155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pDisabledState);
29255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else {
29355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pNotSupportedState);
29455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
29555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
29655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
29755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class DefaultState extends State {
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
29955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
300ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
30255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
30355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
304ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Full connection with WifiStateMachine established");
30555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = (AsyncChannel) message.obj;
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
307ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Full connection failure, error = " + message.arg1);
30855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = null;
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
31155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
314ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Send failed, client connection lost");
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
316ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Client connection lost with reason: " + message.arg1);
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
31855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel = null;
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
32255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    AsyncChannel ac = new AsyncChannel();
32355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    ac.connect(mContext, getHandler(), message.replyTo);
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
3264be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
3274be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
3297d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
3307d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
3317d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                            WifiP2pManager.BUSY);
3327d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    break;
33321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
33421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
33521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
33621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
33755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
3384be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
3394be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
34055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
341651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
342651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
343651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            WifiP2pManager.BUSY);
344651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    break;
34555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
3464be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
3474be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
3504be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
3514be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
35255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
35321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_LOCAL_SERVICE:
35421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
35521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
35621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
35721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
35821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
35921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
36021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
36121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
36221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
36321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
36421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
36521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
36621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
36721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
36821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
36921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
37021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
37121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
37221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
37321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
37421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
37521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
37621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
37721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.BUSY);
37821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
37955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REQUEST_PEERS:
380ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
381ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
382ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REQUEST_CONNECTION_INFO:
383ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO, mWifiP2pInfo);
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
3854be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                case WifiP2pManager.REQUEST_GROUP_INFO:
3864be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup);
3874be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    break;
388295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                    // Ignore
389618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
3907d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SCAN_RESULTS_EVENT:
3917d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUP_CONNECTION_EVENT:
3927d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
3937d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.NETWORK_CONNECTION_EVENT:
3947d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
3957d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
39655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
397618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
398618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
399618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case GROUP_CREATING_TIMED_OUT:
40055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
40155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                /* unexpected group created, remove */
40255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
40355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
40455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    loge("Unexpected group creation, remove " + mGroup);
40555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
40655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    break;
40755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
40855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    loge("Unexpected group failure, flush peers");
40955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pFlush();
41055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    break;
41155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
412ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Unhandled message " + message);
41355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
41455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
41555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
41655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
41755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
41855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
41955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pNotSupportedState extends State {
42055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
42155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
42255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
4237d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case WifiP2pManager.DISCOVER_PEERS:
4247d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
42555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
4277d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
4287d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
429ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
430ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
43121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
43221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
43321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
43421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
435ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CONNECT:
436ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
437ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
438ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
439651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
440651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
441651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
442651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    break;
4437d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff               case WifiP2pManager.CREATE_GROUP:
444ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
445ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
446ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
447ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
448ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
449ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
450ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
45121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_LOCAL_SERVICE:
45221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
45321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
45421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
45521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
45621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
45721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
45821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
45921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
46021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
46121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
46221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
46321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
46421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
46521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
46621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
46721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
46821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
46921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
47021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
47121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
47221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
47321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message,
47421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
47521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
47621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
477ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff               default:
47855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
47955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
48055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
48155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
48255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
48355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
48455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisablingState extends State {
48555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
48655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
487ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
48855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
48955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
4907d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (DBG) logd("p2p socket connection lost");
49155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisabledState);
49255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
4937d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
4947d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
495ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
496ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
49755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
49855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
49955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
50055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
50155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
50255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
50355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
50455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisabledState extends State {
50555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       @Override
50655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
507ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
50855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
50955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
51055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
51155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
512ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
51355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
5147d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
515cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    try {
5167d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        mNwService.setInterfaceUp(mInterface);
5177d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } catch (RemoteException re) {
5187d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        loge("Unable to change interface settings: " + re);
5197d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } catch (IllegalStateException ie) {
5207d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        loge("Unable to change interface settings: " + ie);
52155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
5227d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    mWifiMonitor.startMonitoring();
5237d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    transitionTo(mP2pEnablingState);
52455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
5257d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
5267d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    //Nothing to do
527ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
52855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
52955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
53055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
53155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
53255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
53355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
53455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
53555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnablingState extends State {
53655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
53755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
538ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
53955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
54055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
54155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
54255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
543ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
54455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
54555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
5467d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (DBG) logd("P2p socket connection successful");
54755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
54855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
549ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
5507d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    loge("P2p socket connection failed");
551aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    transitionTo(mP2pDisabledState);
552ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
5537d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
5547d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
555ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
556ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
55755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
55855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
55955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
56055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
56155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
56255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
56355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
56455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnabledState extends State {
56555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
56655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
567ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
56855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(true);
569aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(true);
57055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            sendP2pConnectionChangedBroadcast();
5719322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff            initializeP2pSettings();
57255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
57355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
57455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
57555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
576ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
5787d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_ENABLE_P2P:
5797d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    //Nothing to do
580ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
5817d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
582ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
5837d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    mWifiNative.closeSupplicantConnection();
58455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisablingState);
58555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
58655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
58721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    // do not send service discovery request while normal find operation.
58821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearSupplicantServiceRequest();
5897d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
590ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
591c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                        sendP2pDiscoveryChangedBroadcast(true);
592ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
5934be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
5944be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
595ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
59655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
597c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
598c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                    sendP2pDiscoveryChangedBroadcast(false);
599c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                    break;
6007d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiP2pManager.STOP_DISCOVERY:
6017d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    if (mWifiNative.p2pStopFind()) {
6027d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
6037d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    } else {
6047d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
6057d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                                WifiP2pManager.ERROR);
6067d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    }
6077d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                    break;
60821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.DISCOVER_SERVICES:
60921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " discover services");
61021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (!updateSupplicantServiceRequest()) {
61121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
61221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                                WifiP2pManager.NO_SERVICE_REQUESTS);
61321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        break;
61421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
61521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
61621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED);
61721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    } else {
61821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
61921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                                WifiP2pManager.ERROR);
62021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
62121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
62255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
62355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
624651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                    if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;
6254be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPeers.update(device);
62655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
62755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
62855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
62955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    device = (WifiP2pDevice) message.obj;
63055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
63155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
63221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff               case WifiP2pManager.ADD_LOCAL_SERVICE:
63321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " add service");
63421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)message.obj;
63521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (addLocalService(message.replyTo, servInfo)) {
63621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
63721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    } else {
63821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED);
63921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
64021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
64121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
64221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " remove service");
64321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    servInfo = (WifiP2pServiceInfo)message.obj;
64421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    removeLocalService(message.replyTo, servInfo);
64521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED);
64621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
64721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
64821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " clear service");
64921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearLocalServices(message.replyTo);
65021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
65121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.ADD_SERVICE_REQUEST:
65221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " add service request");
65321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (!addServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj)) {
65421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED);
65521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        break;
65621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
65721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED);
65821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
65921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
66021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " remove service request");
66121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    removeServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj);
66221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED);
66321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
66421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
66521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " clear service request");
66621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearServiceRequests(message.replyTo);
66721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED);
66821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
66921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff               case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
67021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd(getName() + " receive service response");
67121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    List<WifiP2pServiceResponse> sdRespList =
67221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        (List<WifiP2pServiceResponse>) message.obj;
67321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    for (WifiP2pServiceResponse resp : sdRespList) {
67421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        WifiP2pDevice dev =
67521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                            mPeers.get(resp.getSrcDevice().deviceAddress);
67621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        resp.setSrcDevice(dev);
67721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                        sendServiceResponse(resp);
67821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    }
67921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    break;
68021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                default:
68155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
68255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
68355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
68455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
68555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
68655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
68755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void exit() {
68855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(false);
689aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(false);
69055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
69155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
69255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
69355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class InactiveState extends State {
6944be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        @Override
6954be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        public void enter() {
696ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
6974be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            //Start listening every time we get inactive
6987d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            //TODO: Fix listen after driver behavior is fixed
6997d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff            //mWifiNative.p2pListen();
70055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
70155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
70255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
70355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
704ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
70555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
706618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.CONNECT:
707618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd(getName() + " sending connect");
708618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = (WifiP2pConfig) message.obj;
709618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mPersistGroup = false;
710618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress);
711618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (netId >= 0) {
712618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        //TODO: if failure, remove config and do a regular p2pConnect()
713fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress);
714618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
7157d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        //Stop discovery before issuing connect
7167d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                        mWifiNative.p2pStopFind();
717618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        //If peer is a GO, we do not need to send provisional discovery,
718618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        //the supplicant takes care of it.
71961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        if (mWifiNative.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
72055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                            if (DBG) logd("Sending join to GO");
721bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
722618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            transitionTo(mGroupNegotiationState);
723618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        } else {
72455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                            if (DBG) logd("Sending prov disc");
725618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            transitionTo(mProvisionDiscoveryState);
726618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        }
727618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
728618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
729618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    sendP2pPeersChangedBroadcast();
730618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
731618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
73255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
733618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = (WifiP2pConfig) message.obj;
734618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mUserAuthorizingInvitationState);
735618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
736618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
737618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
738bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    WifiP2pDevice owner = group.getOwner();
739bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
740bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    if (owner == null) {
741bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        if (DBG) loge("Ignored invitation from null owner");
742bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        break;
743bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    }
744bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
745bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
746bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    mSavedPeerConfig.deviceAddress = group.getOwner().deviceAddress;
747bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
748bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    //Check if we have the owner in peer list and use appropriate
749bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    //wps method. Default is to use PBC.
750bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    if ((owner = getDeviceFromPeerList(owner.deviceAddress)) != null) {
751bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        if (owner.wpsPbcSupported()) {
752bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.PBC;
753bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        } else if (owner.wpsKeypadSupported()) {
754bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
755bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        } else if (owner.wpsDisplaySupported()) {
756bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                            mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
757bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        }
758bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    }
759618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mUserAuthorizingInvitationState);
760618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
761618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
762618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
763618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
764618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
765618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
766618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
767618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
768618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
769618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Keypad prov disc request");
770618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
771618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
772618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
773618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Display prov disc request");
774618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
775618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
776618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("PBC prov disc request");
777618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
778618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mUserAuthorizingInvitationState);
77955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
78055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
7814be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPersistGroup = true;
782fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.p2pGroupAdd()) {
783ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
784ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
7854be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
7864be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
787ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
78855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mGroupNegotiationState);
78955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
790618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff               default:
791bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    return NOT_HANDLED;
792bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            }
793bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            return HANDLED;
794bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
795bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff    }
796bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
797618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class GroupCreatingState extends State {
798bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
799bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public void enter() {
800bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName());
801618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
802618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
803bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
804bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
805bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
806bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public boolean processMessage(Message message) {
807bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName() + message.toString());
808bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            switch (message.what) {
809618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff               case GROUP_CREATING_TIMED_OUT:
810618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mGroupCreatingTimeoutIndex == message.arg1) {
811618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Group negotiation timed out");
81255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        handleGroupCreationFailure();
813618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mInactiveState);
814618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
815bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
816618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.DISCOVER_PEERS:
817618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    /* Discovery will break negotiation */
818618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
819618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            WifiP2pManager.BUSY);
820bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
821618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiP2pManager.CANCEL_CONNECT:
82255bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //Do a supplicant p2p_cancel which only cancels an ongoing
82355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //group negotiation. This will fail for a pending provision
82455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //discovery or for a pending user action, but at the framework
82555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //level, we always treat cancel as succeded and enter
82655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    //an inactive state
82755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    mWifiNative.p2pCancelConnect();
82855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    handleGroupCreationFailure();
82955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    transitionTo(mInactiveState);
83055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
83155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
832ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
83355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
83455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
83555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
83655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
83755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
83855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
839618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class UserAuthorizingInvitationState extends State {
840bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
841bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public void enter() {
842bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName());
843618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            notifyInvitationReceived();
844bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
845bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
846bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        @Override
847bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        public boolean processMessage(Message message) {
848bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            if (DBG) logd(getName() + message.toString());
849bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            switch (message.what) {
850618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
851618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    //TODO: handle persistence
85261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    if (mWifiNative.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
853bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
854618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
855bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP);
856618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
857618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
858618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    sendP2pPeersChangedBroadcast();
859618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupNegotiationState);
860618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
861618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
862618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
863618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
864bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    transitionTo(mInactiveState);
865bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    break;
866bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                default:
867bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    return NOT_HANDLED;
868bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            }
869bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff            return HANDLED;
870bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff        }
871618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
872618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
873618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void exit() {
874618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            //TODO: dismiss dialog if not already done
875618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
876bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff    }
877bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
878618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class ProvisionDiscoveryState extends State {
879618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
880618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void enter() {
881618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName());
882fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
883618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
884618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
885618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
886618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public boolean processMessage(Message message) {
887618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName() + message.toString());
888618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            WifiP2pProvDiscEvent provDisc;
889618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            WifiP2pDevice device;
890618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            switch (message.what) {
891618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
892618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
893618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
894618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
895618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
896618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
897618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
898fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
899618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mGroupNegotiationState);
900618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
901618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
902618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
903618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
904618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
905618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
906618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
907618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
908618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
909618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        /* we already have the pin */
910618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
911fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                            mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
912618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            transitionTo(mGroupNegotiationState);
913618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        } else {
914618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            transitionTo(mUserAuthorizingInvitationState);
915618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        }
916618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
917618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
918618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
919618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    provDisc = (WifiP2pProvDiscEvent) message.obj;
920618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    device = provDisc.device;
921618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
922618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
923618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
924618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        if (DBG) logd("Found a match " + mSavedPeerConfig);
925618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
926fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
927618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        notifyInvitationSent(provDisc.pin, device.deviceAddress);
928618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        transitionTo(mGroupNegotiationState);
929618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
930618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
931618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                default:
932618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    return NOT_HANDLED;
933618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
934618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            return HANDLED;
935618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
936618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
937bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff
93855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupNegotiationState extends State {
939aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        @Override
940aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void enter() {
941ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
94255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
94355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
94455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
94555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
946ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
94755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
94855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // We ignore these right now, since we get a GROUP_STARTED notification
94955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // afterwards
95055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
95155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
952ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go success");
95355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
954618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
955618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
956618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd(getName() + " group started");
957618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mGroup.isGroupOwner()) {
958618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        startDhcpServer(mGroup.getInterface());
959618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
960618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
961618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                                P2pStateMachine.this, mGroup.getInterface());
962618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
963618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        WifiP2pDevice groupOwner = mGroup.getOwner();
964618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        updateDeviceStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
965618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
966618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
967618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
968618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
969618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
97055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
97155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
972ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go failure");
97355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                    handleGroupCreationFailure();
97455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
97555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
97655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
97755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
97855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
97955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
98055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
98155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
98255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
983618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
984618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
98555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupCreatedState extends State {
98655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
98755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
988ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
989aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
990859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
991651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            updateThisDevice(WifiP2pDevice.CONNECTED);
992651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
993859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            //DHCP server has already been started if I am a group owner
994859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            if (mGroup.isGroupOwner()) {
995859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS);
996859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                sendP2pConnectionChangedBroadcast();
997859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            }
99855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
99955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            if (!mPersistGroup) {
100055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
100155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff            }
100255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
100355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
100455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
100555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
1006ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
100755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
100855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_CONNECTED_EVENT:
1009bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1010bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    String deviceAddress = device.deviceAddress;
10119322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
10129322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        mGroup.addClient(deviceAddress);
1013651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                        updateDeviceStatus(deviceAddress, WifiP2pDevice.CONNECTED);
10149322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (DBG) logd(getName() + " ap sta connected");
10159322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        sendP2pPeersChangedBroadcast();
10169322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
1017bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                        loge("Connect on null device address, ignore");
10189322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    }
101955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
102055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
102161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    device = (WifiP2pDevice) message.obj;
102261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    deviceAddress = device.deviceAddress;
10239322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
1024651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                        updateDeviceStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
10259322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (mGroup.removeClient(deviceAddress)) {
10269322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Removed client " + deviceAddress);
10274be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            if (!mPersistGroup && mGroup.isClientListEmpty()) {
10284be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
1029fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
10304be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            }
10319322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        } else {
10329322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Failed to remove client " + deviceAddress);
10339322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            for (WifiP2pDevice c : mGroup.getClientList()) {
10349322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                                if (DBG) logd("client " + c.deviceAddress);
10359322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            }
103655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
10374be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
10389322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (DBG) loge(getName() + " ap sta disconnected");
10399322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
104061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        loge("Disconnect on unknown device: " + device);
104155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
104255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
1043aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
1044aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
1045ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
1046ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            dhcpInfo != null) {
1047ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("DhcpInfo: " + dhcpInfo);
1048ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
1049aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        sendP2pConnectionChangedBroadcast();
105055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        //Turn on power save on client
105155bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
1052ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
105361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                        loge("DHCP failed");
1054fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
1055aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
1056aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
105755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
1058ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " remove group");
1059fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
1060ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
1061ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
10624be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
10634be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
1064ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
106555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
106655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1067ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " group removed");
106855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    Collection <WifiP2pDevice> devices = mGroup.getClientList();
106955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    boolean changed = false;
107055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    for (WifiP2pDevice d : mPeers.getDeviceList()) {
107155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        if (devices.contains(d) || mGroup.getOwner().equals(d)) {
1072651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                            d.status = WifiP2pDevice.AVAILABLE;
107355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            changed = true;
107455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
107555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
1076aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1077aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    if (mGroup.isGroupOwner()) {
1078aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        stopDhcpServer();
1079aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    } else {
1080ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("stop DHCP client");
1081aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
1082aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.quit();
1083aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine = null;
1084aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
1085aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
108655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mGroup = null;
108761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    mWifiNative.p2pFlush();
108855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (changed) sendP2pPeersChangedBroadcast();
108955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
109055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
109155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1092bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                    device = (WifiP2pDevice) message.obj;
1093530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    //Device loss for a connected device indicates it is not in discovery any more
1094530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    if (mGroup.contains(device)) {
1095530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                        if (DBG) logd("Lost " + device +" , do nothing");
1096530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                        return HANDLED;
109755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
1098530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    // Do the regular device lost handling
1099530040e0b9458994c02f4392765db168128d48daIrfan Sheriff                    return NOT_HANDLED;
11007d6d9c005e5cfad787bb62b7fee6be2d75b13ca3Irfan Sheriff                case WifiStateMachine.CMD_DISABLE_P2P:
110155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.REMOVE_GROUP);
110255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
110355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
110455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
110555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
1106ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("Inviting device : " + config.deviceAddress);
1107fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                    if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
1108651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                        updateDeviceStatus(config.deviceAddress, WifiP2pDevice.INVITED);
1109ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendP2pPeersChangedBroadcast();
1110ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1111ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
11124be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
11134be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
1114ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
111555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // TODO: figure out updating the status to declined when invitation is rejected
111655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
111755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
111855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1119618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1120618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
1121618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = new WifiP2pConfig();
1122618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
1123618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
1124618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
1125618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
1126618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
1127618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.pin = provDisc.pin;
1128618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1129618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
1130618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1131618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mUserAuthorizingJoinState);
113255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
11339322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
11349322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    Slog.e(TAG, "Duplicate group creation event notice, ignore");
11359322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    break;
113655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
113755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
113855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
113955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
114055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
1141aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1142aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void exit() {
1143651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            updateThisDevice(WifiP2pDevice.AVAILABLE);
1144ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            setWifiP2pInfoOnGroupTermination();
1145aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
1146ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            sendP2pConnectionChangedBroadcast();
1147aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
114855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
114955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1150618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    class UserAuthorizingJoinState extends State {
1151618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1152618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void enter() {
1153618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName());
1154618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            notifyInvitationReceived();
1155618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1156618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1157618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1158618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public boolean processMessage(Message message) {
1159618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (DBG) logd(getName() + message.toString());
1160618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            switch (message.what) {
1161618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
1162618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1163618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1164618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    //Ignore more client requests
1165618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1166618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_ACCEPT:
1167618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
116886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        mWifiNative.startWpsPbc(null);
1169618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    } else {
1170fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                        mWifiNative.startWpsPinKeypad(mSavedPeerConfig.wps.pin);
1171618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    }
1172618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1173618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1174618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1175618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                case PEER_CONNECTION_USER_REJECT:
1176618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    if (DBG) logd("User rejected incoming request");
1177618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    mSavedPeerConfig = null;
1178618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    transitionTo(mGroupCreatedState);
1179618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    break;
1180618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                default:
1181618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                    return NOT_HANDLED;
1182618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
1183618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            return HANDLED;
1184618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1185618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1186618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        @Override
1187618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        public void exit() {
1188618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            //TODO: dismiss dialog if not already done
1189618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1190618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
1191618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
119255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pStateChangedBroadcast(boolean enabled) {
119355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
119455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
119555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (enabled) {
119655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
119755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
119855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
119955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
120055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
120155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
120255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.sendStickyBroadcast(intent);
120355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
120455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1205c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private void sendP2pDiscoveryChangedBroadcast(boolean started) {
1206c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        if (mDiscoveryStarted == started) return;
1207c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        mDiscoveryStarted = started;
1208c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1209c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        if (DBG) logd("discovery change broadcast " + started);
1210c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1211c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
1212c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1213c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, started ?
1214c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED :
1215c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
1216c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff        mContext.sendStickyBroadcast(intent);
1217c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    }
1218c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
1219651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void sendThisDeviceChangedBroadcast() {
1220651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
1221651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1222651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
1223651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mContext.sendStickyBroadcast(intent);
1224651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
1225651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
122655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pPeersChangedBroadcast() {
122755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
122855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
122955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.sendBroadcast(intent);
123055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
123155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1232aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void sendP2pConnectionChangedBroadcast() {
1233ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (DBG) logd("sending p2p connection changed broadcast");
1234aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
1235aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
1236aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
1237ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
1238aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
1239aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mContext.sendStickyBroadcast(intent);
1240aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1241aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1242aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void startDhcpServer(String intf) {
1243aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        InterfaceConfiguration ifcg = null;
1244aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1245aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg = mNwService.getInterfaceConfig(intf);
1246ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
1247ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                        SERVER_ADDRESS), 24));
1248ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            ifcg.setInterfaceUp();
1249aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.setInterfaceConfig(intf, ifcg);
1250aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            /* This starts the dnsmasq server */
1251859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            mNwService.startTethering(DHCP_RANGE);
1252aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1253ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error configuring interface " + intf + ", :" + e);
1254aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1255aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1256aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1257ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Started Dhcp server on " + intf);
1258859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff   }
1259aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1260aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void stopDhcpServer() {
1261aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1262aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.stopTethering();
1263aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1264ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error stopping Dhcp server" + e);
1265aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1266aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1267aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1268ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Stopped Dhcp server");
1269aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1270aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
127155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pEnableFailure() {
127255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
127355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
127455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
127555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
127655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
127755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
127855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
127955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
128055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
128155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1282618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void addRowToDialog(ViewGroup group, int stringId, String value) {
128355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1284618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
1285618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                group, false);
1286618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
1287618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ((TextView) row.findViewById(R.id.value)).setText(value);
1288618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        group.addView(row);
128955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
129055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1291618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void notifyInvitationSent(String pin, String peerAddress) {
129255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1293aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
129455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
1295618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                .inflate(R.layout.wifi_p2p_dialog, null);
1296618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1297618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
1298618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
1299618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
130055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
130155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
1302618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
130355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
1304618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setPositiveButton(r.getString(R.string.ok), null)
130555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
130655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
130755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
130855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
130955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1310618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private void notifyInvitationReceived() {
131155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
1312618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        final WpsInfo wps = mSavedPeerConfig.wps;
131355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
1314618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                .inflate(R.layout.wifi_p2p_dialog, null);
131555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1316618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
1317618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
1318618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mSavedPeerConfig.deviceAddress));
131955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1320618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
132155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
132255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
1323618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
132455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
1325618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
132655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1327618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (wps.setup == WpsInfo.KEYPAD) {
1328618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                                mSavedPeerConfig.wps.pin = pin.getText().toString();
1329618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            }
1330618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
1331618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
1332bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        }
1333bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                    })
1334618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
1335bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        @Override
1336bbe77ca6be1f6fe5c13c97ccd8baa68ab0272cf5Irfan Sheriff                        public void onClick(DialogInterface dialog, int which) {
1337618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
1338618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                            sendMessage(PEER_CONNECTION_USER_REJECT);
133955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
134055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
134155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
134255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1343618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //make the enter pin area or the display pin area visible
1344618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        switch (wps.setup) {
1345618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.KEYPAD:
1346618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (DBG) logd("Enter pin section visible");
1347618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
1348618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1349618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            case WpsInfo.DISPLAY:
1350618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                if (DBG) logd("Shown pin section visible");
1351618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
1352618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1353618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            default:
1354618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                break;
1355618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
135655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
135755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
135855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
135955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
136055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1361651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void updateDeviceStatus(String deviceAddress, int status) {
136255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        for (WifiP2pDevice d : mPeers.getDeviceList()) {
13638c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (d.deviceAddress.equals(deviceAddress)) {
136455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                d.status = status;
136555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
136655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
136755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
13688c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
1369ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //TODO: implement when wpa_supplicant is fixed
1370ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private int configuredNetworkId(String deviceAddress) {
1371ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return -1;
1372ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1373ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1374ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
1375ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = true;
1376ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
1377ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = NetworkUtils.numericToInetAddress(serverAddress);
1378ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1379ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1380ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupTermination() {
1381ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = false;
1382ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = false;
1383ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = null;
1384ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1385ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1386618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private String getDeviceName(String deviceAddress) {
1387618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        for (WifiP2pDevice d : mPeers.getDeviceList()) {
1388618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            if (d.deviceAddress.equals(deviceAddress)) {
1389618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                return d.deviceName;
1390618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            }
1391618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        }
1392618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //Treat the address as name if there is no match
1393618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        return deviceAddress;
1394618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    }
1395618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
1396bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    private WifiP2pDevice getDeviceFromPeerList(String deviceAddress) {
1397bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        for (WifiP2pDevice d : mPeers.getDeviceList()) {
1398bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            if (d.deviceAddress.equals(deviceAddress)) {
1399bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                return d;
1400bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            }
1401bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        }
1402bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        return null;
1403bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    }
1404bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
1405bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    private void p2pConnectWithPinDisplay(WifiP2pConfig config, boolean join) {
1406fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        String pin = mWifiNative.p2pConnect(config, join);
1407bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        try {
1408bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            Integer.parseInt(pin);
1409bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            notifyInvitationSent(pin, config.deviceAddress);
1410bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        } catch (NumberFormatException ignore) {
1411bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            // do nothing if p2pConnect did not return a pin
1412bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        }
1413bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    }
1414bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff
14159322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private void initializeP2pSettings() {
1416fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setPersistentReconnect(true);
1417fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setDeviceName(mThisDevice.deviceName);
1418530040e0b9458994c02f4392765db168128d48daIrfan Sheriff        //DIRECT-XY-DEVICENAME (XY is randomly generated)
1419fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
1420fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
1421618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //The supplicant default is to support everything, but a bug necessitates
1422618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff        //the framework to specify this explicitly
1423fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative.setConfigMethods("keypad display push_button");
142455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        //STA has higher priority over P2P
142555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mWifiNative.setConcurrencyPriority("sta");
14264be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
1427fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
1428651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        updateThisDevice(WifiP2pDevice.AVAILABLE);
1429651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        if (DBG) Slog.d(TAG, "DeviceAddress: " + mThisDevice.deviceAddress);
143021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
143121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mClientInfoList.clear();
143221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pFlush();
143321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServiceFlush();
143421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceTransactionId = 0;
143521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = null;
1436651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
1437651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
1438651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private void updateThisDevice(int status) {
1439651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mThisDevice.status = status;
1440651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        sendThisDeviceChangedBroadcast();
14419322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
14429322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
144355bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    private void handleGroupCreationFailure() {
144455bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mSavedPeerConfig = null;
144555bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        /* After cancelling group formation, new connections on existing peers can fail
144655bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff         * at supplicant. Flush and restart discovery */
144755bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        mWifiNative.p2pFlush();
144855bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff        sendMessage(WifiP2pManager.DISCOVER_PEERS);
144955bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff    }
145055bfa42b05868a62ea66d291dcc51f0150fadcc2Irfan Sheriff
1451ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //State machine initiated requests can have replyTo set to null indicating
1452ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //there are no recepients, we ignore those reply actions
1453ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what) {
1454ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
1455651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
1456651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
1457651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
1458ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1459ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1460f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    private void replyToMessage(Message msg, int what, int arg1) {
1461f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff        if (msg.replyTo == null) return;
1462651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
1463651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
1464651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.arg1 = arg1;
1465651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
1466f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    }
1467f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff
1468ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what, Object obj) {
1469ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
1470651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message dstMsg = obtainMessage(msg);
1471651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.what = what;
1472651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dstMsg.obj = obj;
1473651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        mReplyChannel.replyToMessage(msg, dstMsg);
1474651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    }
1475651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff
1476651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /* arg2 on the source message has a hash code that needs to be retained in replies
1477651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff     * see WifiP2pManager for details */
1478651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    private Message obtainMessage(Message srcMsg) {
1479651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        Message msg = Message.obtain();
1480651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        msg.arg2 = srcMsg.arg2;
1481651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        return msg;
1482ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1483ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1484ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void logd(String s) {
1485ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.d(TAG, s);
1486ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1487ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1488ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void loge(String s) {
1489ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.e(TAG, s);
1490ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1491ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
149221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
149321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Update service discovery request to wpa_supplicant.
149421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
149521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean updateSupplicantServiceRequest() {
149621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearSupplicantServiceRequest();
149721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
149821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        StringBuffer sb = new StringBuffer();
149921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c: mClientInfoList.values()) {
150021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            int key;
150121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            WifiP2pServiceRequest req;
150221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            for (int i=0; i < c.mReqList.size(); i++) {
15033b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                req = c.mReqList.valueAt(i);
150421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (req != null) {
150521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    sb.append(req.getSupplicantQuery());
150621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
150721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
150821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
150921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
151021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (sb.length() == 0) {
151121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
151221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
151321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
151421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
151521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
151621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
151721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
151821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
151921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
152021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
152121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
152221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Clear service discovery request in wpa_supplicant
152321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
152421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearSupplicantServiceRequest() {
152521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) return;
152621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
152721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServDiscCancelReq(mServiceDiscReqId);
152821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mServiceDiscReqId = null;
152921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
153021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
153121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /* TODO: We could track individual service adds seperately and avoid
153221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * having to do update all service requests on every new request
153321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
153421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean addServiceRequest(Messenger m, WifiP2pServiceRequest req) {
153521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearClientDeadChannels();
153621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, true);
153721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
153821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
153921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
154021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
15413b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        ++mServiceTransactionId;
15423b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //The Wi-Fi p2p spec says transaction id should be non-zero
15433b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        if (mServiceTransactionId == 0) ++mServiceTransactionId;
15443b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        req.setTransactionId(mServiceTransactionId);
154521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mReqList.put(mServiceTransactionId, req);
154621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
154721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
154821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return true;
154921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
155021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
155121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return updateSupplicantServiceRequest();
155221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
155321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
155421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
155521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
155621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
155721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
155821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
155921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
15603b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //Application does not have transaction id information
15613b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        //go through stored requests to remove
15623b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        boolean removed = false;
15633b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        for (int i=0; i < clientInfo.mReqList.size(); i++) {
15643b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            if (req.equals(clientInfo.mReqList.valueAt(i))) {
15653b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                removed = true;
15663b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                clientInfo.mReqList.removeAt(i);
15673b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                break;
15683b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            }
15693b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        }
15703b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
15713b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        if (!removed) return;
157221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
157321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
157421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
157521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
157621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
157721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
157821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
157921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
158021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
158121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
158221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        updateSupplicantServiceRequest();
158321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
158421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
158521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearServiceRequests(Messenger m) {
158621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
158721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
158821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
158921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
159021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
159121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
159221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0) {
159321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
159421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
159521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
159621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mReqList.clear();
159721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
159821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mServList.size() == 0) {
159921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove channel information from framework");
160021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
160121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
160221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
160321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (mServiceDiscReqId == null) {
160421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
160521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
160621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
160721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        updateSupplicantServiceRequest();
160821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
160921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
161021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private boolean addLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
161121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearClientDeadChannels();
161221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, true);
161321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
161421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
161521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
161621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
161721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!clientInfo.mServList.add(servInfo)) {
161821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
161921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
162021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
162121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (!mWifiNative.p2pServiceAdd(servInfo)) {
162221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            clientInfo.mServList.remove(servInfo);
162321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return false;
162421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
162521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
162621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return true;
162721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
162821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
162921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void removeLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
163021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
163121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
163221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
163321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
163421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
163521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        mWifiNative.p2pServiceDel(servInfo);
163621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
163721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mServList.remove(servInfo);
163821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
163921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
164021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
164121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
164221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
164321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
164421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearLocalServices(Messenger m) {
164521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = getClientInfo(m, false);
164621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null) {
164721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            return;
164821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
164921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
165021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (WifiP2pServiceInfo servInfo: clientInfo.mServList) {
165121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mWifiNative.p2pServiceDel(servInfo);
165221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
165321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
165421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clientInfo.mServList.clear();
165521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo.mReqList.size() == 0) {
165621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("remove client information from framework");
165721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.remove(clientInfo.mMessenger);
165821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
165921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
166021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
166121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearClientInfo(Messenger m) {
166221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearLocalServices(m);
166321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        clearServiceRequests(m);
166421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
166521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
166621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
166721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Send the service response to the WifiP2pManager.Channel.
166821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
166921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param resp
167021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
167121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void sendServiceResponse(WifiP2pServiceResponse resp) {
167221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c : mClientInfoList.values()) {
167321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            WifiP2pServiceRequest req = c.mReqList.get(resp.getTransactionId());
167421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (req != null) {
167521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                Message msg = Message.obtain();
167621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.what = WifiP2pManager.RESPONSE_SERVICE;
167721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.arg1 = 0;
167821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.arg2 = 0;
167921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                msg.obj = resp;
168021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                try {
168121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    c.mMessenger.send(msg);
168221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } catch (RemoteException e) {
168321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    if (DBG) logd("detect dead channel");
168421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    clearClientInfo(c.mMessenger);
16853b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                    return;
168621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
168721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
168821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
168921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
169021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
169121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
169221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * We dont get notifications of clients that have gone away.
169321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * We detect this actively when services are added and throw
169421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * them away.
169521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
169621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * TODO: This can be done better with full async channels.
169721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
169821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private void clearClientDeadChannels() {
16993b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
17003b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
170121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        for (ClientInfo c : mClientInfoList.values()) {
170221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            Message msg = Message.obtain();
170321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.what = WifiP2pManager.PING;
170421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.arg1 = 0;
170521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.arg2 = 0;
170621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            msg.obj = null;
170721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            try {
170821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                c.mMessenger.send(msg);
170921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } catch (RemoteException e) {
171021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (DBG) logd("detect dead channel");
17113b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff                deadClients.add(c.mMessenger);
171221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            }
171321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
17143b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff
17153b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        for (Messenger m : deadClients) {
17163b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff            clearClientInfo(m);
17173b8be87f89e2f98345980954994bdde82b7ee9adIrfan Sheriff        }
171821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
171921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
172021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
172121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Return the specified ClientInfo.
172221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param m Messenger
172321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @param createIfNotExist if true and the specified channel info does not exist,
172421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * create new client info.
172521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * @return the specified ClientInfo.
172621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
172721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private ClientInfo getClientInfo(Messenger m, boolean createIfNotExist) {
172821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        ClientInfo clientInfo = mClientInfoList.get(m);
172921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
173021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        if (clientInfo == null && createIfNotExist) {
173121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            if (DBG) logd("add a new client");
173221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            clientInfo = new ClientInfo(m);
173321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mClientInfoList.put(m, clientInfo);
173421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
173521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
173621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        return clientInfo;
173721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
173821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
173921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    }
174021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
174121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /**
174221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Information about a particular client and we track the service discovery requests
174321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * and the local services registered by the client.
174421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
174521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private class ClientInfo {
174621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
174721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
174821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A reference to WifiP2pManager.Channel handler.
174921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * The response of this request is notified to WifiP2pManager.Channel handler
175021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
175121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private Messenger mMessenger;
175221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
175321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
175421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A service discovery request list.
175521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
175621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private SparseArray<WifiP2pServiceRequest> mReqList;
175721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
175821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        /*
175921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         * A local service information list.
176021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff         */
176121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private List<WifiP2pServiceInfo> mServList;
176221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
176321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        private ClientInfo(Messenger m) {
176421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mMessenger = m;
176521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mReqList = new SparseArray();
176621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            mServList = new ArrayList<WifiP2pServiceInfo>();
176721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff        }
176855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
176955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync}
1770