WifiP2pService.java revision ea5b16ac5751022de73e8f1225407eb01e7f1824
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;
2055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.BroadcastReceiver;
2155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.Context;
2255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.DialogInterface;
2355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.DialogInterface.OnClickListener;
2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.Intent;
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.IntentFilter;
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.pm.PackageManager;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.content.res.Resources;
28aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.IConnectivityManager;
29aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.ConnectivityManager;
30aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.DhcpInfoInternal;
31aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.DhcpStateMachine;
32aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.InterfaceConfiguration;
33aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.LinkAddress;
34aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.LinkProperties;
35aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.NetworkInfo;
36aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport android.net.NetworkUtils;
3755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiManager;
3855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiMonitor;
3955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiNative;
4055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WifiStateMachine;
4155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WpsConfiguration;
4255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.WpsConfiguration.Setup;
4355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pDevice.Status;
4455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Binder;
4555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.IBinder;
46cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.INetworkManagementService;
4755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Handler;
4855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.HandlerThread;
4955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Message;
50f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport android.os.Messenger;
51cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.ServiceManager;
52cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriffimport android.os.SystemProperties;
5355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Slog;
5455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.LayoutInflater;
5555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.View;
5655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.view.WindowManager;
5755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.widget.EditText;
5855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
59f6d09845be2d58b1de7af9f6edc8b9ee216520a5Irfan Sheriffimport com.android.internal.R;
6055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.AsyncChannel;
6155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.Protocol;
6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.State;
6355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.StateMachine;
6455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
65aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.FileDescriptor;
66aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.io.PrintWriter;
67aea743aaa43a833fd8ff3dc56205197583152d5frepo syncimport java.util.Collection;
68aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
6955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/**
7055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * WifiP2pService inclues a state machine to perform Wi-Fi p2p operations. Applications
7155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * communicate with this service to issue device discovery and connectivity requests
7255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * through the WifiP2pManager interface. The state machine communicates with the wifi
7355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * driver through wpa_supplicant and handles the event responses through WifiMonitor.
7455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
7555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Note that the term Wifi when used without a p2p suffix refers to the client mode
7655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * of Wifi operation
7755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * @hide
7855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
7955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpublic class WifiP2pService extends IWifiP2pManager.Stub {
8055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TAG = "WifiP2pService";
8155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final boolean DBG = true;
82aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private static final String NETWORKTYPE = "WIFI_P2P";
8355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private Context mContext;
85cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    private String mInterface;
86cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
87cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    INetworkManagementService mNwService;
88aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private DhcpStateMachine mDhcpStateMachine;
8955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
90aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    //Tracked to notify the user about wifi client/hotspot being shut down
91aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    //during p2p bring up
9255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private int mWifiState = WifiManager.WIFI_STATE_DISABLED;
9355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private int mWifiApState = WifiManager.WIFI_AP_STATE_DISABLED;
9455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
9555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private P2pStateMachine mP2pStateMachine;
96ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private AsyncChannel mReplyChannel = new AsyncChannel();
9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private AsyncChannel mWifiChannel;
9855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
99ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /* Two minutes comes from the wpa_supplicant setting */
100ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int GROUP_NEGOTIATION_WAIT_TIME_MS = 120 * 1000;
101aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private static int mGroupNegotiationTimeoutIndex = 0;
102aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
103ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /**
104ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     * Delay between restarts upon failure to setup connection with supplicant
105ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     */
106ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int P2P_RESTART_INTERVAL_MSECS = 5000;
107ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
108ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    /**
109ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     * Number of times we attempt to restart p2p
110ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff     */
111ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private static final int P2P_RESTART_TRIES = 5;
112ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
113ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private int mP2pRestartCount = 0;
114ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
11555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
11655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
11755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Message sent to WifiStateMachine to indicate p2p enable is pending */
11855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_ENABLE_PENDING              =   BASE + 1;
11955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Message sent to WifiStateMachine to indicate Wi-Fi client/hotspot operation can proceed */
12055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int WIFI_ENABLE_PROCEED             =   BASE + 2;
12155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
122aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    /* Delayed message to timeout of group negotiation */
123aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    public static final int GROUP_NEGOTIATION_TIMED_OUT     =   BASE + 3;
124aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
12555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* User accepted to disable Wi-Fi in order to enable p2p */
12655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int WIFI_DISABLE_USER_ACCEPT       =   BASE + 11;
12755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
12855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final boolean mP2pSupported;
12955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
130aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private NetworkInfo mNetworkInfo;
131aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
13255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pService(Context context) {
13355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext = context;
13455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
135cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mInterface = SystemProperties.get("wifi.interface", "wlan0");
136aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
137aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
13855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pSupported = mContext.getResources().getBoolean(
13955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                com.android.internal.R.bool.config_wifi_p2p_support);
14055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
14155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
14255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mP2pStateMachine.start();
14355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
14455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // broadcasts
14555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        IntentFilter filter = new IntentFilter();
14655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
14755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
14855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.registerReceiver(new WifiStateReceiver(), filter);
14955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
150aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
15155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
152cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    public void connectivityServiceReady() {
153cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
154cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        mNwService = INetworkManagementService.Stub.asInterface(b);
155cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    }
156cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
15755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class WifiStateReceiver extends BroadcastReceiver {
15855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
15955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void onReceive(Context context, Intent intent) {
16055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
16155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
16255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        WifiManager.WIFI_STATE_DISABLED);
16355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (intent.getAction().equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
16455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mWifiApState = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,
16555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        WifiManager.WIFI_AP_STATE_DISABLED);
16655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
16755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
16855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
16955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceAccessPermission() {
17155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
17255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
17355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
17455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void enforceChangePermission() {
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                "WifiP2pService");
17855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
17955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
18155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Get a reference to handler. This is used by a client to establish
18255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * an AsyncChannel communication with WifiP2pService
18355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
18455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public Messenger getMessenger() {
18555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceAccessPermission();
18655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceChangePermission();
18755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return new Messenger(mP2pStateMachine.getHandler());
18855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
18955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
19155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Return if p2p is supported
19255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
19355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public boolean isP2pSupported() {
19455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        enforceAccessPermission();
19555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return mP2pSupported;
19655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
19755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    @Override
19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
20155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                != PackageManager.PERMISSION_GRANTED) {
20255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + Binder.getCallingPid()
20455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    + ", uid=" + Binder.getCallingUid());
20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return;
20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
20855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
21155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Handles interaction with WifiStateMachine
21255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
21355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private class P2pStateMachine extends StateMachine {
21455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private DefaultState mDefaultState = new DefaultState();
21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
219ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        private WaitForUserActionState mWaitForUserActionState = new WaitForUserActionState();
22055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WaitForWifiDisableState mWaitForWifiDisableState = new WaitForWifiDisableState();
22155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
22255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Inactive is when p2p is enabled with no connectivity
22455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private InactiveState mInactiveState = new InactiveState();
22555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
22655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
22755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
22855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiMonitor mWifiMonitor = new WifiMonitor(this);
22955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
231ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
23255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mGroup;
23355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pConfig from GO negotiation request
23555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pConfig mSavedGoNegotiationConfig;
23655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pConfig from connect request
23855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pConfig mSavedConnectConfig;
23955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
24055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        // Saved WifiP2pGroup from invitation request
24155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private WifiP2pGroup mSavedP2pGroup;
24255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
24355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        P2pStateMachine(String name, boolean p2pSupported) {
24455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            super(name);
24555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
24655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            addState(mDefaultState);
24755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pNotSupportedState, mDefaultState);
24855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisablingState, mDefaultState);
24955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pDisabledState, mDefaultState);
250ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    addState(mWaitForUserActionState, mP2pDisabledState);
251ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    addState(mWaitForWifiDisableState, mP2pDisabledState);
25255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnablingState, mDefaultState);
25355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                addState(mP2pEnabledState, mDefaultState);
25455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mInactiveState, mP2pEnabledState);
25555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupNegotiationState, mP2pEnabledState);
25655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    addState(mGroupCreatedState, mP2pEnabledState);
25755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
25855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (p2pSupported) {
25955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pDisabledState);
26055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else {
26155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                setInitialState(mP2pNotSupportedState);
26255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
26355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
26455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
26555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class DefaultState extends State {
26655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
26755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
268ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
26955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
27055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
27155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
272ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Full connection with WifiStateMachine established");
27355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = (AsyncChannel) message.obj;
27455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
275ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Full connection failure, error = " + message.arg1);
27655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel = null;
27755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
27855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
27955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
28155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
282ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Send failed, client connection lost");
28355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
284ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Client connection lost with reason: " + message.arg1);
28555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
28655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel = null;
28755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
28855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
29055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    AsyncChannel ac = new AsyncChannel();
29155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    ac.connect(mContext, getHandler(), message.replyTo);
29255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
29355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiStateMachine.WIFI_ENABLE_PENDING:
29455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // Disable p2p operation before we can respond
29555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.DISABLE_P2P);
29655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
29755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.ENABLE_P2P:
299ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED);
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
302ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED);
30355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
30455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
305ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
30755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
308ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
311ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
314ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REQUEST_PEERS:
317ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
318ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
319ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REQUEST_CONNECTION_INFO:
320ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO, mWifiP2pInfo);
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
32255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // Ignore
32355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WIFI_DISABLE_USER_ACCEPT:
324aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case GROUP_NEGOTIATION_TIMED_OUT:
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
327ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Unhandled message " + message);
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
33055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
33155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
33255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
33355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pNotSupportedState extends State {
33555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
33655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
33755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
33855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // Allow Wi-Fi to proceed
33955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiStateMachine.WIFI_ENABLE_PENDING:
340ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WIFI_ENABLE_PROCEED);
34155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.ENABLE_P2P:
343ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED,
34455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
34555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
34655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
347ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED,
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            WifiP2pManager.P2P_UNSUPPORTED);
34955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
350ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISCOVER_PEERS:
351ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
352ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
353ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
354ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CONNECT:
355ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
356ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
357ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
358ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.CREATE_GROUP:
359ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
360ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
361ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
362ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.REMOVE_GROUP:
363ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
364ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            WifiP2pManager.P2P_UNSUPPORTED);
365ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
366ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff               default:
36755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
36855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
36955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
37055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
37155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
37255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
37355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisablingState extends State {
37455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
37555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
376ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
377ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            logd("stopping supplicant");
378ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (!WifiNative.stopSupplicant()) {
379ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                loge("Failed to stop supplicant, issue kill");
380ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                WifiNative.killSupplicant();
381ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            }
38255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
38355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
38555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
386ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
38755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
38855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_DISCONNECTION_EVENT:
389ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("Supplicant connection lost");
390ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    WifiNative.closeSupplicantConnection();
39155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisabledState);
39255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
393ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
394ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
395ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
396ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
39755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
39955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
40055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
40155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
40255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
40355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
40455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
40555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pDisabledState extends State {
40655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       @Override
40755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
408ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
40955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
41055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
41155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
41255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
413ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
41455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
41555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.ENABLE_P2P:
41655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    OnClickListener listener = new OnClickListener() {
41755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        @Override
41855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
41955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            if (which == DialogInterface.BUTTON_POSITIVE) {
42055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                sendMessage(WIFI_DISABLE_USER_ACCEPT);
42155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            } else {
422ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                                logd("User rejected enabling p2p");
423ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                                //ignore
42455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            }
42555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    };
42755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
42855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // Show a user request dialog if we know Wi-Fi client/hotspot is in operation
42955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mWifiState != WifiManager.WIFI_STATE_DISABLED ||
43055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED) {
43155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        Resources r = Resources.getSystem();
43255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        AlertDialog dialog = new AlertDialog.Builder(mContext)
43355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
43455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setMessage(r.getString(R.string.wifi_p2p_turnon_message))
43555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setPositiveButton(r.getString(R.string.ok), listener)
43655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .setNegativeButton(r.getString(R.string.cancel), listener)
43755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            .create();
43855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
43955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        dialog.show();
440ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        transitionTo(mWaitForUserActionState);
44155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
44255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiChannel.sendMessage(P2P_ENABLE_PENDING);
44355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        transitionTo(mWaitForWifiDisableState);
44455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
445ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED);
44655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
447ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
448ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED);
449ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
450ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiStateMachine.WIFI_ENABLE_PENDING:
451ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WIFI_ENABLE_PROCEED);
452ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
453ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
454ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    return NOT_HANDLED;
455ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            }
456ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            return HANDLED;
457ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
458ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
459ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
460ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    class WaitForUserActionState extends State {
461ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        @Override
462ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        public void enter() {
463ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
464ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        }
465ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
466ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        @Override
467ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        public boolean processMessage(Message message) {
468ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
469ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            switch (message.what) {
47055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WIFI_DISABLE_USER_ACCEPT:
47155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mWifiChannel.sendMessage(P2P_ENABLE_PENDING);
47255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mWaitForWifiDisableState);
47355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
474ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
475ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
476ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
47755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
47855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
47955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
48055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
48155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
48255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
48355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
48455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
48555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class WaitForWifiDisableState extends State {
48655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
48755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
488ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
48955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
49055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
49155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
49255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
493ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
49455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
49555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiStateMachine.P2P_ENABLE_PROCEED:
496cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    try {
497cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        mNwService.wifiFirmwareReload(mInterface, "P2P");
498cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    } catch (Exception e) {
499ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Failed to reload p2p firmware " + e);
500cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                        // continue
501cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    }
502ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
503ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    //A runtime crash can leave the interface up and
504ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    //this affects p2p when supplicant starts up.
505ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    //Ensure interface is down before a supplicant start.
506ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    try {
507ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        mNwService.setInterfaceDown(mInterface);
508ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } catch (Exception e) {
509ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) Slog.w(TAG, "Unable to bring down wlan interface: " + e);
510ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
511ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
512cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff                    if (WifiNative.startSupplicant()) {
51355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mWifiMonitor.startMonitoring();
51455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        transitionTo(mP2pEnablingState);
51555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
51655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        notifyP2pEnableFailure();
51755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        transitionTo(mP2pDisabledState);
51855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
51955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
520ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
521ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
522ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
523ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
52455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
52555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
52655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
52755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
52855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
52955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
53055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
53155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnablingState extends State {
53255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
53355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
534ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
53555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
53655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
53755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
53855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
539ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
54055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
54155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.SUP_CONNECTION_EVENT:
542ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("P2p start successful");
54355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
54455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
545ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:
546ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (++mP2pRestartCount <= P2P_RESTART_TRIES) {
547ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Failed to start p2p, retry");
548ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        WifiNative.killSupplicant();
549ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
550ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
551ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        loge("Failed " + mP2pRestartCount + " times to start p2p, quit ");
552ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        mP2pRestartCount = 0;
553ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
554aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    transitionTo(mP2pDisabledState);
555ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
556ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
557ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.DISABLE_P2P:
558ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    deferMessage(message);
559ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
56055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
56155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
56255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
56355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
56455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
56555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
56655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
56755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class P2pEnabledState extends State {
56855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
56955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
570ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
57155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(true);
572aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(true);
573ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            //Start listening for new connections
574ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            WifiNative.p2pListen();
57555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
57655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
57855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
579ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
58055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
581ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiP2pManager.ENABLE_P2P:
582ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED);
583ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    break;
58455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
585ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
586ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED);
58755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mP2pDisablingState);
58855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
58955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISCOVER_PEERS:
59055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    int timeout = message.arg1;
591ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pFind(timeout)) {
592ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
593ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
594ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
595ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
59655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
59755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
59855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
59955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mPeers.add(device);
60055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
60155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
60255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
60355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    device = (WifiP2pDevice) message.obj;
60455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
60555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
60655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
607ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " sending connect");
60855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSavedConnectConfig = (WifiP2pConfig) message.obj;
609ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    int netId = configuredNetworkId(mSavedConnectConfig.deviceAddress);
610ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (netId >= 0) {
611ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        //TODO: if failure, remove config and do a regular p2pConnect()
612ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        WifiNative.p2pReinvoke(netId, mSavedConnectConfig.deviceAddress);
613ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
614ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        //TODO: Check if device is a GO and "join"
615ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        String pin = WifiNative.p2pConnect(mSavedConnectConfig, false);
616ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        try {
617ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            Integer.parseInt(pin);
618ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            notifyWpsPin(pin, mSavedConnectConfig.deviceAddress);
619ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        } catch (NumberFormatException ignore) {
620ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            // do nothing if p2pConnect did not return a pin
621ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        }
62255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
62355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.INVITED);
62455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
625ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
62655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mGroupNegotiationState);
62755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
628ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant died */
629ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    loge("Connection lost, restart p2p");
630ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    WifiNative.killSupplicant();
631ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    WifiNative.closeSupplicantConnection();
632ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
633ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    transitionTo(mP2pDisabledState);
634ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
63555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
63655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
63755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
63855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
63955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
64055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
64155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
64255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void exit() {
64355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            sendP2pStateChangedBroadcast(false);
644aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setIsAvailable(false);
64555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
64655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
64755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
64855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class InactiveState extends State {
64955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override public void enter() {
650ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
65155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
65255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
65355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
65455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
655ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
65655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
65755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
65855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSavedGoNegotiationConfig = (WifiP2pConfig) message.obj;
65955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig);
66055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
66155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CREATE_GROUP:
662ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pGroupAdd()) {
663ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
664ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
665ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
666ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
66755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mGroupNegotiationState);
66855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
66955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
67055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
67155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pInvitationReceived(group);
67255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
673ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                default:
67455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
67555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
67655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
67755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
67855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
67955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
68055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupNegotiationState extends State {
681aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        @Override
682aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void enter() {
683ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
684aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            sendMessageDelayed(obtainMessage(GROUP_NEGOTIATION_TIMED_OUT,
685aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    ++mGroupNegotiationTimeoutIndex, 0), GROUP_NEGOTIATION_WAIT_TIME_MS);
68655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
68755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
68855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
68955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
690ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
69155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
69255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // We ignore these right now, since we get a GROUP_STARTED notification
69355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                // afterwards
69455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
69555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
696ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go success");
69755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
69855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
69955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
700ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " go failure");
70155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
70255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mSavedConnectConfig = null;
703ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    sendP2pPeersChangedBroadcast();
70455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
70555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
70655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
70755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mGroup = (WifiP2pGroup) message.obj;
708ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " group started");
709aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    if (mGroup.isGroupOwner()) {
710aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        startDhcpServer(mGroup.getInterface());
711aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    } else {
712aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
713aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                                P2pStateMachine.this, mGroup.getInterface());
714aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
71555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        WifiP2pDevice groupOwner = mGroup.getOwner();
71655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        updateDeviceStatus(groupOwner.deviceAddress, Status.CONNECTED);
71755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        sendP2pPeersChangedBroadcast();
71855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
71955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mGroupCreatedState);
72055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
721aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case GROUP_NEGOTIATION_TIMED_OUT:
722aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    if (mGroupNegotiationTimeoutIndex == message.arg1) {
723ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Group negotiation timed out");
724aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
725aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mSavedConnectConfig = null;
726ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendP2pPeersChangedBroadcast();
727aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        transitionTo(mInactiveState);
728aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
729aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
73055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
73155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
73255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
73355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
73455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
73555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
73655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
73755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    class GroupCreatedState extends State {
73855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
73955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public void enter() {
740ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName());
741aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
74255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
74355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
74455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        @Override
74555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        public boolean processMessage(Message message) {
746ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            if (DBG) logd(getName() + message.toString());
74755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            switch (message.what) {
74855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_CONNECTED_EVENT:
7498c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    //After a GO setup, STA connected event comes with interface address
7508c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    String interfaceAddress = (String) message.obj;
7518c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    String deviceAddress = getDeviceAddress(interfaceAddress);
7528c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    mGroup.addClient(deviceAddress);
7538c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    updateDeviceStatus(deviceAddress, Status.CONNECTED);
754ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) logd(getName() + " ap sta connected");
75555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendP2pPeersChangedBroadcast();
75655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
75755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
7588c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    interfaceAddress = (String) message.obj;
7598c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    deviceAddress = getDeviceAddress(interfaceAddress);
7608c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    updateDeviceStatus(deviceAddress, Status.AVAILABLE);
7618c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                    if (mGroup.removeClient(deviceAddress)) {
762ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Removed client " + deviceAddress);
763ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendP2pPeersChangedBroadcast();
76455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else {
765ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("Failed to remove client " + deviceAddress);
76655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        for (WifiP2pDevice c : mGroup.getClientList()) {
767ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            if (DBG) logd("client " + c.deviceAddress);
76855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
76955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
770ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " ap sta disconnected");
77155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
772aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
773aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
774ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
775ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            dhcpInfo != null) {
776ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("DhcpInfo: " + dhcpInfo);
777ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
778aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        sendP2pConnectionChangedBroadcast();
779ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
780ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        WifiNative.p2pGroupRemove(mGroup.getInterface());
781aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
782aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    break;
78355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.REMOVE_GROUP:
784ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " remove group");
785ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pGroupRemove(mGroup.getInterface())) {
786ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
787ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
788ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
789ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
79055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
79155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
792ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (DBG) loge(getName() + " group removed");
79355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    Collection <WifiP2pDevice> devices = mGroup.getClientList();
79455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    boolean changed = false;
79555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    for (WifiP2pDevice d : mPeers.getDeviceList()) {
79655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        if (devices.contains(d) || mGroup.getOwner().equals(d)) {
79755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            d.status = Status.AVAILABLE;
79855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            changed = true;
79955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
80055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
801aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
802aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    if (mGroup.isGroupOwner()) {
803aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        stopDhcpServer();
804aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    } else {
805ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd("stop DHCP client");
806aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
807aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine.quit();
808aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mDhcpStateMachine = null;
809aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    }
810aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
81155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mGroup = null;
81255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (changed) sendP2pPeersChangedBroadcast();
81355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    transitionTo(mInactiveState);
81455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
81555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
81655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
81755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (device.equals(mGroup.getOwner())) {
818ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        logd("Lost the group owner, killing p2p connection");
819aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        WifiNative.p2pGroupRemove(mGroup.getInterface());
820ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
821ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        mGroup.removeClient(device);
82255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
82355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED; // Do the regular device lost handling
82455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.DISABLE_P2P:
82555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    sendMessage(WifiP2pManager.REMOVE_GROUP);
82655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    deferMessage(message);
82755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
82855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.CONNECT:
82955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
830ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("Inviting device : " + config.deviceAddress);
831ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    if (WifiNative.p2pInvite(mGroup, config.deviceAddress)) {
832ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        updateDeviceStatus(config.deviceAddress, Status.INVITED);
833ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        sendP2pPeersChangedBroadcast();
834ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
835ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    } else {
836ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
837ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    }
83855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    // TODO: figure out updating the status to declined when invitation is rejected
83955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
84055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
841ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                    logd("===> INVITATION RESULT EVENT : " + message.obj);
84255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
84355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
84455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pProvDiscPbcRequest((WifiP2pDevice) message.obj);
84555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
84655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
84755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    notifyP2pProvDiscPinRequest((WifiP2pDevice) message.obj);
84855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
84955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.WPS_PBC:
8502b8edd0c485f74067605c19983e3e7f44b20ec50repo sync                    WifiNative.wpsPbc();
85155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
85255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                case WifiP2pManager.WPS_PIN:
8532b8edd0c485f74067605c19983e3e7f44b20ec50repo sync                    WifiNative.wpsPin((String) message.obj);
85455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    break;
85555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                default:
85655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    return NOT_HANDLED;
85755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
85855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return HANDLED;
85955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
860aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
861aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        public void exit() {
862ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            setWifiP2pInfoOnGroupTermination();
863aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
864ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            sendP2pConnectionChangedBroadcast();
865aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
86655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
86755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
86855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pStateChangedBroadcast(boolean enabled) {
86955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
87055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
87155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (enabled) {
87255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
87355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
87455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
87555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
87655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
87755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
87855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.sendStickyBroadcast(intent);
87955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
88055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
88155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void sendP2pPeersChangedBroadcast() {
88255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
88355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
88455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mContext.sendBroadcast(intent);
88555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
88655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
887aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void sendP2pConnectionChangedBroadcast() {
888ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (DBG) logd("sending p2p connection changed broadcast");
889aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
890aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
891aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
892ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
893aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
894aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        mContext.sendStickyBroadcast(intent);
895aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
896aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
897aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void startDhcpServer(String intf) {
898aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        /* Is chosen as a unique range to avoid conflict with
899aea743aaa43a833fd8ff3dc56205197583152d5frepo sync           the range defined in Tethering.java */
900aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        String[] dhcp_range = {"192.168.49.2", "192.168.49.254"};
901aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        String serverAddress = "192.168.49.1";
902aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
903aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        InterfaceConfiguration ifcg = null;
904aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
905aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg = mNwService.getInterfaceConfig(intf);
906aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
907aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        serverAddress), 24);
908aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            ifcg.interfaceFlags = "[up]";
909aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.setInterfaceConfig(intf, ifcg);
910aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            /* This starts the dnsmasq server */
911aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.startTethering(dhcp_range);
912aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
913ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error configuring interface " + intf + ", :" + e);
914aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
915aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
916aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
917ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Started Dhcp server on " + intf);
918ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
919ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        setWifiP2pInfoOnGroupFormation(serverAddress);
920ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        sendP2pConnectionChangedBroadcast();
921aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
922aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
923aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    private void stopDhcpServer() {
924aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        try {
925aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            mNwService.stopTethering();
926aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } catch (Exception e) {
927ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff            loge("Error stopping Dhcp server" + e);
928aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            return;
929aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
930aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
931ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        logd("Stopped Dhcp server");
932aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    }
933aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
93455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pEnableFailure() {
93555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
93655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
93755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
93855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
93955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
94055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
94155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
94255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
94355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
94455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
94555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyWpsPin(String pin, String peerAddress) {
94655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
94755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
94855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
94955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setMessage(r.getString(R.string.wifi_p2p_pin_display_message, pin, peerAddress))
95055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), null)
95155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
95255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
95355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
95455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
95555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
95655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pGoNegotationRequest(WifiP2pConfig config) {
95755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
95855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        WpsConfiguration wpsConfig = config.wpsConfig;
95955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
96055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
96155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
96255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
96355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
96455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
96555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
96655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
96755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
968ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            if (DBG) logd(getName() + " connect " + pin.getText());
969aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
970aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            if (pin.getVisibility() == View.GONE) {
971aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                                mSavedGoNegotiationConfig.wpsConfig.setup = Setup.PBC;
972aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            } else {
97355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                mSavedGoNegotiationConfig.wpsConfig.setup = Setup.KEYPAD;
97455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                mSavedGoNegotiationConfig.wpsConfig.pin = pin.getText().toString();
975aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            }
976aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
977aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                            mSavedGoNegotiationConfig = null;
97855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
97955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
98055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
98155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        @Override
98255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
983ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            if (DBG) logd(getName() + " ignore connect");
984ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                            mSavedGoNegotiationConfig = null;
98555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
98655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
98755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
98855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
98955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (wpsConfig.setup == Setup.PBC) {
99055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            pin.setVisibility(View.GONE);
99155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
99255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        config.deviceAddress));
99355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
99455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            dialog.setMessage(r.getString(R.string.wifi_p2p_pin_go_negotiation_request_message,
99555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        config.deviceAddress));
99655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
99755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
99855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
99955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
100055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
100155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
100255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pProvDiscPbcRequest(WifiP2pDevice peer) {
100355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
100455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
100555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
100655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
100755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
100855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
100955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
101055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
101155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
101255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
1013ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                                if (DBG) logd(getName() + " wps_pbc");
101455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                sendMessage(WifiP2pManager.WPS_PBC);
101555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
101655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
101755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), null)
101855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
101955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
102055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        pin.setVisibility(View.GONE);
102155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
102255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        peer.deviceAddress));
102355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
102455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
102555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
102655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
102755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
102855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pProvDiscPinRequest(WifiP2pDevice peer) {
102955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
103055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
103155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
103255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
103355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
103455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
103555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
103655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
103755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
103855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    public void onClick(DialogInterface dialog, int which) {
1039ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                        if (DBG) logd(getName() + " wps_pin");
104055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        sendMessage(WifiP2pManager.WPS_PIN, pin.getText().toString());
104155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    }
104255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
104355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), null)
104455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
104555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
104655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.setMessage(r.getString(R.string.wifi_p2p_pin_go_negotiation_request_message,
104755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        peer.deviceAddress));
104855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
104955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
105055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
105155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
105255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
105355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void notifyP2pInvitationReceived(WifiP2pGroup group) {
105455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mSavedP2pGroup = group;
105555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        Resources r = Resources.getSystem();
105655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final View textEntryView = LayoutInflater.from(mContext)
105755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
105855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
105955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
106055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        AlertDialog dialog = new AlertDialog.Builder(mContext)
106155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
106255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setView(textEntryView)
106355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
106455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        public void onClick(DialogInterface dialog, int which) {
106555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                WifiP2pConfig config = new WifiP2pConfig();
106655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress;
1067ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff                                if (DBG) logd(getName() + " connect to invited group");
106855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                sendMessage(WifiP2pManager.CONNECT, config);
106955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                                mSavedP2pGroup = null;
107055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        }
107155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    })
107255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .setNegativeButton(r.getString(R.string.cancel), null)
107355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            .create();
107455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
107555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        pin.setVisibility(View.GONE);
107655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
107755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        group.getOwner().deviceAddress));
107855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
107955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
108055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dialog.show();
108155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
108255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
108355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private void updateDeviceStatus(String deviceAddress, Status status) {
108455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        for (WifiP2pDevice d : mPeers.getDeviceList()) {
10858c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (d.deviceAddress.equals(deviceAddress)) {
108655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                d.status = status;
108755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
108855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
108955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
10908c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
1091ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //TODO: implement when wpa_supplicant is fixed
1092ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private int configuredNetworkId(String deviceAddress) {
1093ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        return -1;
1094ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1095ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1096ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
1097ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = true;
1098ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
1099ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = NetworkUtils.numericToInetAddress(serverAddress);
1100ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1101ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1102ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void setWifiP2pInfoOnGroupTermination() {
1103ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupFormed = false;
1104ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.isGroupOwner = false;
1105ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mWifiP2pInfo.groupOwnerAddress = null;
1106ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1107ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
11088c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    private String getDeviceAddress(String interfaceAddress) {
11098c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        for (WifiP2pDevice d : mPeers.getDeviceList()) {
11108c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            if (interfaceAddress.equals(WifiNative.p2pGetInterfaceAddress(d.deviceAddress))) {
11118c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync                return d.deviceAddress;
11128c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync            }
11138c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        }
11148c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return null;
11158c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync    }
11168c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync
1117ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //State machine initiated requests can have replyTo set to null indicating
1118ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    //there are no recepients, we ignore those reply actions
1119ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what) {
1120ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
1121ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mReplyChannel.replyToMessage(msg, what);
1122ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1123ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1124ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void replyToMessage(Message msg, int what, Object obj) {
1125ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        if (msg.replyTo == null) return;
1126ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        mReplyChannel.replyToMessage(msg, what, obj);
1127ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1128ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1129ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void logd(String s) {
1130ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.d(TAG, s);
1131ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1132ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
1133ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    private void loge(String s) {
1134ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff        Slog.e(TAG, s);
1135ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff    }
1136ea5b16ac5751022de73e8f1225407eb01e7f1824Irfan Sheriff
113755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
113855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync}
1139