1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/*
2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2011 The Android Open Source Project
3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License");
5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License.
6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at
7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *      http://www.apache.org/licenses/LICENSE-2.0
9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software
11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS,
12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and
14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License.
15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi.p2p;
18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
19155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.app.AlertDialog;
20155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context;
21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.DialogInterface;
22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.DialogInterface.OnClickListener;
23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Intent;
24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.pm.PackageManager;
25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.res.Configuration;
26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.res.Resources;
27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.ConnectivityManager;
28155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.DhcpResults;
29155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.InterfaceConfiguration;
30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.LinkAddress;
319ed1f7b1a80aae513f3730869b614f66b6c79125Erik Klineimport android.net.LinkProperties;
32155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkInfo;
33155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkUtils;
349ed1f7b1a80aae513f3730869b614f66b6c79125Erik Klineimport android.net.ip.IpManager;
35155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WpsInfo;
36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.IWifiP2pManager;
37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pConfig;
38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pDevice;
39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pDeviceList;
40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pGroup;
41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pGroupList;
42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pGroupList.GroupDeleteListener;
43155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pInfo;
44155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pManager;
45155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pProvDiscEvent;
46155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.WifiP2pWfdInfo;
47155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
48155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
49155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
50155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Binder;
51155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Bundle;
52f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mannimport android.os.Handler;
53f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mannimport android.os.HandlerThread;
54155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.IBinder;
55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.INetworkManagementService;
56f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mannimport android.os.Looper;
57155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Message;
58155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Messenger;
59155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.RemoteException;
60155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.ServiceManager;
61155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.UserHandle;
62155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.provider.Settings;
63155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.text.TextUtils;
64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Slog;
65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.SparseArray;
66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.view.KeyEvent;
67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.view.LayoutInflater;
68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.view.View;
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.view.ViewGroup;
70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.view.WindowManager;
71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.widget.EditText;
72155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.widget.TextView;
73155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
74155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.R;
75155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.AsyncChannel;
76155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.Protocol;
77155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.State;
78155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.internal.util.StateMachine;
79155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.server.wifi.WifiMonitor;
80155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.server.wifi.WifiNative;
81155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport com.android.server.wifi.WifiStateMachine;
82155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
83155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileDescriptor;
84155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.PrintWriter;
85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.net.InetAddress;
86155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
87155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.Collection;
88155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.HashMap;
89155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.List;
90155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WifiP2pService includes a state machine to perform Wi-Fi p2p operations. Applications
94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * communicate with this service to issue device discovery and connectivity requests
95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * through the WifiP2pManager interface. The state machine communicates with the wifi
96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * driver through wpa_supplicant and handles the event responses through WifiMonitor.
97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Note that the term Wifi when used without a p2p suffix refers to the client mode
99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * of Wifi operation
100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * @hide
101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
102eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandepublic class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String TAG = "WifiP2pService";
104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final boolean DBG = false;
105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String NETWORKTYPE = "WIFI_P2P";
106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Context mContext;
108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    INetworkManagementService mNwService;
1109ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private IpManager mIpManager;
1119ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private DhcpResults mDhcpResults;
112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private P2pStateMachine mP2pStateMachine;
114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mReplyChannel = new AsyncChannel();
115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mWifiChannel;
116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean JOIN_GROUP = true;
118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean FORM_GROUP = false;
119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean RELOAD = true;
121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean NO_RELOAD = false;
122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Two minutes comes from the wpa_supplicant setting */
124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static int mGroupCreatingTimeoutIndex = 0;
126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DISABLE_P2P_WAIT_TIME_MS = 5 * 1000;
128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static int mDisableP2pTimeoutIndex = 0;
129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set a two minute discover timeout to avoid STA scans from being blocked */
131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DISCOVER_TIMEOUT_S = 120;
132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Idle time after a peer is gone when the group is torn down */
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int GROUP_IDLE_TIME_S = 10;
135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Delayed message to timeout group creation */
139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 1;
140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User accepted a peer request */
142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 2;
143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User rejected a peer request */
144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 3;
145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User wants to disconnect wifi in favour of p2p */
146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DROP_WIFI_USER_ACCEPT          =   BASE + 4;
147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User wants to keep his wifi connection and drop p2p */
148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DROP_WIFI_USER_REJECT          =   BASE + 5;
149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Delayed message to timeout p2p disable */
150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISABLE_P2P_TIMED_OUT           =   BASE + 6;
151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Commands to the WifiStateMachine */
154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int P2P_CONNECTION_CHANGED          =   BASE + 11;
155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* These commands are used to temporarily disconnect wifi when we detect
157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a frequency conflict which would make it impossible to have with p2p
158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and wifi active at the same time.
159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * If the user chooses to disable wifi temporarily, we keep wifi disconnected
161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * until the p2p connection is done and terminated at which point we will
162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * bring back wifi up
163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DISCONNECT_WIFI_REQUEST
165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *      msg.arg1 = 1 enables temporary disconnect and 0 disables it.
166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISCONNECT_WIFI_REQUEST         =   BASE + 12;
168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISCONNECT_WIFI_RESPONSE        =   BASE + 13;
169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int SET_MIRACAST_MODE               =   BASE + 14;
171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // During dhcp (and perhaps other times) we can't afford to drop packets
173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // but Discovery will switch our channel enough we will.
174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //   msg.arg1 = ENABLED for blocking, DISABLED for resumed.
175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //   msg.arg2 = msg to send when blocked
176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //   msg.obj  = StateMachine to send to when blocked
177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int BLOCK_DISCOVERY                 =   BASE + 15;
178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1799ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    // Messages for interaction with IpManager.
1809ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private static final int IPM_PRE_DHCP_ACTION            =   BASE + 30;
1819ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private static final int IPM_POST_DHCP_ACTION           =   BASE + 31;
1829ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private static final int IPM_DHCP_RESULTS               =   BASE + 32;
1839ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private static final int IPM_PROVISIONING_SUCCESS       =   BASE + 33;
1849ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private static final int IPM_PROVISIONING_FAILURE       =   BASE + 34;
1859ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline
186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int ENABLED                         = 1;
187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISABLED                        = 0;
188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final boolean mP2pSupported;
190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiP2pDevice mThisDevice = new WifiP2pDevice();
192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* When a group has been explicitly created by an app, we persist the group
194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * even after all clients have been disconnected until an explicit remove
195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * is invoked */
196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mAutonomousGroup;
197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Invitation to join an existing p2p group */
199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mJoinExistingGroup;
200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Track whether we are in p2p discovery. This is used to avoid sending duplicate
202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * broadcasts
203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDiscoveryStarted;
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Track whether servcice/peer discovery is blocked in favor of other wifi actions
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * (notably dhcp)
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDiscoveryBlocked;
209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /*
211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * remember if we were in a scan when it had to be stopped
212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDiscoveryPostponed = false;
214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private NetworkInfo mNetworkInfo;
216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2175c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    private boolean mTemporarilyDisconnectedWifi = false;
218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* The transaction Id of service discovery request */
220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private byte mServiceTransactionId = 0;
221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Service discovery request ID of wpa_supplicant.
223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * null means it's not set yet. */
224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mServiceDiscReqId;
225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* clients(application) information list. */
227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2298c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt    /* Is chosen as a unique address to avoid conflict with
2308c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt       the ranges defined in Tethering.java */
231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String SERVER_ADDRESS = "192.168.49.1";
232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Error code definition.
235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * see the Table.8 in the WiFi Direct specification for the detail.
236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static enum P2pStatus {
238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Success. */
239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        SUCCESS,
240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* The target device is currently unavailable. */
242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INFORMATION_IS_CURRENTLY_UNAVAILABLE,
243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Protocol error. */
245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INCOMPATIBLE_PARAMETERS,
246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* The target device reached the limit of the number of the connectable device.
248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * For example, device limit or group limit is set. */
249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        LIMIT_REACHED,
250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Protocol error. */
252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INVALID_PARAMETER,
253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Unable to accommodate request. */
255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        UNABLE_TO_ACCOMMODATE_REQUEST,
256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Previous protocol error, or disruptive behavior. */
258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        PREVIOUS_PROTOCOL_ERROR,
259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* There is no common channels the both devices can use. */
261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        NO_COMMON_CHANNEL,
262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *  but device B has removed the specified credential already. */
265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        UNKNOWN_P2P_GROUP,
266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        BOTH_GO_INTENT_15,
269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Incompatible provisioning method. */
271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INCOMPATIBLE_PROVISIONING_METHOD,
272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Rejected by user */
274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        REJECTED_BY_USER,
275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Unknown error */
277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        UNKNOWN;
278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public static P2pStatus valueOf(int error) {
280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(error) {
281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 0 :
282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return SUCCESS;
283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 1:
284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 2:
286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INCOMPATIBLE_PARAMETERS;
287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 3:
288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return LIMIT_REACHED;
289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 4:
290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INVALID_PARAMETER;
291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 5:
292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return UNABLE_TO_ACCOMMODATE_REQUEST;
293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 6:
294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return PREVIOUS_PROTOCOL_ERROR;
295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 7:
296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return NO_COMMON_CHANNEL;
297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 8:
298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return UNKNOWN_P2P_GROUP;
299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 9:
300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return BOTH_GO_INTENT_15;
301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 10:
302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INCOMPATIBLE_PROVISIONING_METHOD;
303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 11:
304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return REJECTED_BY_USER;
305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return UNKNOWN;
307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
311f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    /**
312f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * Handles client connections
313f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     */
314f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    private class ClientHandler extends Handler {
315f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
316f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        ClientHandler(android.os.Looper looper) {
317f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            super(looper);
318f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        }
319f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
320f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        @Override
321f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        public void handleMessage(Message msg) {
322f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            switch (msg.what) {
323f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.SET_DEVICE_NAME:
324f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.SET_WFD_INFO:
325f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.DISCOVER_PEERS:
326f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.STOP_DISCOVERY:
327f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CONNECT:
328f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CANCEL_CONNECT:
329f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CREATE_GROUP:
330f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REMOVE_GROUP:
331f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.START_LISTEN:
332f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.STOP_LISTEN:
333f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.SET_CHANNEL:
334f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.START_WPS:
335f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.ADD_LOCAL_SERVICE:
336f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REMOVE_LOCAL_SERVICE:
337f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CLEAR_LOCAL_SERVICES:
338f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.DISCOVER_SERVICES:
339f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.ADD_SERVICE_REQUEST:
340f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REMOVE_SERVICE_REQUEST:
341f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
342f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_PEERS:
343f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_CONNECTION_INFO:
344f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_GROUP_INFO:
345f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.DELETE_PERSISTENT_GROUP:
346f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
347f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                mP2pStateMachine.sendMessage(Message.obtain(msg));
348f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                break;
349f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              default:
350f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
351f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                break;
352f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            }
353f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        }
354f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    }
355f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    private ClientHandler mClientHandler;
356f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public WifiP2pServiceImpl(Context context) {
358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext = context;
359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                PackageManager.FEATURE_WIFI_DIRECT);
364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.primaryDeviceType = mContext.getResources().getString(
366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                com.android.internal.R.string.config_wifi_p2p_device_type);
367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
368f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        HandlerThread wifiP2pThread = new HandlerThread("WifiP2pService");
369f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        wifiP2pThread.start();
370f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        mClientHandler = new ClientHandler(wifiP2pThread.getLooper());
371f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
372f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        mP2pStateMachine = new P2pStateMachine(TAG, wifiP2pThread.getLooper(), mP2pSupported);
373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pStateMachine.start();
374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void connectivityServiceReady() {
377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNwService = INetworkManagementService.Stub.asInterface(b);
379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void enforceAccessPermission() {
382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "WifiP2pService");
384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void enforceChangePermission() {
387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "WifiP2pService");
389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void enforceConnectivityInternalPermission() {
392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.enforceCallingOrSelfPermission(
393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                android.Manifest.permission.CONNECTIVITY_INTERNAL,
394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "WifiP2pService");
395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
39707a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    private int checkConnectivityInternalPermission() {
39807a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        return mContext.checkCallingOrSelfPermission(
39907a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel                android.Manifest.permission.CONNECTIVITY_INTERNAL);
40007a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    }
40107a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel
40207a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    private int checkLocationHardwarePermission() {
40307a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        return mContext.checkCallingOrSelfPermission(
40407a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel                android.Manifest.permission.LOCATION_HARDWARE);
40507a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    }
40607a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel
40707a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    private void enforceConnectivityInternalOrLocationHardwarePermission() {
40807a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        if (checkConnectivityInternalPermission() != PackageManager.PERMISSION_GRANTED
40907a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel                && checkLocationHardwarePermission() != PackageManager.PERMISSION_GRANTED) {
41007a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel            enforceConnectivityInternalPermission();
41107a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        }
41207a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    }
41307a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel
4149ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private void stopIpManager() {
4159ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        if (mIpManager != null) {
4169ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline            mIpManager.stop();
4179ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline            mIpManager = null;
4189ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        }
4199ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        mDhcpResults = null;
4209ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    }
4219ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline
4229ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    private void startIpManager(String ifname) {
4239ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        stopIpManager();
4249ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline
4259ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        mIpManager = new IpManager(mContext, ifname,
4269ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                new IpManager.Callback() {
4279ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    @Override
4289ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    public void onPreDhcpAction() {
4299ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        mP2pStateMachine.sendMessage(IPM_PRE_DHCP_ACTION);
4309ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    }
4319ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    @Override
4329ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    public void onPostDhcpAction() {
4339ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        mP2pStateMachine.sendMessage(IPM_POST_DHCP_ACTION);
4349ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    }
4359ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    @Override
4369ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    public void onNewDhcpResults(DhcpResults dhcpResults) {
4379ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        mP2pStateMachine.sendMessage(IPM_DHCP_RESULTS, dhcpResults);
4389ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    }
4399ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    @Override
4409ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    public void onProvisioningSuccess(LinkProperties newLp) {
4419ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        mP2pStateMachine.sendMessage(IPM_PROVISIONING_SUCCESS);
4429ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    }
4439ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    @Override
4449ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    public void onProvisioningFailure(LinkProperties newLp) {
4459ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        mP2pStateMachine.sendMessage(IPM_PROVISIONING_FAILURE);
4469ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    }
4479ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                },
4489ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                mNwService);
4499ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline
4509ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        final IpManager.ProvisioningConfiguration config =
4519ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                mIpManager.buildProvisioningConfiguration()
4529ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                          .withoutIPv6()
4539ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                          .withoutIpReachabilityMonitor()
4549ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                          .withPreDhcpAction(30 * 1000)
4559ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                          .withProvisioningTimeoutMs(36 * 1000)
4569ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                          .build();
4579ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        mIpManager.startProvisioning(config);
4589ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    }
4599ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline
460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Get a reference to handler. This is used by a client to establish
462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * an AsyncChannel communication with WifiP2pService
463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public Messenger getMessenger() {
465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enforceAccessPermission();
466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enforceChangePermission();
467f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        return new Messenger(mClientHandler);
468f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    }
469f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
470f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    /**
471f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * Get a reference to handler. This is used by a WifiStateMachine to establish
472f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * an AsyncChannel communication with P2pStateMachine
473f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * @hide
474f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     */
475f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    public Messenger getP2pStateMachineMessenger() {
47607a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        enforceConnectivityInternalOrLocationHardwarePermission();
477f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        enforceAccessPermission();
478f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        enforceChangePermission();
479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return new Messenger(mP2pStateMachine.getHandler());
480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /** This is used to provide information to drivers to optimize performance depending
483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * on the current mode of operation.
484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * 0 - disabled
485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * 1 - source operation
486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * 2 - sink operation
487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * As an example, the driver could reduce the channel dwell time during scanning
489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * when acting as a source or sink to minimize impact on miracast.
490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setMiracastMode(int mode) {
492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enforceConnectivityInternalPermission();
493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pStateMachine.sendMessage(SET_MIRACAST_MODE, mode);
494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                != PackageManager.PERMISSION_GRANTED) {
500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + Binder.getCallingPid()
502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + ", uid=" + Binder.getCallingUid());
503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pStateMachine.dump(fd, pw, args);
506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mAutonomousGroup " + mAutonomousGroup);
507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mJoinExistingGroup " + mJoinExistingGroup);
508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mDiscoveryStarted " + mDiscoveryStarted);
509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mNetworkInfo " + mNetworkInfo);
5105c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales        pw.println("mTemporarilyDisconnectedWifi " + mTemporarilyDisconnectedWifi);
511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mServiceDiscReqId " + mServiceDiscReqId);
512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println();
5139ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline
5149ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        final IpManager ipManager = mIpManager;
5159ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        if (ipManager != null) {
5169ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline            pw.println("mIpManager:");
5179ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline            ipManager.dump(fd, pw, args);
5189ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        }
519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Handles interaction with WifiStateMachine
524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private class P2pStateMachine extends StateMachine {
526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private DefaultState mDefaultState = new DefaultState();
528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Inactive is when p2p is enabled with no connectivity
534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private InactiveState mInactiveState = new InactiveState();
535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState
537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                = new UserAuthorizingInviteRequestState();
538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private UserAuthorizingNegotiationRequestState mUserAuthorizingNegotiationRequestState
539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                = new UserAuthorizingNegotiationRequestState();
540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
5429ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline        private FrequencyConflictState mFrequencyConflictState = new FrequencyConflictState();
543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private OngoingGroupRemovalState mOngoingGroupRemovalState = new OngoingGroupRemovalState();
547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
54818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        private WifiNative mWifiNative = WifiNative.getP2pNativeInterface();
5494e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills        private WifiMonitor mWifiMonitor = WifiMonitor.getInstance();
550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* During a connection, supplicant can tell us that a device was lost. From a supplicant's
552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * perspective, the discovery stops during connection and it purges device since it does
553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * not get latest updates about the device without being in discovery state.
554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *
555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * From the framework perspective, the device is still there since we are connecting or
556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * connected to it. so we keep these devices in a separate list, so that they are removed
557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * when connection is cancelled or lost
558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pDeviceList mPeersLostDuringConnection = new WifiP2pDeviceList();
560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new GroupDeleteListener() {
562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            @Override
563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            public void onDeleteGroup(int netId) {
564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("called onDeleteGroup() netId=" + netId);
565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.removeNetwork(netId);
566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.saveConfig();
567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendP2pPersistentGroupsChangedBroadcast();
568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        });
570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private WifiP2pGroup mGroup;
572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Saved WifiP2pConfig for an ongoing peer connection. This will never be null.
574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // The deviceAddress will be an empty string when the device is inactive
575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // or if it is connected without any ongoing join request
576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private WifiP2pConfig mSavedPeerConfig = new WifiP2pConfig();
577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
578f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        P2pStateMachine(String name, Looper looper, boolean p2pSupported) {
579f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            super(name, looper);
580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mDefaultState);
582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pNotSupportedState, mDefaultState);
583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pDisablingState, mDefaultState);
584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pDisabledState, mDefaultState);
585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pEnablingState, mDefaultState);
586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pEnabledState, mDefaultState);
587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mInactiveState, mP2pEnabledState);
588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mGroupCreatingState, mP2pEnabledState);
589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mUserAuthorizingInviteRequestState, mGroupCreatingState);
590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mUserAuthorizingNegotiationRequestState, mGroupCreatingState);
591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mProvisionDiscoveryState, mGroupCreatingState);
592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mGroupNegotiationState, mGroupCreatingState);
593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mFrequencyConflictState, mGroupCreatingState);
594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mGroupCreatedState, mP2pEnabledState);
595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mOngoingGroupRemovalState, mGroupCreatedState);
597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (p2pSupported) {
599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setInitialState(mP2pDisabledState);
600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setInitialState(mP2pNotSupportedState);
602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setLogRecSize(50);
604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setLogOnlyTransitions(true);
6054e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills
6064e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            String interfaceName = mWifiNative.getInterfaceName();
6074e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6084e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.AP_STA_CONNECTED_EVENT, getHandler());
6094e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6104e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.AP_STA_DISCONNECTED_EVENT, getHandler());
6114e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6124e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.AUTHENTICATION_FAILURE_EVENT, getHandler());
6134e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6144e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.NETWORK_CONNECTION_EVENT, getHandler());
6154e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6164e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.NETWORK_DISCONNECTION_EVENT, getHandler());
6174e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6184e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_DEVICE_FOUND_EVENT, getHandler());
6194e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6204e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_DEVICE_LOST_EVENT, getHandler());
6214e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6224e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_FIND_STOPPED_EVENT, getHandler());
6234e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6244e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT, getHandler());
6254e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6264e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT, getHandler());
6274e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6284e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT, getHandler());
6294e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6304e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT, getHandler());
6314e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6324e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT, getHandler());
6334e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6344e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_REMOVED_EVENT, getHandler());
6354e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6364e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_STARTED_EVENT, getHandler());
6374e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6384e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_INVITATION_RECEIVED_EVENT, getHandler());
6394e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6404e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_INVITATION_RESULT_EVENT, getHandler());
6414e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6424e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT, getHandler());
6434e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6444e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT, getHandler());
6454e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6464e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT, getHandler());
6474e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6484e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT, getHandler());
6494e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6504e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT, getHandler());
6514e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6524e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_SERV_DISC_RESP_EVENT, getHandler());
6534e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6544e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SCAN_RESULTS_EVENT, getHandler());
6554e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6564e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SUP_CONNECTION_EVENT, getHandler());
6574e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6584e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SUP_DISCONNECTION_EVENT, getHandler());
6594e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6604e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, getHandler());
6614e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6624e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_FAIL_EVENT, getHandler());
6634e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6644e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_OVERLAP_EVENT, getHandler());
6654e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6664e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_SUCCESS_EVENT, getHandler());
6674e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6684e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_TIMEOUT_EVENT, getHandler());
669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DefaultState extends State {
672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Full connection with WifiStateMachine established");
679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiChannel = (AsyncChannel) message.obj;
680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Full connection failure, error = " + message.arg1);
682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiChannel = null;
683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Send failed, client connection lost");
689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Client connection lost with reason: " + message.arg1);
691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiChannel = null;
693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    AsyncChannel ac = new AsyncChannel();
697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ac.connect(mContext, getHandler(), message.replyTo);
698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case BLOCK_DISCOVERY:
700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDiscoveryBlocked = (message.arg1 == ENABLED ? true : false);
701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // always reset this - we went to a state that doesn't support discovery so
702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // it would have stopped regardless
703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDiscoveryPostponed = false;
704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked) {
705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            StateMachine m = (StateMachine)message.obj;
707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            m.sendMessage(message.arg2);
708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (Exception e) {
709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("unable to send BLOCK_DISCOVERY response: " + e);
710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_PEERS:
714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_SERVICES:
722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CANCEL_CONNECT:
730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CREATE_GROUP:
734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_LOCAL_SERVICE:
742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_SERVICE_REQUEST:
754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_DEVICE_NAME:
768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_WFD_INFO:
776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_PEERS:
780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,
781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            new WifiP2pDeviceList(mPeers));
782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_CONNECTION_INFO:
784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            new WifiP2pInfo(mWifiP2pInfo));
786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_GROUP_INFO:
788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mGroup != null ? new WifiP2pGroup(mGroup) : null);
790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            new WifiP2pGroupList(mGroups, null));
794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_WPS:
796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pManager.BUSY);
798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7995c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_REQUEST:
8005c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_SELECT:
8015c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.RESPONSE_GET_HANDOVER_MESSAGE, null);
8025c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
8035c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.INITIATOR_REPORT_NFC_HANDOVER:
8045c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.RESPONDER_REPORT_NFC_HANDOVER:
8055c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED,
8065c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            WifiP2pManager.BUSY);
8075c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Ignore
809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SCAN_RESULTS_EVENT:
811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_SUCCESS_EVENT:
818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_FAIL_EVENT:
819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_OVERLAP_EVENT:
820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_TIMEOUT_EVENT:
821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISCONNECT_WIFI_RESPONSE:
829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_ACCEPT:
830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_REJECT:
831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case GROUP_CREATING_TIMED_OUT:
832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISABLE_P2P_TIMED_OUT:
8339ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_PRE_DHCP_ACTION:
8349ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_POST_DHCP_ACTION:
8359ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_DHCP_RESULTS:
8369ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_PROVISIONING_SUCCESS:
8379ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_PROVISIONING_FAILURE:
838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case SET_MIRACAST_MODE:
840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_CHANNEL:
843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Enable is lazy and has no response
845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // If we end up handling in default, p2p is not enabled
848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* unexpected group created, remove */
851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mGroup = (WifiP2pGroup) message.obj;
853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unexpected group creation, remove " + mGroup);
854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // A group formation failure is always followed by
857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // a group removed event. Flushing things at group formation
858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // failure causes supplicant issues. Ignore right now.
859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unhandled message " + message);
863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
868155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pNotSupportedState extends State {
870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case WifiP2pManager.DISCOVER_PEERS:
874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_SERVICES:
882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CANCEL_CONNECT:
890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case WifiP2pManager.CREATE_GROUP:
894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_LOCAL_SERVICE:
902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_SERVICE_REQUEST:
914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_DEVICE_NAME:
928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_WFD_INFO:
936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_WPS:
940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED,
945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED,
949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pDisablingState extends State {
960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(DISABLE_P2P_TIMED_OUT,
964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mDisableP2pTimeoutIndex, 0), DISABLE_P2P_WAIT_TIME_MS);
965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("p2p socket connection lost");
973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisabledState);
974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISABLE_P2P_TIMED_OUT:
98097a856eb1fda1585316055bd4912f0000deccb52Yuhao Zheng                    if (mDisableP2pTimeoutIndex == message.arg1) {
981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("P2p disable timed out");
982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mP2pDisabledState);
983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pDisabledState extends State {
998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       @Override
999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
1008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
100918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        mNwService.setInterfaceUp(mWifiNative.getInterfaceName());
1010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (RemoteException re) {
1011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unable to change interface settings: " + re);
1012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (IllegalStateException ie) {
1013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unable to change interface settings: " + ie);
1014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
10154e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    mWifiMonitor.startMonitoring(mWifiNative.getInterfaceName());
1016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pEnablingState);
1017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pEnablingState extends State {
1026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
1036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("P2p socket connection successful");
1037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("P2p socket connection failed");
1041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisabledState);
1042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
1044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
1045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
1046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pEnabledState extends State {
1055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pStateChangedBroadcast(true);
1059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setIsAvailable(true);
1060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pConnectionChangedBroadcast();
1061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            initializeP2pSettings();
1062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
1069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unexpected loss of p2p socket connection");
1070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisabledState);
1071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
1073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Nothing to do
1074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
1076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mPeers.clear()) {
1077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
1080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
10814e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    mWifiMonitor.stopMonitoring(mWifiNative.getInterfaceName());
1082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisablingState);
1083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_DEVICE_NAME:
1085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                {
1086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
1087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
1088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("set device name " + d.deviceName);
1089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
1090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
1092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_WFD_INFO:
1097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                {
1098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
1099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (d != null && setWfdInfo(d)) {
1100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
1101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
1103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case BLOCK_DISCOVERY:
1108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean blocked = (message.arg1 == ENABLED ? true : false);
1109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked == blocked) break;
1110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDiscoveryBlocked = blocked;
1111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (blocked && mDiscoveryStarted) {
1112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pStopFind();
1113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDiscoveryPostponed = true;
1114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!blocked && mDiscoveryPostponed) {
1116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDiscoveryPostponed = false;
1117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pFind(DISCOVER_TIMEOUT_S);
1118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (blocked) {
1120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            StateMachine m = (StateMachine)message.obj;
1122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            m.sendMessage(message.arg2);
1123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (Exception e) {
1124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("unable to send BLOCK_DISCOVERY response: " + e);
1125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_PEERS:
1129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked) {
1130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.BUSY);
1132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // do not send service discovery request while normal find operation.
1135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearSupplicantServiceRequest();
1136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
1137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
1138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendP2pDiscoveryChangedBroadcast(true);
1139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
1145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendP2pDiscoveryChangedBroadcast(false);
1146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
1148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pStopFind()) {
1149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
1150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
1152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_SERVICES:
1156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked) {
1157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
1158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.BUSY);
1159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " discover services");
1162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!updateSupplicantServiceRequest()) {
1163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
1164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.NO_SERVICE_REQUESTS);
1165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
1168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED);
1169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
1171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
1175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;
1177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateSupplicantDetails(device);
1178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = (WifiP2pDevice) message.obj;
1182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Gets current details for the one removed
1183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = mPeers.remove(device.deviceAddress);
1184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (device != null) {
1185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_LOCAL_SERVICE:
1189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " add service");
1190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)message.obj;
1191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (addLocalService(message.replyTo, servInfo)) {
1192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
1193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED);
1195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
1198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " remove service");
1199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    servInfo = (WifiP2pServiceInfo)message.obj;
1200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    removeLocalService(message.replyTo, servInfo);
1201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED);
1202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
1204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " clear service");
1205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearLocalServices(message.replyTo);
1206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_SUCCEEDED);
1207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_SERVICE_REQUEST:
1209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " add service request");
1210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!addServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj)) {
1211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED);
1212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED);
1215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
1217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " remove service request");
1218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    removeServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj);
1219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED);
1220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
1222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " clear service request");
1223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearServiceRequests(message.replyTo);
1224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED);
1225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
1227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " receive service response");
1228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    List<WifiP2pServiceResponse> sdRespList =
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        (List<WifiP2pServiceResponse>) message.obj;
1230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    for (WifiP2pServiceResponse resp : sdRespList) {
1231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pDevice dev =
1232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mPeers.get(resp.getSrcDevice().deviceAddress);
1233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        resp.setSrcDevice(dev);
1234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendServiceResponse(resp);
1235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
1238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   if (DBG) logd(getName() + " delete persistent group");
1239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   mGroups.remove(message.arg1);
1240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
1241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   break;
1242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case SET_MIRACAST_MODE:
1243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.setMiracastMode(message.arg1);
1244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
1246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " start listen mode");
1247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(true, 500, 500)) {
1249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
1250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
1252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
1255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " stop listen mode");
1256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(false, 0, 0)) {
1257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
1258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
1260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_CHANNEL:
1264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Bundle p2pChannels = (Bundle) message.obj;
1265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int lc = p2pChannels.getInt("lc", 0);
1266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int oc = p2pChannels.getInt("oc", 0);
1267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " set listen and operating channel");
1268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pSetChannel(lc, oc)) {
1269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
1270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
1272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
12745c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_REQUEST:
12755c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    Bundle requestBundle = new Bundle();
12765c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    requestBundle.putString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE,
12775c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            mWifiNative.getNfcHandoverRequest());
12785c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.RESPONSE_GET_HANDOVER_MESSAGE,
12795c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            requestBundle);
12805c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
12815c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_SELECT:
12825c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    Bundle selectBundle = new Bundle();
12835c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    selectBundle.putString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE,
12845c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            mWifiNative.getNfcHandoverSelect());
12855c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.RESPONSE_GET_HANDOVER_MESSAGE,
12865c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            selectBundle);
12875c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   return NOT_HANDLED;
1290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pDiscoveryChangedBroadcast(false);
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pStateChangedBroadcast(false);
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setIsAvailable(false);
1299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class InactiveState extends State {
1303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSavedPeerConfig.invalidate();
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
1314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " sending connect");
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
1316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping connect requeset " + config);
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
1319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = false;
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (reinvokePersistentGroup(config)) {
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mProvisionDiscoveryState);
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pStopFind()) {
1336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // When discovery stops in inactive state, flush to clear
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // state peer data
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pFlush();
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mServiceDiscReqId = null;
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
1341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
1347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = (WifiP2pConfig) message.obj;
1348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
1349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping GO neg request " + config);
1350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
1353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = false;
1354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mJoinExistingGroup = false;
1355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUserAuthorizingNegotiationRequestState);
1356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
1358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
1359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice owner = group.getOwner();
1360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (owner == null) {
1362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Ignored invitation from null owner");
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = new WifiP2pConfig();
1367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config.deviceAddress = group.getOwner().deviceAddress;
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
1370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping invitation request " + config);
1371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
1374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Check if we have the owner in peer list and use appropriate
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //wps method. Default is to use PBC.
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if ((owner = mPeers.get(owner.deviceAddress)) != null) {
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (owner.wpsPbcSupported()) {
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mSavedPeerConfig.wps.setup = WpsInfo.PBC;
1380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else if (owner.wpsKeypadSupported()) {
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
1382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else if (owner.wpsDisplaySupported()) {
1383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
1384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = false;
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mJoinExistingGroup = true;
1389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUserAuthorizingInviteRequestState);
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //We let the supplicant handle the provision discovery response
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //and wait instead for the GO_NEGOTIATION_REQUEST_EVENT.
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Handling provision discovery and issuing a p2p_connect before
1397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //group negotiation comes through causes issues
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CREATE_GROUP:
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = true;
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int netId = message.arg1;
1402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean ret = false;
1403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
1404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // check if the go persistent group is present.
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (netId != -1) {
1407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ret = mWifiNative.p2pGroupAdd(netId);
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ret = mWifiNative.p2pGroupAdd(true);
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = mWifiNative.p2pGroupAdd(false);
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (ret) {
1416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
1417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // remain at this state.
1422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mGroup = (WifiP2pGroup) message.obj;
1426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " group started");
1427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // We hit this scenario when a persistent group is reinvoked
1429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
1430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mAutonomousGroup = false;
1431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        deferMessage(message);
1432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unexpected group creation, remove " + mGroup);
1435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
1436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
1439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " start listen mode");
1440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(true, 500, 500)) {
1442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
1443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
1445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
1448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " stop listen mode");
1449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(false, 0, 0)) {
1450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
1451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
1453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_CHANNEL:
1457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Bundle p2pChannels = (Bundle) message.obj;
1458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int lc = p2pChannels.getInt("lc", 0);
1459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int oc = p2pChannels.getInt("oc", 0);
1460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " set listen and operating channel");
1461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pSetChannel(lc, oc)) {
1462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
1463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
1465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
14675c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.INITIATOR_REPORT_NFC_HANDOVER:
14685c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    String handoverSelect = null;
14695c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14705c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (message.obj != null) {
14715c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        handoverSelect = ((Bundle) message.obj)
14725c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                                .getString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE);
14735c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14745c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14755c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (handoverSelect != null
14765c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            && mWifiNative.initiatorReportNfcHandover(handoverSelect)) {
14775c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_SUCCEEDED);
14785c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        transitionTo(mGroupCreatingState);
14795c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    } else {
14805c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED);
14815c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14825c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
14835c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.RESPONDER_REPORT_NFC_HANDOVER:
14845c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    String handoverRequest = null;
14855c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14865c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (message.obj != null) {
14875c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        handoverRequest = ((Bundle) message.obj)
14885c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                                .getString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE);
14895c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14905c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14915c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (handoverRequest != null
14925c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            && mWifiNative.responderReportNfcHandover(handoverRequest)) {
14935c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_SUCCEEDED);
14945c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        transitionTo(mGroupCreatingState);
14955c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    } else {
14965c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED);
14975c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14985c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
1499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class GroupCreatingState extends State {
1507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
1511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
1512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
1518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case GROUP_CREATING_TIMED_OUT:
1520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroupCreatingTimeoutIndex == message.arg1) {
1521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Group negotiation timed out");
1522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleGroupCreationFailure();
1523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInactiveState);
1524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
1529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) {
1530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            logd("mSavedPeerConfig " + mSavedPeerConfig.deviceAddress +
1531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                "device " + device.deviceAddress);
1532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Do the regular device lost handling
1534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = NOT_HANDLED;
1535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Do nothing
1538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("Add device to lost list " + device);
1539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeersLostDuringConnection.updateSupplicantDetails(device);
1540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_PEERS:
1542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Discovery will break negotiation */
1543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
1545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CANCEL_CONNECT:
1547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Do a supplicant p2p_cancel which only cancels an ongoing
1548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //group negotiation. This will fail for a pending provision
1549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //discovery or for a pending user action, but at the framework
1550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //level, we always treat cancel as succeeded and enter
1551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //an inactive state
1552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pCancelConnect();
1553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
1556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
15575c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
15585c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    // We hit this scenario when NFC handover is invoked.
15595c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    mAutonomousGroup = false;
15605c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    transitionTo(mGroupNegotiationState);
15615c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
1562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ret = NOT_HANDLED;
1564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
1566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UserAuthorizingNegotiationRequestState extends State {
1570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationReceived();
1574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
1580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
1582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
1583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    p2pConnectWithPinDisplay(mSavedPeerConfig);
1584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupNegotiationState);
1587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   break;
1588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
1589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("User rejected negotiation " + mSavedPeerConfig);
1590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
1596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: dismiss dialog if not already done
1601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UserAuthorizingInviteRequestState extends State {
1605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationReceived();
1609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
1615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
1617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
1618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!reinvokePersistentGroup(mSavedPeerConfig)) {
1619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Do negotiation when persistence fails
1620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupNegotiationState);
1625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   break;
1626155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
1627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
1628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
1634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: dismiss dialog if not already done
1639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ProvisionDiscoveryState extends State {
1645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
1649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pProvDiscEvent provDisc;
1655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pDevice device;
1656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
1658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = provDisc.device;
1660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
1663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = provDisc.device;
1671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
1674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /* we already have the pin */
1676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
1677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            p2pConnectWithPinDisplay(mSavedPeerConfig);
1678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            transitionTo(mGroupNegotiationState);
1679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mJoinExistingGroup = false;
1681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            transitionTo(mUserAuthorizingNegotiationRequestState);
1682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = provDisc.device;
1688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
1691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.pin = provDisc.pin;
1693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        notifyInvitationSent(provDisc.pin, device.deviceAddress);
1695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
1699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("provision discovery failed");
1700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class GroupNegotiationState extends State {
1711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // We ignore these right now, since we get a GROUP_STARTED notification
1721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // afterwards
1722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
1723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
1724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " go success");
1725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mGroup = (WifiP2pGroup) message.obj;
1728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " group started");
1729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
1731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /*
1732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * update cache information and set network id to mGroup.
1733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         */
1734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        updatePersistentNetworks(NO_RELOAD);
1735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        String devAddr = mGroup.getOwner().deviceAddress;
1736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
1737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mGroup.getNetworkName()));
1738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.isGroupOwner()) {
1741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /* Setting an idle time out on GO causes issues with certain scenarios
1742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * on clients where it can be off-channel for longer and with the power
1743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * save modes used.
1744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         *
1745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * TODO: Verify multi-channel scenarios and supplicant behavior are
1746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * better before adding a time out in future
1747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         */
1748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        //Set group idle timeout of 10 sec, to avoid GO beaconing incase of any
1749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        //failure during 4-way Handshake.
1750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (!mAutonomousGroup) {
1751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
1752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        startDhcpServer(mGroup.getInterface());
1754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
17569ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        startIpManager(mGroup.getInterface());
1757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pDevice groupOwner = mGroup.getOwner();
1758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pDevice peer = mPeers.get(groupOwner.deviceAddress);
1759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (peer != null) {
1760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // update group owner details with peer details found at discovery
1761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            groupOwner.updateSupplicantDetails(peer);
1762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
1763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendPeersChangedBroadcast();
1764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // A supplicant bug can lead to reporting an invalid
1766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // group owner address (all zeroes) at times. Avoid a
1767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // crash, but continue group creation since it is not
1768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // essential.
1769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            logw("Unknown group owner " + groupOwner);
1770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupCreatedState);
1773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
1775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    P2pStatus status = (P2pStatus) message.obj;
1776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.NO_COMMON_CHANNEL) {
1777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mFrequencyConflictState);
1778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* continue with group removal handling */
1781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " go failure");
1783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // A group formation failure is always followed by
1787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // a group removed event. Flushing things at group formation
1788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // failure causes supplicant issues. Ignore right now.
1789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
1790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    status = (P2pStatus) message.obj;
1791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.NO_COMMON_CHANNEL) {
1792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mFrequencyConflictState);
1793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
1797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    status = (P2pStatus)message.obj;
1798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.SUCCESS) {
1799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // invocation was succeeded.
1800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // wait P2P_GROUP_STARTED_EVENT.
1801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Invitation result " + status);
1804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
1805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // target device has already removed the credential.
1806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // So, remove this credential accordingly.
1807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        int netId = mSavedPeerConfig.netId;
1808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (netId >= 0) {
1809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Remove unknown client from the list");
1810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
1811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Reinvocation has failed, try group negotiation
1814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
1815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (status == P2pStatus.INFORMATION_IS_CURRENTLY_UNAVAILABLE) {
1817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Devices setting persistent_reconnect to 0 in wpa_supplicant
1819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // always defer the invocation request and return
1820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // "information is currently unable" error.
1821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // So, try another way to connect for interoperability.
1822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
1823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (status == P2pStatus.NO_COMMON_CHANNEL) {
1825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mFrequencyConflictState);
1826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleGroupCreationFailure();
1828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInactiveState);
1829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class FrequencyConflictState extends State {
1839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private AlertDialog mFrequencyConflictDialog;
1840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyFrequencyConflict();
1844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private void notifyFrequencyConflict() {
1847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            logd("Notify frequency conflict");
1848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Resources r = Resources.getSystem();
1849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            AlertDialog dialog = new AlertDialog.Builder(mContext)
1851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setMessage(r.getString(R.string.wifi_p2p_frequency_conflict_message,
1852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        getDeviceName(mSavedPeerConfig.deviceAddress)))
1853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setPositiveButton(r.getString(R.string.dlg_ok), new OnClickListener() {
1854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
1855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
1856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(DROP_WIFI_USER_ACCEPT);
1857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
1859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
1860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
1861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
1862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(DROP_WIFI_USER_REJECT);
1863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
1865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setOnCancelListener(new DialogInterface.OnCancelListener() {
1866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
1867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onCancel(DialogInterface arg0) {
1868155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(DROP_WIFI_USER_REJECT);
1869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
1871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .create();
1872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
1874123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber            WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
1875123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber            attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
1876123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber            dialog.getWindow().setAttributes(attrs);
1877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dialog.show();
1878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mFrequencyConflictDialog = dialog;
1879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
1886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
1887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge(getName() + "group sucess during freq conflict!");
1888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge(getName() + "group started after freq conflict, handle anyway");
1891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
1892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupNegotiationState);
1893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
1895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
1897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Ignore failures since we retry again
1898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_REJECT:
1900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // User rejected dropping wifi in favour of p2p
1901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_ACCEPT:
1905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // User accepted dropping wifi in favour of p2p
1906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiChannel.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST, 1);
19075c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    mTemporarilyDisconnectedWifi = true;
1908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISCONNECT_WIFI_RESPONSE:
1910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Got a response from wifistatemachine, retry p2p
1911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + "Wifi disconnected, retry p2p");
1912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
1914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mFrequencyConflictDialog != null) mFrequencyConflictDialog.dismiss();
1923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class GroupCreatedState extends State {
1927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // Once connected, peer config details are invalid
1931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSavedPeerConfig.invalidate();
1932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
1933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            updateThisDevice(WifiP2pDevice.CONNECTED);
1935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //DHCP server has already been started if I am a group owner
1937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mGroup.isGroupOwner()) {
1938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setWifiP2pInfoOnGroupFormation(NetworkUtils.numericToInetAddress(SERVER_ADDRESS));
1939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // In case of a negotiation group, connection changed is sent
1942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // after a client joins. For autonomous, send now
1943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mAutonomousGroup) {
1944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendP2pConnectionChangedBroadcast();
1945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AP_STA_CONNECTED_EVENT:
1953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    String deviceAddress = device.deviceAddress;
1955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Clear timeout that was set when group was started.
1956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
1957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (deviceAddress != null) {
1958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mPeers.get(deviceAddress) != null) {
1959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mGroup.addClient(mPeers.get(deviceAddress));
1960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mGroup.addClient(deviceAddress);
1962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED);
1964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd(getName() + " ap sta connected");
1965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Connect on null device address, ignore");
1968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendP2pConnectionChangedBroadcast();
1970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
1972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = (WifiP2pDevice) message.obj;
1973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deviceAddress = device.deviceAddress;
1974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (deviceAddress != null) {
1975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
1976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mGroup.removeClient(deviceAddress)) {
1977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Removed client " + deviceAddress);
1978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (!mAutonomousGroup && mGroup.isClientListEmpty()) {
1979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                logd("Client list empty, remove non-persistent p2p group");
1980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
1981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // We end up sending connection changed broadcast
1982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // when this happens at exit()
1983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            } else {
1984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // Notify when a client disconnects from group
1985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                sendP2pConnectionChangedBroadcast();
1986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
1987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Failed to remove client " + deviceAddress);
1989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            for (WifiP2pDevice c : mGroup.getClientList()) {
1990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                if (DBG) logd("client " + c.deviceAddress);
1991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
1992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd(getName() + " ap sta disconnected");
1995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Disconnect on unknown device: " + device);
1997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
19999ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_PRE_DHCP_ACTION:
20009ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    mWifiNative.setP2pPowerSave(mGroup.getInterface(), false);
20019ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    mIpManager.completedPreDhcpAction();
20029ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    break;
20039ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_POST_DHCP_ACTION:
20049ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
20059ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    break;
20069ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_DHCP_RESULTS:
20079ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    mDhcpResults = (DhcpResults) message.obj;
20089ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    break;
20099ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_PROVISIONING_SUCCESS:
20109ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    if (DBG) logd("mDhcpResults: " + mDhcpResults);
20119ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    setWifiP2pInfoOnGroupFormation(mDhcpResults.serverAddress);
20129ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    sendP2pConnectionChangedBroadcast();
20139ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    try {
20149ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        final String ifname = mGroup.getInterface();
20159ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        mNwService.addInterfaceToLocalNetwork(
20169ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                                ifname, mDhcpResults.getRoutes(ifname));
20179ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    } catch (RemoteException e) {
20189ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                        loge("Failed to add iface to local network " + e);
2019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
20219ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                case IPM_PROVISIONING_FAILURE:
20229ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    loge("IP provisioning failed");
20239ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
20249ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline                    break;
2025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
2026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " remove group");
2027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
2028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mOngoingGroupRemovalState);
2029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
2030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleGroupRemoved();
2032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInactiveState);
2033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
2034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
2035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                /* We do not listen to NETWORK_DISCONNECTION_EVENT for group removal
2038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * handling since supplicant actually tries to reconnect after a temporary
2039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * disconnect until group idle time out. Eventually, a group removal event
2040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * will come when group has been removed.
2041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 *
2042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * When there are connectivity issues during temporary disconnect, the application
2043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * will also just remove the group.
2044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 *
2045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * Treating network disconnection as group removal causes race conditions since
2046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * supplicant would still maintain the group at that stage.
2047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 */
2048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
2049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " group removed");
2050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupRemoved();
2051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
2052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
2054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = (WifiP2pDevice) message.obj;
2055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Device loss for a connected device indicates it is not in discovery any more
2056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.contains(device)) {
2057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Add device to lost list " + device);
2058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeersLostDuringConnection.updateSupplicantDetails(device);
2059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return HANDLED;
2060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Do the regular device lost handling
2062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
2064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(WifiP2pManager.REMOVE_GROUP);
2065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
2066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // This allows any client to join the GO during the
2068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // WPS window
2069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_WPS:
2070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WpsInfo wps = (WpsInfo) message.obj;
2071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (wps == null) {
2072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_WPS_FAILED);
2073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
2074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean ret = true;
2076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (wps.setup == WpsInfo.PBC) {
2077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = mWifiNative.startWpsPbc(mGroup.getInterface(), null);
2078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (wps.pin == null) {
2080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
2081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            try {
2082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                Integer.parseInt(pin);
2083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                notifyInvitationSent(pin, "any");
2084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            } catch (NumberFormatException ignore) {
2085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                ret = false;
2086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
2087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
2088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ret = mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
2089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    wps.pin);
2090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, ret ? WifiP2pManager.START_WPS_SUCCEEDED :
2093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.START_WPS_FAILED);
2094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
2096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
2097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
2098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping connect requeset " + config);
2099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
2100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
2101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    logd("Inviting device : " + config.deviceAddress);
2103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
2104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
2105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
2106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
2107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
2108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
2110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
2111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // TODO: figure out updating the status to declined when invitation is rejected
2113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
2115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    P2pStatus status = (P2pStatus)message.obj;
2116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.SUCCESS) {
2117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // invocation was succeeded.
2118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
2119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Invitation result " + status);
2121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
2122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // target device has already removed the credential.
2123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // So, remove this credential accordingly.
2124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        int netId = mGroup.getNetworkId();
2125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (netId >= 0) {
2126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Remove unknown client from the list");
2127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (!removeClientFromList(netId,
2128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    mSavedPeerConfig.deviceAddress, false)) {
2129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // not found the client on the list
2130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                loge("Already removed the client, ignore");
2131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                break;
2132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
2133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // try invitation.
2134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
2135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
2139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
2140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
2141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
2142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = new WifiP2pConfig();
2143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
2144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
2145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
2146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
2147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
2148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.pin = provDisc.pin;
2149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
2151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUserAuthorizingJoinState);
2153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
2155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Duplicate group creation event notice, ignore");
2156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
2158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
2161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
2164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            updateThisDevice(WifiP2pDevice.AVAILABLE);
2165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            resetWifiP2pInfo();
2166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
2167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pConnectionChangedBroadcast();
2168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UserAuthorizingJoinState extends State {
2172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
2174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
2175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationReceived();
2176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
2180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
2181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
2182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
2183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
2184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
2185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Ignore more client requests
2186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
2188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Stop discovery to avoid failure due to channel switch
2189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
2190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
2191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startWpsPbc(mGroup.getInterface(), null);
2192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
2194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mSavedPeerConfig.wps.pin);
2195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupCreatedState);
2197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
2199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("User rejected incoming request");
2200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupCreatedState);
2201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
2203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
2206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
2210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: dismiss dialog if not already done
2211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class OngoingGroupRemovalState extends State {
2215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
2217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
2218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
2222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
2223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
2224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Group removal ongoing. Multiple calls
2225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // end up removing persisted network. Do nothing.
2226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
2227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
2228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Parent state will transition out of this state
2230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // when removal is complete
2231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
2232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
2235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        super.dump(fd, pw, args);
2241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mWifiP2pInfo " + mWifiP2pInfo);
2242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mGroup " + mGroup);
2243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mSavedPeerConfig " + mSavedPeerConfig);
2244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println();
2245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pStateChangedBroadcast(boolean enabled) {
2248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
2249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enabled) {
2251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
2252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
2253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
2254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
2255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
2256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pDiscoveryChangedBroadcast(boolean started) {
2261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mDiscoveryStarted == started) return;
2262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDiscoveryStarted = started;
2263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("discovery change broadcast " + started);
2265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
2267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, started ?
2269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED :
2270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
2271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendThisDeviceChangedBroadcast() {
2275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
2276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
2278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendPeersChangedBroadcast() {
2282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
2283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, new WifiP2pDeviceList(mPeers));
2284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
2286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pConnectionChangedBroadcast() {
2289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("sending p2p connection changed broadcast");
2290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
2291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
2292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
2293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
2294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
2295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, new WifiP2pGroup(mGroup));
2296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiChannel.sendMessage(WifiP2pServiceImpl.P2P_CONNECTION_CHANGED,
2298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new NetworkInfo(mNetworkInfo));
2299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pPersistentGroupsChangedBroadcast() {
2302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("sending p2p persistent groups changed broadcast");
2303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
2304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void startDhcpServer(String intf) {
2309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        InterfaceConfiguration ifcg = null;
2310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
2311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg = mNwService.getInterfaceConfig(intf);
2312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
2313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        SERVER_ADDRESS), 24));
2314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg.setInterfaceUp();
2315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.setInterfaceConfig(intf, ifcg);
2316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* This starts the dnsmasq server */
23178c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
23188c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                    Context.CONNECTIVITY_SERVICE);
23198c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            String[] tetheringDhcpRanges = cm.getTetheredDhcpRanges();
23208c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            if (mNwService.isTetheringStarted()) {
23218c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                if (DBG) logd("Stop existing tethering and restart it");
23228c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                mNwService.stopTethering();
23238c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            }
23248c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            mNwService.tetherInterface(intf);
23258c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            mNwService.startTethering(tetheringDhcpRanges);
2326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
2327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Error configuring interface " + intf + ", :" + e);
2328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
2329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        logd("Started Dhcp server on " + intf);
2332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande   }
2333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void stopDhcpServer(String intf) {
2335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
23368c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            mNwService.untetherInterface(intf);
23378c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            for (String temp : mNwService.listTetheredInterfaces()) {
23388c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                logd("List all interfaces " + temp);
23398c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                if (temp.compareTo(intf) != 0) {
23408c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                    logd("Found other tethering interfaces, so keep tethering alive");
23418c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                    return;
23428c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                }
23438c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            }
2344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.stopTethering();
2345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
2346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Error stopping Dhcp server" + e);
2347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
23488c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt        } finally {
23498c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            logd("Stopped Dhcp server");
2350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyP2pEnableFailure() {
2354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        AlertDialog dialog = new AlertDialog.Builder(mContext)
2356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
2357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
2358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setPositiveButton(r.getString(R.string.ok), null)
2359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .create();
2360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2361123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
2362123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2363123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        dialog.getWindow().setAttributes(attrs);
2364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.show();
2365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void addRowToDialog(ViewGroup group, int stringId, String value) {
2368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
2370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group, false);
2371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
2372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ((TextView) row.findViewById(R.id.value)).setText(value);
2373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        group.addView(row);
2374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyInvitationSent(String pin, String peerAddress) {
2377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final View textEntryView = LayoutInflater.from(mContext)
2380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .inflate(R.layout.wifi_p2p_dialog, null);
2381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
2383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
2384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
2385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        AlertDialog dialog = new AlertDialog.Builder(mContext)
2387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
2388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setView(textEntryView)
2389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setPositiveButton(r.getString(R.string.ok), null)
2390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .create();
2391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2392123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
2393123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2394123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        dialog.getWindow().setAttributes(attrs);
2395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.show();
2396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyInvitationReceived() {
2399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final WpsInfo wps = mSavedPeerConfig.wps;
2401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final View textEntryView = LayoutInflater.from(mContext)
2402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .inflate(R.layout.wifi_p2p_dialog, null);
2403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
2405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
2406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mSavedPeerConfig.deviceAddress));
2407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
2409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        AlertDialog dialog = new AlertDialog.Builder(mContext)
2411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
2412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setView(textEntryView)
2413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
2414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
2415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (wps.setup == WpsInfo.KEYPAD) {
2416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mSavedPeerConfig.wps.pin = pin.getText().toString();
2417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
2418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
2419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
2420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
2422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
2423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
2424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
2425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd(getName() + " ignore connect");
2426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(PEER_CONNECTION_USER_REJECT);
2427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
2429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setOnCancelListener(new DialogInterface.OnCancelListener() {
2430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
2431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onCancel(DialogInterface arg0) {
2432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd(getName() + " ignore connect");
2433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(PEER_CONNECTION_USER_REJECT);
2434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
2436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .create();
2437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //make the enter pin area or the display pin area visible
2439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (wps.setup) {
2440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.KEYPAD:
2441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("Enter pin section visible");
2442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
2443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
2444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.DISPLAY:
2445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("Shown pin section visible");
2446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
2447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
2448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
2449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
2450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if ((r.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_APPLIANCE) ==
2453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Configuration.UI_MODE_TYPE_APPLIANCE) {
2454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // For appliance devices, add a key listener which accepts.
2455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
2456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                @Override
2458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
2459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // TODO: make the actual key come from a config value.
2460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
2461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(PEER_CONNECTION_USER_ACCEPT);
2462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        dialog.dismiss();
2463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return true;
2464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return false;
2466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            });
2468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // TODO: add timeout for this dialog.
2469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // TODO: update UI in appliance mode to tell user what to do.
2470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2473123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
2474123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2475123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        dialog.getWindow().setAttributes(attrs);
2476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.show();
2477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Synchronize the persistent group list between
2481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * wpa_supplicant and mGroups.
2482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void updatePersistentNetworks(boolean reload) {
2484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String listStr = mWifiNative.listNetworks();
2485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (listStr == null) return;
2486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean isSaveRequired = false;
2488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] lines = listStr.split("\n");
2489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (lines == null) return;
2490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (reload) mGroups.clear();
2492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Skip the first line, which is a header
2494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (int i = 1; i < lines.length; i++) {
2495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] result = lines[i].split("\t");
2496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (result == null || result.length < 4) {
2497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // network-id | ssid | bssid | flags
2500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = -1;
2501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String ssid = result[1];
2502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String bssid = result[2];
2503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String flags = result[3];
2504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
2505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                netId = Integer.parseInt(result[0]);
2506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch(NumberFormatException e) {
2507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                e.printStackTrace();
2508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (flags.indexOf("[CURRENT]") != -1) {
2512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
2515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                /*
2516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * The unused profile is sometimes remained when the p2p group formation is failed.
2517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * So, we clean up the p2p group here.
2518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 */
2519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("clean up the unused persistent group. netId=" + netId);
2520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.removeNetwork(netId);
2521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                isSaveRequired = true;
2522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mGroups.contains(netId)) {
2526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pGroup group = new WifiP2pGroup();
2530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            group.setNetworkId(netId);
2531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            group.setNetworkName(ssid);
2532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String mode = mWifiNative.getNetworkVariable(netId, "mode");
2533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mode != null && mode.equals("3")) {
2534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group.setIsGroupOwner(true);
2535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
2537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group.setOwner(mThisDevice);
2538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
2539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiP2pDevice device = new WifiP2pDevice();
2540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                device.deviceAddress = bssid;
2541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group.setOwner(device);
2542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mGroups.add(group);
2544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            isSaveRequired = true;
2545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (reload || isSaveRequired) {
2548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.saveConfig();
2549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pPersistentGroupsChangedBroadcast();
2550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * A config is valid if it has a peer address that has already been
2555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * discovered
2556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return true if it is invalid, false otherwise
2557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean isConfigInvalid(WifiP2pConfig config) {
2559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config == null) return true;
2560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(config.deviceAddress)) return true;
2561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mPeers.get(config.deviceAddress) == null) return true;
2562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
2563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* TODO: The supplicant does not provide group capability changes as an event.
2566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Having it pushed as an event would avoid polling for this information right
2567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * before a connection
2568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiP2pDevice fetchCurrentDeviceDetails(WifiP2pConfig config) {
2570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Fetch & update group capability from supplicant on the device */
2571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int gc = mWifiNative.getGroupCapability(config.deviceAddress);
2572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPeers.updateGroupCapability(config.deviceAddress, gc);
2573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mPeers.get(config.deviceAddress);
2574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start a p2p group negotiation and display pin if necessary
2578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param config for the peer
2579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
2581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
2582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
2584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
2585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Integer.parseInt(pin);
2586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationSent(pin, config.deviceAddress);
2587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (NumberFormatException ignore) {
2588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // do nothing if p2pConnect did not return a pin
2589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Reinvoke a persistent group.
2594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param config for the peer
2596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return true on success, false on failure
2597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean reinvokePersistentGroup(WifiP2pConfig config) {
2599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
2600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean join = dev.isGroupOwner();
2602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
2603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("target ssid is " + ssid + " join:" + join);
2604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (join && dev.isGroupLimit()) {
2606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("target device reaches group limit.");
2607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // if the target group has reached the limit,
2609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // try group formation.
2610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            join = false;
2611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else if (join) {
2612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
2613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (netId >= 0) {
2614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Skip WPS and start 4way handshake immediately.
2615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (!mWifiNative.p2pGroupAdd(netId)) {
2616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return false;
2617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return true;
2619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!join && dev.isDeviceLimit()) {
2623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("target device reaches the device limit.");
2624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2626155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!join && dev.isInvitationCapable()) {
2628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = WifiP2pGroup.PERSISTENT_NET_ID;
2629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (config.netId >= 0) {
2630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
2631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    netId = config.netId;
2632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
2634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                netId = mGroups.getNetworkId(dev.deviceAddress);
2635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (netId < 0) {
2637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                netId = getNetworkIdFromClientList(dev.deviceAddress);
2638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
2640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (netId >= 0) {
2641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Invoke the persistent group.
2642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
2643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Save network id. It'll be used when an invitation result event is received.
2644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config.netId = netId;
2645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return true;
2646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
2647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("p2pReinvoke() failed, update networks");
2648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    updatePersistentNetworks(RELOAD);
2649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return false;
2650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
2655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Return the network id of the group owner profile which has the p2p client with
2659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * the specified device address in it's client list.
2660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * If more than one persistent group of the same address is present in its client
2661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * lists, return the first one.
2662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param deviceAddress p2p device address.
2664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return the network id. if not found, return -1.
2665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int getNetworkIdFromClientList(String deviceAddress) {
2667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (deviceAddress == null) return -1;
2668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Collection<WifiP2pGroup> groups = mGroups.getGroupList();
2670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (WifiP2pGroup group : groups) {
2671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = group.getNetworkId();
2672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] p2pClientList = getClientList(netId);
2673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (p2pClientList == null) continue;
2674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String client : p2pClientList) {
2675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (deviceAddress.equalsIgnoreCase(client)) {
2676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return netId;
2677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return -1;
2681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Return p2p client list associated with the specified network id.
2685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param netId network id.
2686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return p2p client list. if not found, return null.
2687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String[] getClientList(int netId) {
2689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
2690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (p2pClients == null) {
2691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return null;
2692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return p2pClients.split(" ");
2694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Remove the specified p2p client from the specified profile.
2698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param netId network id of the profile.
2699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param addr p2p client address to be removed.
2700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param isRemovable if true, remove the specified profile if its client list becomes empty.
2701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return whether removing the specified p2p client is successful or not.
2702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
2704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        StringBuilder modifiedClientList =  new StringBuilder();
2705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] currentClientList = getClientList(netId);
2706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean isClientRemoved = false;
2707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (currentClientList != null) {
2708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String client : currentClientList) {
2709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (!client.equalsIgnoreCase(addr)) {
2710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    modifiedClientList.append(" ");
2711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    modifiedClientList.append(client);
2712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
2713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    isClientRemoved = true;
2714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (modifiedClientList.length() == 0 && isRemovable) {
2718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // the client list is empty. so remove it.
2719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("Remove unknown network");
2720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mGroups.remove(netId);
2721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return true;
2722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!isClientRemoved) {
2725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // specified p2p client is not found. already removed.
2726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("Modified client list: " + modifiedClientList);
2730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (modifiedClientList.length() == 0) {
2731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            modifiedClientList.append("\"\"");
2732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setNetworkVariable(netId,
2734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "p2p_client_list", modifiedClientList.toString());
2735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.saveConfig();
2736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setWifiP2pInfoOnGroupFormation(InetAddress serverInetAddress) {
2740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupFormed = true;
2741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
2742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupOwnerAddress = serverInetAddress;
2743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void resetWifiP2pInfo() {
2746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupFormed = false;
2747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.isGroupOwner = false;
2748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupOwnerAddress = null;
2749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String getDeviceName(String deviceAddress) {
2752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiP2pDevice d = mPeers.get(deviceAddress);
2753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (d != null) {
2754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return d.deviceName;
2755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //Treat the address as name if there is no match
2757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return deviceAddress;
2758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String getPersistedDeviceName() {
2761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String deviceName = Settings.Global.getString(mContext.getContentResolver(),
2762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_P2P_DEVICE_NAME);
2763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (deviceName == null) {
2764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* We use the 4 digits of the ANDROID_ID to have a friendly
2765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * default that has low likelihood of collision with a peer */
2766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String id = Settings.Secure.getString(mContext.getContentResolver(),
2767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Settings.Secure.ANDROID_ID);
2768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return "Android_" + id.substring(0,4);
2769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return deviceName;
2771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean setAndPersistDeviceName(String devName) {
2774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (devName == null) return false;
2775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!mWifiNative.setDeviceName(devName)) {
2777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to set device name " + devName);
2778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.deviceName = devName;
2782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
2783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Settings.Global.putString(mContext.getContentResolver(),
2785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_P2P_DEVICE_NAME, devName);
2786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendThisDeviceChangedBroadcast();
2787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
2791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean success;
2792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!wfdInfo.isWfdEnabled()) {
2794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            success = mWifiNative.setWfdEnable(false);
2795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
2796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            success =
2797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.setWfdEnable(true)
2798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                && mWifiNative.setWfdDeviceInfo(wfdInfo.getDeviceInfoHex());
2799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!success) {
2802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to set wfd properties");
2803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.wfdInfo = wfdInfo;
2807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendThisDeviceChangedBroadcast();
2808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void initializeP2pSettings() {
2812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setPersistentReconnect(true);
2813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.deviceName = getPersistedDeviceName();
2814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setDeviceName(mThisDevice.deviceName);
2815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // DIRECT-XY-DEVICENAME (XY is randomly generated)
2816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
2817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
2818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Supplicant defaults to using virtual display with display
2819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // which refers to a remote display. Use physical_display
2820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setConfigMethods("virtual_push_button physical_display keypad");
2821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // STA has higher priority over P2P
2822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setConcurrencyPriority("sta");
2823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
2825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updateThisDevice(WifiP2pDevice.AVAILABLE);
2826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("DeviceAddress: " + mThisDevice.deviceAddress);
2827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mClientInfoList.clear();
2829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pFlush();
2830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pServiceFlush();
2831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceTransactionId = 0;
2832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updatePersistentNetworks(RELOAD);
2835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void updateThisDevice(int status) {
2838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.status = status;
2839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendThisDeviceChangedBroadcast();
2840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleGroupCreationFailure() {
2843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resetWifiP2pInfo();
2844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.FAILED, null, null);
2845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendP2pConnectionChangedBroadcast();
2846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Remove only the peer we failed to connect to so that other devices discovered
2848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // that have not timed out still remain in list for connection
2849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean peersChanged = mPeers.remove(mPeersLostDuringConnection);
285084befe36af491f26ae46243017a1aca4dd5b24d5Vinit Deshpande        if (TextUtils.isEmpty(mSavedPeerConfig.deviceAddress) == false &&
28515c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                mPeers.remove(mSavedPeerConfig.deviceAddress) != null) {
2852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            peersChanged = true;
2853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (peersChanged) {
2855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendPeersChangedBroadcast();
2856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPeersLostDuringConnection.clear();
2859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(WifiP2pManager.DISCOVER_PEERS);
2861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleGroupRemoved() {
2864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mGroup.isGroupOwner()) {
2865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            stopDhcpServer(mGroup.getInterface());
2866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
28679ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline            if (DBG) logd("stop IpManager");
28689ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline            stopIpManager();
28696751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran            try {
28706751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                mNwService.removeInterfaceFromLocalNetwork(mGroup.getInterface());
28716751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran            } catch (RemoteException e) {
28726751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                loge("Failed to remove iface from local network " + e);
28736751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran            }
2874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
2877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.clearInterfaceAddresses(mGroup.getInterface());
2878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
2879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to clear addresses " + e);
2880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Clear any timeout that was set. This is essential for devices
2883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // that reuse the main p2p interface for a created group.
2884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
2885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean peersChanged = false;
2887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Remove only peers part of the group, so that other devices discovered
2888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // that have not timed out still remain in list for connection
2889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (WifiP2pDevice d : mGroup.getClientList()) {
2890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mPeers.remove(d)) peersChanged = true;
2891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mPeers.remove(mGroup.getOwner())) peersChanged = true;
2893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mPeers.remove(mPeersLostDuringConnection)) peersChanged = true;
2894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (peersChanged) {
2895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendPeersChangedBroadcast();
2896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mGroup = null;
2899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPeersLostDuringConnection.clear();
2900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
29025c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales        if (mTemporarilyDisconnectedWifi) {
2903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiChannel.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST, 0);
29045c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales            mTemporarilyDisconnectedWifi = false;
2905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
29069ed1f7b1a80aae513f3730869b614f66b6c79125Erik Kline    }
2907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //State machine initiated requests can have replyTo set to null indicating
2909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //there are no recipients, we ignore those reply actions
2910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what) {
2911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
2912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message dstMsg = obtainMessage(msg);
2913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.what = what;
2914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
2915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what, int arg1) {
2918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
2919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message dstMsg = obtainMessage(msg);
2920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.what = what;
2921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.arg1 = arg1;
2922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
2923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what, Object obj) {
2926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
2927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message dstMsg = obtainMessage(msg);
2928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.what = what;
2929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.obj = obj;
2930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
2931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* arg2 on the source message has a hash code that needs to be retained in replies
2934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * see WifiP2pManager for details */
2935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Message obtainMessage(Message srcMsg) {
2936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message msg = Message.obtain();
2937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.arg2 = srcMsg.arg2;
2938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return msg;
2939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    protected void logd(String s) {
2943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Slog.d(TAG, s);
2944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    protected void loge(String s) {
2948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Slog.e(TAG, s);
2949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Update service discovery request to wpa_supplicant.
2953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean updateSupplicantServiceRequest() {
2955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearSupplicantServiceRequest();
2956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        StringBuffer sb = new StringBuffer();
2958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (ClientInfo c: mClientInfoList.values()) {
2959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int key;
2960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pServiceRequest req;
2961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (int i=0; i < c.mReqList.size(); i++) {
2962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                req = c.mReqList.valueAt(i);
2963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (req != null) {
2964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sb.append(req.getSupplicantQuery());
2965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (sb.length() == 0) {
2970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
2974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
2975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Clear service discovery request in wpa_supplicant
2982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearSupplicantServiceRequest() {
2984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) return;
2985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pServDiscCancelReq(mServiceDiscReqId);
2987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* TODO: We could track individual service adds separately and avoid
2991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * having to do update all service requests on every new request
2992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean addServiceRequest(Messenger m, WifiP2pServiceRequest req) {
2994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearClientDeadChannels();
2995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, true);
2996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
2997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ++mServiceTransactionId;
3001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //The Wi-Fi p2p spec says transaction id should be non-zero
3002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceTransactionId == 0) ++mServiceTransactionId;
3003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        req.setTransactionId(mServiceTransactionId);
3004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mReqList.put(mServiceTransactionId, req);
3005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
3007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return true;
3008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return updateSupplicantServiceRequest();
3011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
3014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //Application does not have transaction id information
3020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //go through stored requests to remove
3021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean removed = false;
3022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (int i=0; i<clientInfo.mReqList.size(); i++) {
3023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (req.equals(clientInfo.mReqList.valueAt(i))) {
3024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                removed = true;
3025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                clientInfo.mReqList.removeAt(i);
3026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
3027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!removed) return;
3031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
3033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove client information from framework");
3034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
3038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updateSupplicantServiceRequest();
3042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearServiceRequests(Messenger m) {
3045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0) {
3052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mReqList.clear();
3056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mServList.size() == 0) {
3058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove channel information from framework");
3059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
3063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updateSupplicantServiceRequest();
3067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean addLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
3070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearClientDeadChannels();
3071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, true);
3072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
3074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!clientInfo.mServList.add(servInfo)) {
3077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
3078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!mWifiNative.p2pServiceAdd(servInfo)) {
3081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            clientInfo.mServList.remove(servInfo);
3082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
3083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
3086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void removeLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
3089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pServiceDel(servInfo);
3095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mServList.remove(servInfo);
3097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
3098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove client information from framework");
3099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearLocalServices(Messenger m) {
3104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (WifiP2pServiceInfo servInfo: clientInfo.mServList) {
3110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.p2pServiceDel(servInfo);
3111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mServList.clear();
3114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0) {
3115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove client information from framework");
3116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearClientInfo(Messenger m) {
3121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearLocalServices(m);
3122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearServiceRequests(m);
3123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Send the service response to the WifiP2pManager.Channel.
3127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param resp
3129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendServiceResponse(WifiP2pServiceResponse resp) {
3131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (ClientInfo c : mClientInfoList.values()) {
3132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pServiceRequest req = c.mReqList.get(resp.getTransactionId());
3133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (req != null) {
3134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Message msg = Message.obtain();
3135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.what = WifiP2pManager.RESPONSE_SERVICE;
3136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.arg1 = 0;
3137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.arg2 = 0;
3138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.obj = resp;
3139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
3140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    c.mMessenger.send(msg);
3141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (RemoteException e) {
3142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("detect dead channel");
3143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearClientInfo(c.mMessenger);
3144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return;
3145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * We dont get notifications of clients that have gone away.
3152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * We detect this actively when services are added and throw
3153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * them away.
3154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: This can be done better with full async channels.
3156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearClientDeadChannels() {
3158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
3159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (ClientInfo c : mClientInfoList.values()) {
3161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Message msg = Message.obtain();
3162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.what = WifiP2pManager.PING;
3163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.arg1 = 0;
3164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.arg2 = 0;
3165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.obj = null;
3166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
3167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                c.mMessenger.send(msg);
3168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException e) {
3169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("detect dead channel");
3170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                deadClients.add(c.mMessenger);
3171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (Messenger m : deadClients) {
3175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            clearClientInfo(m);
3176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Return the specified ClientInfo.
3181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param m Messenger
3182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param createIfNotExist if true and the specified channel info does not exist,
3183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * create new client info.
3184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return the specified ClientInfo.
3185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private ClientInfo getClientInfo(Messenger m, boolean createIfNotExist) {
3187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = mClientInfoList.get(m);
3188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null && createIfNotExist) {
3190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("add a new client");
3191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            clientInfo = new ClientInfo(m);
3192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.put(m, clientInfo);
3193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return clientInfo;
3196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Information about a particular client and we track the service discovery requests
3202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and the local services registered by the client.
3203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private class ClientInfo {
3205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
3207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * A reference to WifiP2pManager.Channel handler.
3208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * The response of this request is notified to WifiP2pManager.Channel handler
3209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
3210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private Messenger mMessenger;
3211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
3213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * A service discovery request list.
3214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
3215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private SparseArray<WifiP2pServiceRequest> mReqList;
3216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
3218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * A local service information list.
3219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
3220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private List<WifiP2pServiceInfo> mServList;
3221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private ClientInfo(Messenger m) {
3223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mMessenger = m;
3224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mReqList = new SparseArray();
3225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mServList = new ArrayList<WifiP2pServiceInfo>();
3226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
3229