WifiP2pService.java revision 616f3173e08ec6110cf5766c70f84c9e031fb7d7
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;
44489a9d81fd1458940e1ec01ba0cef36843732479Irfan Sheriffimport android.net.wifi.Wps;
45489a9d81fd1458940e1ec01ba0cef36843732479Irfan Sheriffimport android.net.wifi.Wps.Setup;
4655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pDevice.Status;
4755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Binder;
4855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.IBinder;
49cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.INetworkManagementService;
5055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Handler;
5155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.HandlerThread;
5255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Message;
53f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport android.os.Messenger;
54cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.ServiceManager;
55cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.SystemProperties;
569322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriffimport android.provider.Settings;
5755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Slog;
5855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.LayoutInflater;
5955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.View;
6055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.WindowManager;
6155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.widget.EditText;
6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
63f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport com.android.internal.R;
64616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriffimport com.android.internal.telephony.TelephonyIntents;
6555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.AsyncChannel;
6655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.Protocol;
6755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.State;
6855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.StateMachine;
6955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
70aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.FileDescriptor;
71aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.PrintWriter;
72aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.util.Collection;
73aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
7455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/**
7555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * WifiP2pService inclues a state machine to perform Wi-Fi p2p operations. Applications
7655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * communicate with this service to issue device discovery and connectivity requests
7755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * through the WifiP2pManager interface. The state machine communicates with the wifi
7855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * driver through wpa_supplicant and handles the event responses through WifiMonitor.
7955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
8055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Note that the term Wifi when used without a p2p suffix refers to the client mode
8155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * of Wifi operation
8255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * @hide
8355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpublic class WifiP2pService extends IWifiP2pManager.Stub {
8555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TAG = "WifiP2pService";
8655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final boolean DBG = true;
87aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private static final String NETWORKTYPE = "WIFI_P2P";
8855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
8955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private Context mContext;
90cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    private String mInterface;
91daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    private Notification mNotification;
92cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
93cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    INetworkManagementService mNwService;
94aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private DhcpStateMachine mDhcpStateMachine;
9555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
96aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    //Tracked to notify the user about wifi client/hotspot being shut down
97aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    //during p2p bring up
9855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private int mWifiState = WifiManager.WIFI_STATE_DISABLED;
9955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private int mWifiApState = WifiManager.WIFI_AP_STATE_DISABLED;
10055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
10155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private P2pStateMachine mP2pStateMachine;
102ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private AsyncChannel mReplyChannel = new AsyncChannel();
10355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private AsyncChannel mWifiChannel;
10455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
105ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Two minutes comes from the wpa_supplicant setting */
106ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int GROUP_NEGOTIATION_WAIT_TIME_MS = 120 * 1000;
107aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private static int mGroupNegotiationTimeoutIndex = 0;
108aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
109ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /**
110ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     * Delay between restarts upon failure to setup connection with supplicant
111ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     */
112ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int P2P_RESTART_INTERVAL_MSECS = 5000;
113ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
114ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /**
115ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     * Number of times we attempt to restart p2p
116ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     */
117ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int P2P_RESTART_TRIES = 5;
118ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
119ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private int mP2pRestartCount = 0;
120ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
12155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
12255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
12355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Message sent to WifiStateMachine to indicate p2p enable is pending */
12455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_ENABLE_PENDING              =   BASE + 1;
12555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Message sent to WifiStateMachine to indicate Wi-Fi client/hotspot operation can proceed */
12655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int WIFI_ENABLE_PROCEED             =   BASE + 2;
12755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
128aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    /* Delayed message to timeout of group negotiation */
129aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    public static final int GROUP_NEGOTIATION_TIMED_OUT     =   BASE + 3;
130aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
13155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* User accepted to disable Wi-Fi in order to enable p2p */
132dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff    private static final int WIFI_DISABLE_USER_ACCEPT       =   BASE + 4;
133dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff    /* User rejected to disable Wi-Fi in order to enable p2p */
134dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff    private static final int WIFI_DISABLE_USER_REJECT       =   BASE + 5;
13555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
136295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff    /* Airplane mode changed */
137295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff    private static final int AIRPLANE_MODE_CHANGED          =   BASE + 6;
138616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff    /* Emergency callback mode */
139616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff    private static final int EMERGENCY_CALLBACK_MODE        =   BASE + 7;
140295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff
14155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final boolean mP2pSupported;
1429322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private final String mDeviceType;
1439322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private String mDeviceName;
1444be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    private String mDeviceAddress;
1454be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
1464be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    /* When a group has been explicitly created by an app, we persist the group
1474be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * even after all clients have been disconnected until an explicit remove
1484be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff     * is invoked */
1494be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    private boolean mPersistGroup;
15055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
151aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private NetworkInfo mNetworkInfo;
152aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
153859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    /* Is chosen as a unique range to avoid conflict with
154859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff       the range defined in Tethering.java */
155859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
156859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff    private static final String SERVER_ADDRESS = "192.168.49.1";
157859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
15855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pService(Context context) {
15955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext = context;
16055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
161cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mInterface = SystemProperties.get("wifi.interface", "wlan0");
162aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
163aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
164a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
165a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff                PackageManager.FEATURE_WIFI_DIRECT);
166a8f63a38a0570d2521d5db73f05218d114fa902aIrfan Sheriff
1679322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        mDeviceType = mContext.getResources().getString(
1689322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                com.android.internal.R.string.config_wifi_p2p_device_type);
1699322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        mDeviceName = getDefaultDeviceName();
17055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
17255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine.start();
17355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // broadcasts
17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        IntentFilter filter = new IntentFilter();
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
177295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
178616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
17955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
18055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.registerReceiver(new WifiStateReceiver(), filter);
18155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
182aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
18355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
184cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    public void connectivityServiceReady() {
185cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
186cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
187cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    }
188cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
18955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class WifiStateReceiver extends BroadcastReceiver {
19055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
19155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void onReceive(Context context, Intent intent) {
192616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff            String action = intent.getAction();
193616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
19455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
19555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        WifiManager.WIFI_STATE_DISABLED);
196616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff            } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
19755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mWifiApState = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        WifiManager.WIFI_AP_STATE_DISABLED);
199616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff            } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
200295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                mP2pStateMachine.sendMessage(AIRPLANE_MODE_CHANGED);
201616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
202616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff                if (intent.getBooleanExtra("phoneinECMState", false) == true) {
203616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff                    mP2pStateMachine.sendMessage(EMERGENCY_CALLBACK_MODE);
204616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff                }
20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
20855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceAccessPermission() {
21055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
21155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
21255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
21355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceChangePermission() {
21555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2199322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    /* We use the 4 digits of the ANDROID_ID to have a friendly
2209322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff     * default that has low likelihood of collision with a peer */
2219322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private String getDefaultDeviceName() {
2229322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        String id = Settings.Secure.getString(mContext.getContentResolver(),
2239322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    Settings.Secure.ANDROID_ID);
2249322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        return "Android_" + id.substring(0,4);
2259322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
2269322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
22755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
22855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Get a reference to handler. This is used by a client to establish
22955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * an AsyncChannel communication with WifiP2pService
23055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
23155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public Messenger getMessenger() {
23255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceAccessPermission();
23355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceChangePermission();
23455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return new Messenger(mP2pStateMachine.getHandler());
23555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
23655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    @Override
23855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
23955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
24055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                != PackageManager.PERMISSION_GRANTED) {
24155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
24255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + Binder.getCallingPid()
24355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + ", uid=" + Binder.getCallingUid());
24455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return;
24555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
24655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
24755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
24855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
24955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
25055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Handles interaction with WifiStateMachine
25155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
25255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class P2pStateMachine extends StateMachine {
25355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
25455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private DefaultState mDefaultState = new DefaultState();
25555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
25655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
25755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
258ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        private WaitForUserActionState mWaitForUserActionState = new WaitForUserActionState();
25955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WaitForWifiDisableState mWaitForWifiDisableState = new WaitForWifiDisableState();
26055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
26155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
26255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Inactive is when p2p is enabled with no connectivity
26355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private InactiveState mInactiveState = new InactiveState();
26455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
26555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
26655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
26755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiMonitor mWifiMonitor = new WifiMonitor(this);
26855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
26955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
270ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
27155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mGroup;
27255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pConfig from GO negotiation request
27455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pConfig mSavedGoNegotiationConfig;
27555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pConfig from connect request
27755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pConfig mSavedConnectConfig;
27855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pGroup from invitation request
28055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mSavedP2pGroup;
28155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        P2pStateMachine(String name, boolean p2pSupported) {
28355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            super(name);
28455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            addState(mDefaultState);
28655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pNotSupportedState, mDefaultState);
28755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisablingState, mDefaultState);
28855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisabledState, mDefaultState);
289ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    addState(mWaitForUserActionState, mP2pDisabledState);
290ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    addState(mWaitForWifiDisableState, mP2pDisabledState);
29155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnablingState, mDefaultState);
29255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnabledState, mDefaultState);
29355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mInactiveState, mP2pEnabledState);
29455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupNegotiationState, mP2pEnabledState);
29555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupCreatedState, mP2pEnabledState);
29655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
29755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (p2pSupported) {
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pDisabledState);
29955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else {
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pNotSupportedState);
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
30255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
30355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class DefaultState extends State {
30555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
307ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
30855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
311ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Full connection with WifiStateMachine established");
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = (AsyncChannel) message.obj;
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
314ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Full connection failure, error = " + message.arg1);
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = null;
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
31855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
321ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Send failed, client connection lost");
32255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
323ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Client connection lost with reason: " + message.arg1);
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel = null;
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
32755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    AsyncChannel ac = new AsyncChannel();
33055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    ac.connect(mContext, getHandler(), message.replyTo);
33155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
33255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiStateMachine.WIFI_ENABLE_PENDING:
33355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // Disable p2p operation before we can respond
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.DISABLE_P2P);
33555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
33655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
33755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.ENABLE_P2P:
3384be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED,
3394be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
34055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
3424be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED,
3434be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
34455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
3464be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
3474be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
3504be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
3514be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
35255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
35355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
3544be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
3554be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
35655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
35755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
3584be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
3594be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
36055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
36155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REQUEST_PEERS:
362ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
363ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
364ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REQUEST_CONNECTION_INFO:
365ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO, mWifiP2pInfo);
36655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
3674be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                case WifiP2pManager.REQUEST_GROUP_INFO:
3684be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup);
3694be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    break;
370295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                case AIRPLANE_MODE_CHANGED:
371295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                    if (isAirplaneModeOn()) sendMessage(WifiP2pManager.DISABLE_P2P);
372295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                    break;
373616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff                case EMERGENCY_CALLBACK_MODE:
374616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff                    sendMessage(WifiP2pManager.DISABLE_P2P);
375616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff                    break;
376295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                    // Ignore
37755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WIFI_DISABLE_USER_ACCEPT:
378dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                case WIFI_DISABLE_USER_REJECT:
379aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case GROUP_NEGOTIATION_TIMED_OUT:
38055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
38155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
382ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Unhandled message " + message);
38355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
38555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
38655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
38755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
38855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
38955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pNotSupportedState extends State {
39055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
39155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
39255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
39355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // Allow Wi-Fi to proceed
39455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiStateMachine.WIFI_ENABLE_PENDING:
395ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WIFI_ENABLE_PROCEED);
39655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
39755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.ENABLE_P2P:
398ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED,
39955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
40055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
40155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
402ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED,
40355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
40455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
405ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISCOVER_PEERS:
406ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
407ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
408ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
409ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CONNECT:
410ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
411ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
412ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
413ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CREATE_GROUP:
414ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
415ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
416ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
417ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
418ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
419ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
420ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
421ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff               default:
42255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
42355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
42455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
42555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
42755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
42855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisablingState extends State {
42955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
43055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
431ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
432ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            logd("stopping supplicant");
433ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (!WifiNative.stopSupplicant()) {
434ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                loge("Failed to stop supplicant, issue kill");
435ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                WifiNative.killSupplicant();
436ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            }
43755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
43855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
43955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
44055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
441ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
44255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
44355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
444ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("Supplicant connection lost");
445ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    WifiNative.closeSupplicantConnection();
44655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisabledState);
44755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
448ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
449ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
450ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
451ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
45255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
45355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
45455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
45555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
45655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
45755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
45855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
45955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
46055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisabledState extends State {
46155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       @Override
46255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
463ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
46455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
46555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
46655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
46755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
468ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
46955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
47055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.ENABLE_P2P:
47155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    OnClickListener listener = new OnClickListener() {
47255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        @Override
47355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
47455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            if (which == DialogInterface.BUTTON_POSITIVE) {
47555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                sendMessage(WIFI_DISABLE_USER_ACCEPT);
47655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            } else {
477dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                                sendMessage(WIFI_DISABLE_USER_REJECT);
47855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            }
47955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
48055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    };
48155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
48255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // Show a user request dialog if we know Wi-Fi client/hotspot is in operation
48355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mWifiState != WifiManager.WIFI_STATE_DISABLED ||
48455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED) {
48555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        Resources r = Resources.getSystem();
48655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        AlertDialog dialog = new AlertDialog.Builder(mContext)
48755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
48855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setMessage(r.getString(R.string.wifi_p2p_turnon_message))
48955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setPositiveButton(r.getString(R.string.ok), listener)
49055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setNegativeButton(r.getString(R.string.cancel), listener)
49155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .create();
49255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
49355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        dialog.show();
494ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        transitionTo(mWaitForUserActionState);
49555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
49655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel.sendMessage(P2P_ENABLE_PENDING);
49755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        transitionTo(mWaitForWifiDisableState);
49855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
499ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED);
50055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
501ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
502ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED);
503ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
504ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiStateMachine.WIFI_ENABLE_PENDING:
505ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WIFI_ENABLE_PROCEED);
506ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
507ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
508ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    return NOT_HANDLED;
509ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            }
510ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return HANDLED;
511ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
512ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
513ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
514ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    class WaitForUserActionState extends State {
515ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        @Override
516ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        public void enter() {
517ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
518ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
519ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
520ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        @Override
521ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        public boolean processMessage(Message message) {
522ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
523ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            switch (message.what) {
52455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WIFI_DISABLE_USER_ACCEPT:
52555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel.sendMessage(P2P_ENABLE_PENDING);
52655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mWaitForWifiDisableState);
52755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
528dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                case WIFI_DISABLE_USER_REJECT:
529dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                    logd("User rejected enabling p2p");
530dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                    sendP2pStateChangedBroadcast(false);
531dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                    transitionTo(mP2pDisabledState);
532dff28d5293c16ac75f6db7a1c3b78fbaad1f2f6aIrfan Sheriff                    break;
533ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
534ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
535ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
53655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
53755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
53855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
53955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
54055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
54155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
54255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
54355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
54455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class WaitForWifiDisableState extends State {
54555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
54655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
547ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
54855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
54955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
55055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
55155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
552ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
55355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
55455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiStateMachine.P2P_ENABLE_PROCEED:
555cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    try {
556cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        mNwService.wifiFirmwareReload(mInterface, "P2P");
557cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    } catch (Exception e) {
558ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Failed to reload p2p firmware " + e);
559cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        // continue
560cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    }
561ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
562ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    //A runtime crash can leave the interface up and
563ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    //this affects p2p when supplicant starts up.
564ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    //Ensure interface is down before a supplicant start.
565ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    try {
566ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        mNwService.setInterfaceDown(mInterface);
567ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } catch (Exception e) {
568ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) Slog.w(TAG, "Unable to bring down wlan interface: " + e);
569ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
570ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
571f42c39b3d188ebb3ba9003cffc530717829fe874Irfan Sheriff                    if (WifiNative.startP2pSupplicant()) {
57255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiMonitor.startMonitoring();
57355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        transitionTo(mP2pEnablingState);
57455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
57555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        notifyP2pEnableFailure();
57655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        transitionTo(mP2pDisabledState);
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
57855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
579ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
580ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
581ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
582ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
58355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
58455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
58555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
58655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
58755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
58855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
58955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
59055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnablingState extends State {
59155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
59255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
593ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
59455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
59555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
59655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
59755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
598ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
59955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
60055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
601ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("P2p start successful");
60255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
60355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
604ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
605ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (++mP2pRestartCount <= P2P_RESTART_TRIES) {
606ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Failed to start p2p, retry");
607ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        WifiNative.killSupplicant();
608ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
609ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
610ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Failed " + mP2pRestartCount + " times to start p2p, quit ");
611ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        mP2pRestartCount = 0;
612ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
613aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    transitionTo(mP2pDisabledState);
614ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
615ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
616ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
617ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
618ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
61955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
62055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
62155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
62255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
62355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
62455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
62555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
62655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnabledState extends State {
62755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
62855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
629ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
63055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(true);
631aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(true);
6329322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff            initializeP2pSettings();
633daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            showNotification();
63455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
63555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
63655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
63755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
638ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
63955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
640ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
641ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED);
642ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
64355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
644ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
645ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED);
64655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisablingState);
64755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
64855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
64955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    int timeout = message.arg1;
650ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pFind(timeout)) {
651ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
652ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
6534be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
6544be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
655ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
65655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
65755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
65855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
6594be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    if (mDeviceAddress.equals(device.deviceAddress)) break;
6604be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPeers.update(device);
66155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
66255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
66355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
66455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    device = (WifiP2pDevice) message.obj;
66555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
66655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
66755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
668ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " sending connect");
66955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSavedConnectConfig = (WifiP2pConfig) message.obj;
6704be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPersistGroup = false;
671ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    int netId = configuredNetworkId(mSavedConnectConfig.deviceAddress);
672ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (netId >= 0) {
673ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        //TODO: if failure, remove config and do a regular p2pConnect()
674ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        WifiNative.p2pReinvoke(netId, mSavedConnectConfig.deviceAddress);
675ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
6764be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        boolean join = false;
6774be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        if (isGroupOwner(mSavedConnectConfig.deviceAddress)) join = true;
6784be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        String pin = WifiNative.p2pConnect(mSavedConnectConfig, join);
679ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        try {
680ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            Integer.parseInt(pin);
681ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            notifyWpsPin(pin, mSavedConnectConfig.deviceAddress);
682ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        } catch (NumberFormatException ignore) {
683ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            // do nothing if p2pConnect did not return a pin
684ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        }
68555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
68655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.INVITED);
68755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
688ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
68955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mGroupNegotiationState);
69055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
691ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant died */
692ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Connection lost, restart p2p");
693ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    WifiNative.killSupplicant();
694ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    WifiNative.closeSupplicantConnection();
695ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
696ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    transitionTo(mP2pDisabledState);
697ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
6989322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    break;
6999322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
7009322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    mGroup = (WifiP2pGroup) message.obj;
7019322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (DBG) logd(getName() + " group started");
7029322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (mGroup.isGroupOwner()) {
7039322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        startDhcpServer(mGroup.getInterface());
7049322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
7059322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
7069322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                                P2pStateMachine.this, mGroup.getInterface());
7079322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
7089322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        WifiP2pDevice groupOwner = mGroup.getOwner();
7099322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        updateDeviceStatus(groupOwner.deviceAddress, Status.CONNECTED);
7109322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        sendP2pPeersChangedBroadcast();
7119322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    }
7129322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    transitionTo(mGroupCreatedState);
7139322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    break;
71455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
71555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
71655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
71755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
71855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
71955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
72055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
72155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void exit() {
72255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(false);
723aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(false);
724daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            clearNotification();
72555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
72655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
72755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
72855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class InactiveState extends State {
7294be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        @Override
7304be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        public void enter() {
731ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
7324be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            //Start listening every time we get inactive
7334be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            WifiNative.p2pListen();
73455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
73555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
73655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
73755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
738ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
73955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
74055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
74155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSavedGoNegotiationConfig = (WifiP2pConfig) message.obj;
74255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig);
74355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
74455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
7454be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    mPersistGroup = true;
746ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pGroupAdd()) {
747ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
748ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
7494be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
7504be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
751ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
75255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mGroupNegotiationState);
75355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
75455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
75555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
75655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pInvitationReceived(group);
75755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
758ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
75955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
76055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
76155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
76255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
76355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
76455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
76555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupNegotiationState extends State {
766aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        @Override
767aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void enter() {
768ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
769aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            sendMessageDelayed(obtainMessage(GROUP_NEGOTIATION_TIMED_OUT,
770aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    ++mGroupNegotiationTimeoutIndex, 0), GROUP_NEGOTIATION_WAIT_TIME_MS);
77155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
77255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
77355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
77455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
775ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
77655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
77755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // We ignore these right now, since we get a GROUP_STARTED notification
77855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // afterwards
77955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
78055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
781ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go success");
78255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
78355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
78455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
785ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go failure");
78655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
78755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSavedConnectConfig = null;
788ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    sendP2pPeersChangedBroadcast();
78955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
79055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
791aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case GROUP_NEGOTIATION_TIMED_OUT:
792aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    if (mGroupNegotiationTimeoutIndex == message.arg1) {
793ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Group negotiation timed out");
794aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
795aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mSavedConnectConfig = null;
796ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendP2pPeersChangedBroadcast();
797aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        transitionTo(mInactiveState);
798aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
799aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
8004be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                case WifiP2pManager.DISCOVER_PEERS:
8014be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    /* Discovery will break negotiation */
8024be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
8034be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiP2pManager.BUSY);
8044be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    break;
80555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
80655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
80755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
80855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
80955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
81055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
81155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
81255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupCreatedState extends State {
81355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
81455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
815ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
816aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
817859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff
818859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            //DHCP server has already been started if I am a group owner
819859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            if (mGroup.isGroupOwner()) {
820859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS);
821859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                sendP2pConnectionChangedBroadcast();
822859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            }
82355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
82455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
82555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
82655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
827ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
82855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
82955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_CONNECTED_EVENT:
8308c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    //After a GO setup, STA connected event comes with interface address
8318c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    String interfaceAddress = (String) message.obj;
8328c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    String deviceAddress = getDeviceAddress(interfaceAddress);
8339322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
8349322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        mGroup.addClient(deviceAddress);
8359322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        updateDeviceStatus(deviceAddress, Status.CONNECTED);
8369322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (DBG) logd(getName() + " ap sta connected");
8379322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        sendP2pPeersChangedBroadcast();
8389322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
8399322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        loge("Connect on unknown device address : " + interfaceAddress);
8409322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    }
84155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
84255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
8438c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    interfaceAddress = (String) message.obj;
8448c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    deviceAddress = getDeviceAddress(interfaceAddress);
8459322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    if (deviceAddress != null) {
8469322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        updateDeviceStatus(deviceAddress, Status.AVAILABLE);
8479322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (mGroup.removeClient(deviceAddress)) {
8489322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Removed client " + deviceAddress);
8494be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            if (!mPersistGroup && mGroup.isClientListEmpty()) {
8504be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
8514be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiNative.p2pGroupRemove(mGroup.getInterface());
8524be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            }
8539322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        } else {
8549322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            if (DBG) logd("Failed to remove client " + deviceAddress);
8559322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            for (WifiP2pDevice c : mGroup.getClientList()) {
8569322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                                if (DBG) logd("client " + c.deviceAddress);
8579322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                            }
85855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
8594be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        sendP2pPeersChangedBroadcast();
8609322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        if (DBG) loge(getName() + " ap sta disconnected");
8619322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    } else {
8629322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                        loge("Disconnect on unknown device address : " + interfaceAddress);
86355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
86455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
865aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
866aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
867ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
868ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            dhcpInfo != null) {
869ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("DhcpInfo: " + dhcpInfo);
870ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
871aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        sendP2pConnectionChangedBroadcast();
872ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
873ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        WifiNative.p2pGroupRemove(mGroup.getInterface());
874aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
875aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
87655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
877ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " remove group");
878ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pGroupRemove(mGroup.getInterface())) {
879ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
880ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
8814be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
8824be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
883ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
88455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
88555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
886ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " group removed");
88755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    Collection <WifiP2pDevice> devices = mGroup.getClientList();
88855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    boolean changed = false;
88955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    for (WifiP2pDevice d : mPeers.getDeviceList()) {
89055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        if (devices.contains(d) || mGroup.getOwner().equals(d)) {
89155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            d.status = Status.AVAILABLE;
89255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            changed = true;
89355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
89455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
895aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
896aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    if (mGroup.isGroupOwner()) {
897aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        stopDhcpServer();
898aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    } else {
899ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("stop DHCP client");
900aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
901aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.quit();
902aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine = null;
903aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
904aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
90555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mGroup = null;
90655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (changed) sendP2pPeersChangedBroadcast();
90755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
90855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
90955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
91055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
91155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (device.equals(mGroup.getOwner())) {
912ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        logd("Lost the group owner, killing p2p connection");
913aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        WifiNative.p2pGroupRemove(mGroup.getInterface());
9144be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                    } else if (mGroup.removeClient(device)) {
9154be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        if (!mPersistGroup && mGroup.isClientListEmpty()) {
9164be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            Slog.d(TAG, "Client list empty, removing a non-persistent p2p group");
9174be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                            WifiNative.p2pGroupRemove(mGroup.getInterface());
9184be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        }
91955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
92055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED; // Do the regular device lost handling
92155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
92255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.REMOVE_GROUP);
92355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
92455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
92555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
92655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
927ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("Inviting device : " + config.deviceAddress);
928ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pInvite(mGroup, config.deviceAddress)) {
929ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        updateDeviceStatus(config.deviceAddress, Status.INVITED);
930ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendP2pPeersChangedBroadcast();
931ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
932ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
9334be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
9344be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                                WifiP2pManager.ERROR);
935ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
93655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // TODO: figure out updating the status to declined when invitation is rejected
93755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
93855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
939ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("===> INVITATION RESULT EVENT : " + message.obj);
94055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
94155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
94255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pProvDiscPbcRequest((WifiP2pDevice) message.obj);
94355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
94455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
94555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pProvDiscPinRequest((WifiP2pDevice) message.obj);
94655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
9479322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
9489322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    Slog.e(TAG, "Duplicate group creation event notice, ignore");
9499322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff                    break;
95055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.WPS_PBC:
9512b8edd0c485f74067605c19983e3e7f44b20ec50repo sync                    WifiNative.wpsPbc();
95255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
95355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.WPS_PIN:
9542b8edd0c485f74067605c19983e3e7f44b20ec50repo sync                    WifiNative.wpsPin((String) message.obj);
95555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
95655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
95755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
95855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
95955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
96055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
961aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
962aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void exit() {
963ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            setWifiP2pInfoOnGroupTermination();
964aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
965ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            sendP2pConnectionChangedBroadcast();
966aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
96755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
96855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
96955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pStateChangedBroadcast(boolean enabled) {
97055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
97155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
97255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (enabled) {
97355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
97455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
97555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
97655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
97755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
97855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
97955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.sendStickyBroadcast(intent);
98055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
98155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
98255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pPeersChangedBroadcast() {
98355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
98455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
98555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.sendBroadcast(intent);
98655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
98755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
988aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void sendP2pConnectionChangedBroadcast() {
989ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (DBG) logd("sending p2p connection changed broadcast");
990aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
991aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
992aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
993ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
994aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
995aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mContext.sendStickyBroadcast(intent);
996aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
997aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
998aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void startDhcpServer(String intf) {
999aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        InterfaceConfiguration ifcg = null;
1000aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1001aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg = mNwService.getInterfaceConfig(intf);
1002aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
1003859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff                        SERVER_ADDRESS), 24);
1004aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg.interfaceFlags = "[up]";
1005aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.setInterfaceConfig(intf, ifcg);
1006aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            /* This starts the dnsmasq server */
1007859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff            mNwService.startTethering(DHCP_RANGE);
1008aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1009ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error configuring interface " + intf + ", :" + e);
1010aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1011aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1012aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1013ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Started Dhcp server on " + intf);
1014859e7de2359420dcc5275bdce588b96dcc9203f0Irfan Sheriff   }
1015aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1016aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void stopDhcpServer() {
1017aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
1018aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.stopTethering();
1019aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
1020ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error stopping Dhcp server" + e);
1021aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
1022aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
1023aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1024ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Stopped Dhcp server");
1025aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
1026aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
102755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pEnableFailure() {
102855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
102955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
103055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
103155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
103255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
103355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
103455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
103555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
103655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
103755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
103855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyWpsPin(String pin, String peerAddress) {
103955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
104055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
104155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
104255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_pin_display_message, pin, peerAddress))
104355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
104455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
104555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
104655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
104755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
104855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
104955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pGoNegotationRequest(WifiP2pConfig config) {
105055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
10516f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        Wps wps = config.wps;
105255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
105355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
105455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
105555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
105655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
105755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
105855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
105955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
106055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1061ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            if (DBG) logd(getName() + " connect " + pin.getText());
1062aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
1063aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            if (pin.getVisibility() == View.GONE) {
10646f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                                mSavedGoNegotiationConfig.wps.setup = Setup.PBC;
1065aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            } else {
10666f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                                mSavedGoNegotiationConfig.wps.setup = Setup.KEYPAD;
10676f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff                                mSavedGoNegotiationConfig.wps.pin = pin.getText().toString();
1068aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            }
1069aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
1070aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            mSavedGoNegotiationConfig = null;
107155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
107255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
107355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
107455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        @Override
107555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1076ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
1077ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            mSavedGoNegotiationConfig = null;
107855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
107955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
108055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
108155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
10826f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        if (wps.setup == Setup.PBC) {
108355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pin.setVisibility(View.GONE);
108455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
108555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        config.deviceAddress));
108655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
108755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            dialog.setMessage(r.getString(R.string.wifi_p2p_pin_go_negotiation_request_message,
108855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        config.deviceAddress));
108955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
109055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
109155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
109255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
109355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
109455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
109555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pProvDiscPbcRequest(WifiP2pDevice peer) {
109655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
109755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
109855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
109955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
110055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
110155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
110255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
110355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
110455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
110555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1106ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                                if (DBG) logd(getName() + " wps_pbc");
110755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                sendMessage(WifiP2pManager.WPS_PBC);
110855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
110955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
111055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), null)
111155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
111255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
111355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        pin.setVisibility(View.GONE);
111455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
111555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        peer.deviceAddress));
111655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
111755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
111855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
111955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
112055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
112155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pProvDiscPinRequest(WifiP2pDevice peer) {
112255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
112355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
112455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
112555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
112655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
112755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
112855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
112955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
113055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
113155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    public void onClick(DialogInterface dialog, int which) {
1132ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd(getName() + " wps_pin");
113355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        sendMessage(WifiP2pManager.WPS_PIN, pin.getText().toString());
113455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
113555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
113655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), null)
113755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
113855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
113955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.setMessage(r.getString(R.string.wifi_p2p_pin_go_negotiation_request_message,
114055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        peer.deviceAddress));
114155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
114255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
114355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
114455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
114555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
114655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pInvitationReceived(WifiP2pGroup group) {
114755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mSavedP2pGroup = group;
114855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
114955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
115055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
115155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
115255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
115355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
115455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
115555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
115655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
115755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
115855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                WifiP2pConfig config = new WifiP2pConfig();
115955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress;
1160ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                                if (DBG) logd(getName() + " connect to invited group");
116155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                sendMessage(WifiP2pManager.CONNECT, config);
116255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                mSavedP2pGroup = null;
116355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
116455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
116555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), null)
116655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
116755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
116855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        pin.setVisibility(View.GONE);
116955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
117055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        group.getOwner().deviceAddress));
117155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
117255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
117355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
117455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
117555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
117655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void updateDeviceStatus(String deviceAddress, Status status) {
117755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        for (WifiP2pDevice d : mPeers.getDeviceList()) {
11788c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (d.deviceAddress.equals(deviceAddress)) {
117955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                d.status = status;
118055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
118155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
118255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
11838c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
11844be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    private boolean isGroupOwner(String deviceAddress) {
11854be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        for (WifiP2pDevice d : mPeers.getDeviceList()) {
11864be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            if (d.deviceAddress.equals(deviceAddress)) {
11874be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff                return d.isGroupOwner();
11884be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff            }
11894be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        }
11904be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        return false;
11914be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff    }
11924be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
1193ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //TODO: implement when wpa_supplicant is fixed
1194ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private int configuredNetworkId(String deviceAddress) {
1195ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return -1;
1196ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1197ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1198ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
1199ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = true;
1200ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
1201ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = NetworkUtils.numericToInetAddress(serverAddress);
1202ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1203ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1204ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupTermination() {
1205ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = false;
1206ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = false;
1207ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = null;
1208ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1209ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
12108c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    private String getDeviceAddress(String interfaceAddress) {
12118c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        for (WifiP2pDevice d : mPeers.getDeviceList()) {
12128c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (interfaceAddress.equals(WifiNative.p2pGetInterfaceAddress(d.deviceAddress))) {
12138c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                return d.deviceAddress;
12148c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            }
12158c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        }
12168c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return null;
12178c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
12188c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
12199322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    private void initializeP2pSettings() {
12209322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        WifiNative.setPersistentReconnect(true);
12219322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        WifiNative.setDeviceName(mDeviceName);
12229322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff        WifiNative.setDeviceType(mDeviceType);
12234be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff
12244be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        mDeviceAddress = WifiNative.p2pGetDeviceAddress();
12254be4d31f34a0fd0e23de1cbda311c07412f8d0b8Irfan Sheriff        if (DBG) Slog.d(TAG, "DeviceAddress: " + mDeviceAddress);
12269322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff    }
12279322687d98ec425da03cc10ab64ea19ad7fe2d69Irfan Sheriff
1228ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //State machine initiated requests can have replyTo set to null indicating
1229ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //there are no recepients, we ignore those reply actions
1230ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what) {
1231ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
1232ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mReplyChannel.replyToMessage(msg, what);
1233ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1234ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1235f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    private void replyToMessage(Message msg, int what, int arg1) {
1236f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff        if (msg.replyTo == null) return;
1237f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff        mReplyChannel.replyToMessage(msg, what, arg1);
1238f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff    }
1239f0ef26af3430b9c6402a34eeb9248f805d570922Irfan Sheriff
1240ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what, Object obj) {
1241ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
1242ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mReplyChannel.replyToMessage(msg, what, obj);
1243ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1244ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1245ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void logd(String s) {
1246ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.d(TAG, s);
1247ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1248ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1249ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void loge(String s) {
1250ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.e(TAG, s);
1251ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1252ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1253daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    private void showNotification() {
1254daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        NotificationManager notificationManager =
1255daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1256daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        if (notificationManager == null || mNotification != null) {
1257daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            return;
1258daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        }
1259daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1260daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
1261daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
1262daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1263daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
1264daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1265daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        Resources r = Resources.getSystem();
1266daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        CharSequence title = r.getText(R.string.wifi_p2p_enabled_notification_title);
1267daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        CharSequence message = r.getText(R.string.wifi_p2p_enabled_notification_message);
1268daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1269daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification = new Notification();
1270daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification.when = 0;
1271daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        //TODO: might change to be a seperate icon
1272daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification.icon = R.drawable.stat_sys_tether_wifi;
1273daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification.defaults &= ~Notification.DEFAULT_SOUND;
1274daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification.flags = Notification.FLAG_ONGOING_EVENT;
1275daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification.tickerText = title;
1276daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        mNotification.setLatestEventInfo(mContext, title, message, pi);
1277daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1278daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        notificationManager.notify(mNotification.icon, mNotification);
1279daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    }
1280daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1281daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    private void clearNotification() {
1282daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        NotificationManager notificationManager =
1283daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1284daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        if (notificationManager != null && mNotification != null) {
1285daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            notificationManager.cancel(mNotification.icon);
1286daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff            mNotification = null;
1287daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff        }
1288daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff    }
1289daf57e5ff495684f93d9ac2f5c5fc826a02f5f7aIrfan Sheriff
1290295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff    private boolean isAirplaneSensitive() {
1291295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff        String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
1292295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                Settings.System.AIRPLANE_MODE_RADIOS);
1293295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff        return airplaneModeRadios == null
1294295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff            || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
1295295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff    }
1296295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff
1297295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff    private boolean isAirplaneModeOn() {
1298295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff        return isAirplaneSensitive() && Settings.System.getInt(mContext.getContentResolver(),
1299295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff                Settings.System.AIRPLANE_MODE_ON, 0) == 1;
1300295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff    }
1301295da73f051e1a1280284d94d800c57f163a3986Irfan Sheriff
130255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
130355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync}
1304