WifiP2pServiceImpl.java revision eee1d479d8d402a2e78e2f143e957030cfc77749
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.app.Notification;
21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context;
22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.DialogInterface;
23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.DialogInterface.OnClickListener;
24155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Intent;
25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.pm.PackageManager;
26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.res.Configuration;
27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.res.Resources;
28155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.ConnectivityManager;
29155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.DhcpResults;
30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.DhcpStateMachine;
31155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.InterfaceConfiguration;
32155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.LinkAddress;
33155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkInfo;
34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.NetworkUtils;
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 Deshpandeimport java.util.Locale;
91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
94155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WifiP2pService includes a state machine to perform Wi-Fi p2p operations. Applications
95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * communicate with this service to issue device discovery and connectivity requests
96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * through the WifiP2pManager interface. The state machine communicates with the wifi
97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * driver through wpa_supplicant and handles the event responses through WifiMonitor.
98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Note that the term Wifi when used without a p2p suffix refers to the client mode
100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * of Wifi operation
101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * @hide
102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
103eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandepublic class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String TAG = "WifiP2pService";
105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final boolean DBG = false;
106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String NETWORKTYPE = "WIFI_P2P";
107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Context mContext;
109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Notification mNotification;
110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    INetworkManagementService mNwService;
112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private DhcpStateMachine mDhcpStateMachine;
113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private P2pStateMachine mP2pStateMachine;
115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mReplyChannel = new AsyncChannel();
116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private AsyncChannel mWifiChannel;
117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean JOIN_GROUP = true;
119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean FORM_GROUP = false;
120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean RELOAD = true;
122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final Boolean NO_RELOAD = false;
123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Two minutes comes from the wpa_supplicant setting */
125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static int mGroupCreatingTimeoutIndex = 0;
127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DISABLE_P2P_WAIT_TIME_MS = 5 * 1000;
129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static int mDisableP2pTimeoutIndex = 0;
130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Set a two minute discover timeout to avoid STA scans from being blocked */
132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DISCOVER_TIMEOUT_S = 120;
133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Idle time after a peer is gone when the group is torn down */
135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int GROUP_IDLE_TIME_S = 10;
136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Delayed message to timeout group creation */
140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 1;
141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User accepted a peer request */
143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 2;
144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User rejected a peer request */
145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 3;
146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User wants to disconnect wifi in favour of p2p */
147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DROP_WIFI_USER_ACCEPT          =   BASE + 4;
148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* User wants to keep his wifi connection and drop p2p */
149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final int DROP_WIFI_USER_REJECT          =   BASE + 5;
150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Delayed message to timeout p2p disable */
151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISABLE_P2P_TIMED_OUT           =   BASE + 6;
152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Commands to the WifiStateMachine */
155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int P2P_CONNECTION_CHANGED          =   BASE + 11;
156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* These commands are used to temporarily disconnect wifi when we detect
158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a frequency conflict which would make it impossible to have with p2p
159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and wifi active at the same time.
160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * If the user chooses to disable wifi temporarily, we keep wifi disconnected
162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * until the p2p connection is done and terminated at which point we will
163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * bring back wifi up
164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DISCONNECT_WIFI_REQUEST
166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *      msg.arg1 = 1 enables temporary disconnect and 0 disables it.
167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISCONNECT_WIFI_REQUEST         =   BASE + 12;
169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISCONNECT_WIFI_RESPONSE        =   BASE + 13;
170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int SET_MIRACAST_MODE               =   BASE + 14;
172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // During dhcp (and perhaps other times) we can't afford to drop packets
174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // but Discovery will switch our channel enough we will.
175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //   msg.arg1 = ENABLED for blocking, DISABLED for resumed.
176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //   msg.arg2 = msg to send when blocked
177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //   msg.obj  = StateMachine to send to when blocked
178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int BLOCK_DISCOVERY                 =   BASE + 15;
179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // set country code
181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int SET_COUNTRY_CODE                =   BASE + 16;
182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int ENABLED                         = 1;
184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static final int DISABLED                        = 0;
185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private final boolean mP2pSupported;
187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiP2pDevice mThisDevice = new WifiP2pDevice();
189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* When a group has been explicitly created by an app, we persist the group
191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * even after all clients have been disconnected until an explicit remove
192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * is invoked */
193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mAutonomousGroup;
194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Invitation to join an existing p2p group */
196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mJoinExistingGroup;
197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Track whether we are in p2p discovery. This is used to avoid sending duplicate
199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * broadcasts
200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDiscoveryStarted;
202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Track whether servcice/peer discovery is blocked in favor of other wifi actions
203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * (notably dhcp)
204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDiscoveryBlocked;
206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // Supplicant doesn't like setting the same country code multiple times (it may drop
208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    // current connected network), so we save the country code here to avoid redundency
209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mLastSetCountryCode;
210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /*
212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * remember if we were in a scan when it had to be stopped
213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean mDiscoveryPostponed = false;
215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private NetworkInfo mNetworkInfo;
217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2185c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    private boolean mTemporarilyDisconnectedWifi = false;
219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* The transaction Id of service discovery request */
221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private byte mServiceTransactionId = 0;
222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* Service discovery request ID of wpa_supplicant.
224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * null means it's not set yet. */
225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String mServiceDiscReqId;
226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* clients(application) information list. */
228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2308c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt    /* Is chosen as a unique address to avoid conflict with
2318c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt       the ranges defined in Tethering.java */
232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private static final String SERVER_ADDRESS = "192.168.49.1";
233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Error code definition.
236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * see the Table.8 in the WiFi Direct specification for the detail.
237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public static enum P2pStatus {
239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Success. */
240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        SUCCESS,
241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* The target device is currently unavailable. */
243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INFORMATION_IS_CURRENTLY_UNAVAILABLE,
244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Protocol error. */
246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INCOMPATIBLE_PARAMETERS,
247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* The target device reached the limit of the number of the connectable device.
249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * For example, device limit or group limit is set. */
250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        LIMIT_REACHED,
251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Protocol error. */
253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INVALID_PARAMETER,
254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Unable to accommodate request. */
256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        UNABLE_TO_ACCOMMODATE_REQUEST,
257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Previous protocol error, or disruptive behavior. */
259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        PREVIOUS_PROTOCOL_ERROR,
260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* There is no common channels the both devices can use. */
262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        NO_COMMON_CHANNEL,
263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *  but device B has removed the specified credential already. */
266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        UNKNOWN_P2P_GROUP,
267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        BOTH_GO_INTENT_15,
270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Incompatible provisioning method. */
272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        INCOMPATIBLE_PROVISIONING_METHOD,
273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Rejected by user */
275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        REJECTED_BY_USER,
276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Unknown error */
278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        UNKNOWN;
279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public static P2pStatus valueOf(int error) {
281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch(error) {
282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 0 :
283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return SUCCESS;
284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 1:
285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 2:
287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INCOMPATIBLE_PARAMETERS;
288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 3:
289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return LIMIT_REACHED;
290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 4:
291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INVALID_PARAMETER;
292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 5:
293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return UNABLE_TO_ACCOMMODATE_REQUEST;
294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 6:
295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return PREVIOUS_PROTOCOL_ERROR;
296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 7:
297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return NO_COMMON_CHANNEL;
298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 8:
299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return UNKNOWN_P2P_GROUP;
300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 9:
301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return BOTH_GO_INTENT_15;
302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 10:
303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return INCOMPATIBLE_PROVISIONING_METHOD;
304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case 11:
305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return REJECTED_BY_USER;
306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return UNKNOWN;
308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
312f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    /**
313f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * Handles client connections
314f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     */
315f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    private class ClientHandler extends Handler {
316f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
317f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        ClientHandler(android.os.Looper looper) {
318f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            super(looper);
319f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        }
320f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
321f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        @Override
322f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        public void handleMessage(Message msg) {
323f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            switch (msg.what) {
324f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.SET_DEVICE_NAME:
325f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.SET_WFD_INFO:
326f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.DISCOVER_PEERS:
327f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.STOP_DISCOVERY:
328f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CONNECT:
329f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CANCEL_CONNECT:
330f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CREATE_GROUP:
331f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REMOVE_GROUP:
332f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.START_LISTEN:
333f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.STOP_LISTEN:
334f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.SET_CHANNEL:
335f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.START_WPS:
336f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.ADD_LOCAL_SERVICE:
337f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REMOVE_LOCAL_SERVICE:
338f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CLEAR_LOCAL_SERVICES:
339f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.DISCOVER_SERVICES:
340f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.ADD_SERVICE_REQUEST:
341f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REMOVE_SERVICE_REQUEST:
342f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
343f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_PEERS:
344f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_CONNECTION_INFO:
345f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_GROUP_INFO:
346f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.DELETE_PERSISTENT_GROUP:
347f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
348f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                mP2pStateMachine.sendMessage(Message.obtain(msg));
349f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                break;
350f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann              default:
351f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
352f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann                break;
353f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            }
354f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        }
355f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    }
356f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    private ClientHandler mClientHandler;
357f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public WifiP2pServiceImpl(Context context) {
359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext = context;
360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                PackageManager.FEATURE_WIFI_DIRECT);
365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.primaryDeviceType = mContext.getResources().getString(
367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                com.android.internal.R.string.config_wifi_p2p_device_type);
368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
369f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        HandlerThread wifiP2pThread = new HandlerThread("WifiP2pService");
370f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        wifiP2pThread.start();
371f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        mClientHandler = new ClientHandler(wifiP2pThread.getLooper());
372f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
373f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        mP2pStateMachine = new P2pStateMachine(TAG, wifiP2pThread.getLooper(), mP2pSupported);
374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pStateMachine.start();
375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void connectivityServiceReady() {
378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNwService = INetworkManagementService.Stub.asInterface(b);
380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void enforceAccessPermission() {
383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "WifiP2pService");
385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void enforceChangePermission() {
388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "WifiP2pService");
390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void enforceConnectivityInternalPermission() {
393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.enforceCallingOrSelfPermission(
394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                android.Manifest.permission.CONNECTIVITY_INTERNAL,
395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "WifiP2pService");
396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
39807a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    private int checkConnectivityInternalPermission() {
39907a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        return mContext.checkCallingOrSelfPermission(
40007a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel                android.Manifest.permission.CONNECTIVITY_INTERNAL);
40107a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    }
40207a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel
40307a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    private int checkLocationHardwarePermission() {
40407a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        return mContext.checkCallingOrSelfPermission(
40507a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel                android.Manifest.permission.LOCATION_HARDWARE);
40607a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    }
40707a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel
40807a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    private void enforceConnectivityInternalOrLocationHardwarePermission() {
40907a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        if (checkConnectivityInternalPermission() != PackageManager.PERMISSION_GRANTED
41007a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel                && checkLocationHardwarePermission() != PackageManager.PERMISSION_GRANTED) {
41107a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel            enforceConnectivityInternalPermission();
41207a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        }
41307a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel    }
41407a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel
415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Get a reference to handler. This is used by a client to establish
417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * an AsyncChannel communication with WifiP2pService
418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public Messenger getMessenger() {
420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enforceAccessPermission();
421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enforceChangePermission();
422f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        return new Messenger(mClientHandler);
423f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    }
424f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann
425f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    /**
426f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * Get a reference to handler. This is used by a WifiStateMachine to establish
427f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * an AsyncChannel communication with P2pStateMachine
428f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     * @hide
429f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann     */
430f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann    public Messenger getP2pStateMachineMessenger() {
43107a55aa0236fc5d1b05c5d54c6ff8d42d881b4bbJoe Farfel        enforceConnectivityInternalOrLocationHardwarePermission();
432f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        enforceAccessPermission();
433f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        enforceChangePermission();
434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return new Messenger(mP2pStateMachine.getHandler());
435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /** This is used to provide information to drivers to optimize performance depending
438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * on the current mode of operation.
439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * 0 - disabled
440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * 1 - source operation
441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * 2 - sink operation
442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * As an example, the driver could reduce the channel dwell time during scanning
444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * when acting as a source or sink to minimize impact on miracast.
445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setMiracastMode(int mode) {
447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        enforceConnectivityInternalPermission();
448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pStateMachine.sendMessage(SET_MIRACAST_MODE, mode);
449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                != PackageManager.PERMISSION_GRANTED) {
455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + Binder.getCallingPid()
457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    + ", uid=" + Binder.getCallingUid());
458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mP2pStateMachine.dump(fd, pw, args);
461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mAutonomousGroup " + mAutonomousGroup);
462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mJoinExistingGroup " + mJoinExistingGroup);
463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mDiscoveryStarted " + mDiscoveryStarted);
464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mNetworkInfo " + mNetworkInfo);
4655c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales        pw.println("mTemporarilyDisconnectedWifi " + mTemporarilyDisconnectedWifi);
466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mServiceDiscReqId " + mServiceDiscReqId);
467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println();
468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Handles interaction with WifiStateMachine
473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private class P2pStateMachine extends StateMachine {
475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private DefaultState mDefaultState = new DefaultState();
477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Inactive is when p2p is enabled with no connectivity
483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private InactiveState mInactiveState = new InactiveState();
484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState
486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                = new UserAuthorizingInviteRequestState();
487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private UserAuthorizingNegotiationRequestState mUserAuthorizingNegotiationRequestState
488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                = new UserAuthorizingNegotiationRequestState();
489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private FrequencyConflictState mFrequencyConflictState =new FrequencyConflictState();
492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private OngoingGroupRemovalState mOngoingGroupRemovalState = new OngoingGroupRemovalState();
496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
49718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        private WifiNative mWifiNative = WifiNative.getP2pNativeInterface();
4984e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills        private WifiMonitor mWifiMonitor = WifiMonitor.getInstance();
499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* During a connection, supplicant can tell us that a device was lost. From a supplicant's
501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * perspective, the discovery stops during connection and it purges device since it does
502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * not get latest updates about the device without being in discovery state.
503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         *
504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * From the framework perspective, the device is still there since we are connecting or
505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * connected to it. so we keep these devices in a separate list, so that they are removed
506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * when connection is cancelled or lost
507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pDeviceList mPeersLostDuringConnection = new WifiP2pDeviceList();
509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new GroupDeleteListener() {
511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            @Override
512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            public void onDeleteGroup(int netId) {
513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("called onDeleteGroup() netId=" + netId);
514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.removeNetwork(netId);
515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.saveConfig();
516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendP2pPersistentGroupsChangedBroadcast();
517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        });
519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private WifiP2pGroup mGroup;
521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Saved WifiP2pConfig for an ongoing peer connection. This will never be null.
523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // The deviceAddress will be an empty string when the device is inactive
524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // or if it is connected without any ongoing join request
525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private WifiP2pConfig mSavedPeerConfig = new WifiP2pConfig();
526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Saved WifiP2pGroup from invitation request
528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private WifiP2pGroup mSavedP2pGroup;
529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
530f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann        P2pStateMachine(String name, Looper looper, boolean p2pSupported) {
531f933721551d39adc4924e5f69dcc51c16c520850Navtej Singh Mann            super(name, looper);
532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            addState(mDefaultState);
534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pNotSupportedState, mDefaultState);
535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pDisablingState, mDefaultState);
536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pDisabledState, mDefaultState);
537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pEnablingState, mDefaultState);
538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addState(mP2pEnabledState, mDefaultState);
539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mInactiveState, mP2pEnabledState);
540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mGroupCreatingState, mP2pEnabledState);
541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mUserAuthorizingInviteRequestState, mGroupCreatingState);
542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mUserAuthorizingNegotiationRequestState, mGroupCreatingState);
543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mProvisionDiscoveryState, mGroupCreatingState);
544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mGroupNegotiationState, mGroupCreatingState);
545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mFrequencyConflictState, mGroupCreatingState);
546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    addState(mGroupCreatedState, mP2pEnabledState);
547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        addState(mOngoingGroupRemovalState, mGroupCreatedState);
549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (p2pSupported) {
551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setInitialState(mP2pDisabledState);
552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setInitialState(mP2pNotSupportedState);
554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setLogRecSize(50);
556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            setLogOnlyTransitions(true);
5574e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills
5584e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            String interfaceName = mWifiNative.getInterfaceName();
5594e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5604e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.AP_STA_CONNECTED_EVENT, getHandler());
5614e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5624e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.AP_STA_DISCONNECTED_EVENT, getHandler());
5634e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5644e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.AUTHENTICATION_FAILURE_EVENT, getHandler());
5654e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5664e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.NETWORK_CONNECTION_EVENT, getHandler());
5674e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5684e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.NETWORK_DISCONNECTION_EVENT, getHandler());
5694e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5704e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_DEVICE_FOUND_EVENT, getHandler());
5714e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5724e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_DEVICE_LOST_EVENT, getHandler());
5734e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5744e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_FIND_STOPPED_EVENT, getHandler());
5754e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5764e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT, getHandler());
5774e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5784e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT, getHandler());
5794e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5804e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT, getHandler());
5814e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5824e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT, getHandler());
5834e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5844e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT, getHandler());
5854e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5864e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_REMOVED_EVENT, getHandler());
5874e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5884e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_GROUP_STARTED_EVENT, getHandler());
5894e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5904e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_INVITATION_RECEIVED_EVENT, getHandler());
5914e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5924e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_INVITATION_RESULT_EVENT, getHandler());
5934e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5944e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT, getHandler());
5954e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5964e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT, getHandler());
5974e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
5984e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT, getHandler());
5994e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6004e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT, getHandler());
6014e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6024e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT, getHandler());
6034e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6044e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.P2P_SERV_DISC_RESP_EVENT, getHandler());
6054e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6064e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SCAN_RESULTS_EVENT, getHandler());
6074e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6084e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SUP_CONNECTION_EVENT, getHandler());
6094e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6104e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SUP_DISCONNECTION_EVENT, getHandler());
6114e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6124e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, getHandler());
6134e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6144e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_FAIL_EVENT, getHandler());
6154e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6164e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_OVERLAP_EVENT, getHandler());
6174e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6184e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_SUCCESS_EVENT, getHandler());
6194e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills            mWifiMonitor.registerHandler(interfaceName,
6204e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    WifiMonitor.WPS_TIMEOUT_EVENT, getHandler());
621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class DefaultState extends State {
624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
626155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Full connection with WifiStateMachine established");
631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiChannel = (AsyncChannel) message.obj;
632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Full connection failure, error = " + message.arg1);
634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiChannel = null;
635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Send failed, client connection lost");
641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Client connection lost with reason: " + message.arg1);
643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiChannel = null;
645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    AsyncChannel ac = new AsyncChannel();
649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ac.connect(mContext, getHandler(), message.replyTo);
650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case BLOCK_DISCOVERY:
652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDiscoveryBlocked = (message.arg1 == ENABLED ? true : false);
653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // always reset this - we went to a state that doesn't support discovery so
654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // it would have stopped regardless
655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDiscoveryPostponed = false;
656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked) {
657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            StateMachine m = (StateMachine)message.obj;
659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            m.sendMessage(message.arg2);
660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (Exception e) {
661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("unable to send BLOCK_DISCOVERY response: " + e);
662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_PEERS:
666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_SERVICES:
674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CANCEL_CONNECT:
682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CREATE_GROUP:
686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_LOCAL_SERVICE:
694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_SERVICE_REQUEST:
706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_DEVICE_NAME:
720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_WFD_INFO:
728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_PEERS:
732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,
733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            new WifiP2pDeviceList(mPeers));
734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_CONNECTION_INFO:
736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            new WifiP2pInfo(mWifiP2pInfo));
738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_GROUP_INFO:
740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mGroup != null ? new WifiP2pGroup(mGroup) : null);
742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            new WifiP2pGroupList(mGroups, null));
746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_WPS:
748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pManager.BUSY);
750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
7515c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_REQUEST:
7525c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_SELECT:
7535c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.RESPONSE_GET_HANDOVER_MESSAGE, null);
7545c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
7555c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.INITIATOR_REPORT_NFC_HANDOVER:
7565c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.RESPONDER_REPORT_NFC_HANDOVER:
7575c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED,
7585c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            WifiP2pManager.BUSY);
7595c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Ignore
761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SCAN_RESULTS_EVENT:
763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_CONNECTION_EVENT:
766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_SUCCESS_EVENT:
770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_FAIL_EVENT:
771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_OVERLAP_EVENT:
772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.WPS_TIMEOUT_EVENT:
773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISCONNECT_WIFI_RESPONSE:
781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_ACCEPT:
782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_REJECT:
783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case GROUP_CREATING_TIMED_OUT:
784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISABLE_P2P_TIMED_OUT:
785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_ON_QUIT:
788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case SET_MIRACAST_MODE:
790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_CHANNEL:
793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case SET_COUNTRY_CODE:
794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Enable is lazy and has no response
797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // If we end up handling in default, p2p is not enabled
800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* unexpected group created, remove */
803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mGroup = (WifiP2pGroup) message.obj;
805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unexpected group creation, remove " + mGroup);
806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // A group formation failure is always followed by
809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // a group removed event. Flushing things at group formation
810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // failure causes supplicant issues. Ignore right now.
811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unhandled message " + message);
815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pNotSupportedState extends State {
822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case WifiP2pManager.DISCOVER_PEERS:
826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_SERVICES:
834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CANCEL_CONNECT:
842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
844155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case WifiP2pManager.CREATE_GROUP:
846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_LOCAL_SERVICE:
854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_SERVICE_REQUEST:
866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
868155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
875155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message,
876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_DEVICE_NAME:
880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_WFD_INFO:
888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_WPS:
892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED,
897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED,
901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.P2P_UNSUPPORTED);
902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pDisablingState extends State {
912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(DISABLE_P2P_TIMED_OUT,
916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mDisableP2pTimeoutIndex, 0), DISABLE_P2P_WAIT_TIME_MS);
917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("p2p socket connection lost");
925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisabledState);
926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISABLE_P2P_TIMED_OUT:
93297a856eb1fda1585316055bd4912f0000deccb52Yuhao Zheng                    if (mDisableP2pTimeoutIndex == message.arg1) {
933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("P2p disable timed out");
934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mP2pDisabledState);
935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pDisabledState extends State {
950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande       @Override
951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    try {
96118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                        mNwService.setInterfaceUp(mWifiNative.getInterfaceName());
962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (RemoteException re) {
963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unable to change interface settings: " + re);
964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } catch (IllegalStateException ie) {
965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unable to change interface settings: " + ie);
966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
9674e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    mWifiMonitor.startMonitoring(mWifiNative.getInterfaceName());
968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pEnablingState);
969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pEnablingState extends State {
978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_CONNECTION_EVENT:
988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("P2p socket connection successful");
989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("P2p socket connection failed");
993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisabledState);
994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class P2pEnabledState extends State {
1007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pStateChangedBroadcast(true);
1011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setIsAvailable(true);
1012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pConnectionChangedBroadcast();
1013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            initializeP2pSettings();
1014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.SUP_DISCONNECTION_EVENT:
1021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Unexpected loss of p2p socket connection");
1022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisabledState);
1023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_ENABLE_P2P:
1025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Nothing to do
1026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
1028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mPeers.clear()) {
1029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
1032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
10334e210ea1c7eb7d3a70792571651181e429b39582Mitchell Wills                    mWifiMonitor.stopMonitoring(mWifiNative.getInterfaceName());
1034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mP2pDisablingState);
1035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_DEVICE_NAME:
1037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                {
1038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("set device name " + d.deviceName);
1041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
1042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
1044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_WFD_INFO:
1049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                {
1050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
1051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (d != null && setWfdInfo(d)) {
1052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
1053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
1055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
1059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case BLOCK_DISCOVERY:
1060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean blocked = (message.arg1 == ENABLED ? true : false);
1061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked == blocked) break;
1062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mDiscoveryBlocked = blocked;
1063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (blocked && mDiscoveryStarted) {
1064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pStopFind();
1065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDiscoveryPostponed = true;
1066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!blocked && mDiscoveryPostponed) {
1068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDiscoveryPostponed = false;
1069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pFind(DISCOVER_TIMEOUT_S);
1070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (blocked) {
1072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        try {
1073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            StateMachine m = (StateMachine)message.obj;
1074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            m.sendMessage(message.arg2);
1075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } catch (Exception e) {
1076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            loge("unable to send BLOCK_DISCOVERY response: " + e);
1077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_PEERS:
1081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked) {
1082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.BUSY);
1084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // do not send service discovery request while normal find operation.
1087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearSupplicantServiceRequest();
1088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
1089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
1090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendP2pDiscoveryChangedBroadcast(true);
1091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
1097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendP2pDiscoveryChangedBroadcast(false);
1098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
1100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pStopFind()) {
1101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
1102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
1104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_SERVICES:
1108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mDiscoveryBlocked) {
1109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
1110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.BUSY);
1111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " discover services");
1114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!updateSupplicantServiceRequest()) {
1115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
1116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.NO_SERVICE_REQUESTS);
1117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
1120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED);
1121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
1123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
1127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;
1129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateSupplicantDetails(device);
1130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = (WifiP2pDevice) message.obj;
1134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Gets current details for the one removed
1135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = mPeers.remove(device.deviceAddress);
1136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (device != null) {
1137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_LOCAL_SERVICE:
1141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " add service");
1142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)message.obj;
1143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (addLocalService(message.replyTo, servInfo)) {
1144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
1145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED);
1147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
1150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " remove service");
1151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    servInfo = (WifiP2pServiceInfo)message.obj;
1152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    removeLocalService(message.replyTo, servInfo);
1153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED);
1154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
1156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " clear service");
1157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearLocalServices(message.replyTo);
1158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_SUCCEEDED);
1159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.ADD_SERVICE_REQUEST:
1161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " add service request");
1162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!addServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj)) {
1163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED);
1164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED);
1167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
1169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " remove service request");
1170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    removeServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj);
1171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED);
1172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
1174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " clear service request");
1175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearServiceRequests(message.replyTo);
1176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED);
1177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
1179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " receive service response");
1180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    List<WifiP2pServiceResponse> sdRespList =
1181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        (List<WifiP2pServiceResponse>) message.obj;
1182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    for (WifiP2pServiceResponse resp : sdRespList) {
1183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pDevice dev =
1184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mPeers.get(resp.getSrcDevice().deviceAddress);
1185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        resp.setSrcDevice(dev);
1186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendServiceResponse(resp);
1187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
1190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   if (DBG) logd(getName() + " delete persistent group");
1191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   mGroups.remove(message.arg1);
1192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
1193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   break;
1194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case SET_MIRACAST_MODE:
1195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.setMiracastMode(message.arg1);
1196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
1198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " start listen mode");
1199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(true, 500, 500)) {
1201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
1202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
1204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
1207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " stop listen mode");
1208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(false, 0, 0)) {
1209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
1210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
1212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_CHANNEL:
1216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Bundle p2pChannels = (Bundle) message.obj;
1217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int lc = p2pChannels.getInt("lc", 0);
1218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int oc = p2pChannels.getInt("oc", 0);
1219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " set listen and operating channel");
1220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pSetChannel(lc, oc)) {
1221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
1222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
1224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case SET_COUNTRY_CODE:
1227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    String countryCode = (String) message.obj;
1228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    countryCode = countryCode.toUpperCase(Locale.ROOT);
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mLastSetCountryCode == null ||
1230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            countryCode.equals(mLastSetCountryCode) == false) {
1231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mWifiNative.setCountryCode(countryCode)) {
1232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mLastSetCountryCode = countryCode;
1233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
12365c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_REQUEST:
12375c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    Bundle requestBundle = new Bundle();
12385c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    requestBundle.putString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE,
12395c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            mWifiNative.getNfcHandoverRequest());
12405c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.RESPONSE_GET_HANDOVER_MESSAGE,
12415c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            requestBundle);
12425c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
12435c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.GET_HANDOVER_SELECT:
12445c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    Bundle selectBundle = new Bundle();
12455c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    selectBundle.putString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE,
12465c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            mWifiNative.getNfcHandoverSelect());
12475c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    replyToMessage(message, WifiP2pManager.RESPONSE_GET_HANDOVER_MESSAGE,
12485c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            selectBundle);
12495c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
1250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   return NOT_HANDLED;
1252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pDiscoveryChangedBroadcast(false);
1259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pStateChangedBroadcast(false);
1260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setIsAvailable(false);
1261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mLastSetCountryCode = null;
1263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class InactiveState extends State {
1267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSavedPeerConfig.invalidate();
1271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
1278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " sending connect");
1279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
1280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
1281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping connect requeset " + config);
1282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
1283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = false;
1287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (reinvokePersistentGroup(config)) {
1289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mProvisionDiscoveryState);
1292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
1294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_DISCOVERY:
1299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pStopFind()) {
1300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // When discovery stops in inactive state, flush to clear
1301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // state peer data
1302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pFlush();
1303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mServiceDiscReqId = null;
1304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
1311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = (WifiP2pConfig) message.obj;
1312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
1313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping GO neg request " + config);
1314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = false;
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mJoinExistingGroup = false;
1319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUserAuthorizingNegotiationRequestState);
1320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice owner = group.getOwner();
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (owner == null) {
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Ignored invitation from null owner");
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config = new WifiP2pConfig();
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config.deviceAddress = group.getOwner().deviceAddress;
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
1334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping invitation request " + config);
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Check if we have the owner in peer list and use appropriate
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //wps method. Default is to use PBC.
1341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if ((owner = mPeers.get(owner.deviceAddress)) != null) {
1342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (owner.wpsPbcSupported()) {
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mSavedPeerConfig.wps.setup = WpsInfo.PBC;
1344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else if (owner.wpsKeypadSupported()) {
1345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
1346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else if (owner.wpsDisplaySupported()) {
1347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
1348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = false;
1352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mJoinExistingGroup = true;
1353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUserAuthorizingInviteRequestState);
1354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
1356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //We let the supplicant handle the provision discovery response
1359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //and wait instead for the GO_NEGOTIATION_REQUEST_EVENT.
1360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Handling provision discovery and issuing a p2p_connect before
1361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //group negotiation comes through causes issues
1362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CREATE_GROUP:
1364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mAutonomousGroup = true;
1365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int netId = message.arg1;
1366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean ret = false;
1367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // check if the go persistent group is present.
1369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
1370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (netId != -1) {
1371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ret = mWifiNative.p2pGroupAdd(netId);
1372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ret = mWifiNative.p2pGroupAdd(true);
1374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = mWifiNative.p2pGroupAdd(false);
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (ret) {
1380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
1384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // remain at this state.
1386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mGroup = (WifiP2pGroup) message.obj;
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " group started");
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // We hit this scenario when a persistent group is reinvoked
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mAutonomousGroup = false;
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        deferMessage(message);
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Unexpected group creation, remove " + mGroup);
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_LISTEN:
1403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " start listen mode");
1404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(true, 500, 500)) {
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
1407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.STOP_LISTEN:
1412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " stop listen mode");
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pExtListen(false, 0, 0)) {
1414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
1415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
1417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pFlush();
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.SET_CHANNEL:
1421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Bundle p2pChannels = (Bundle) message.obj;
1422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int lc = p2pChannels.getInt("lc", 0);
1423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    int oc = p2pChannels.getInt("oc", 0);
1424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " set listen and operating channel");
1425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pSetChannel(lc, oc)) {
1426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
1427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
1429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
14315c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.INITIATOR_REPORT_NFC_HANDOVER:
14325c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    String handoverSelect = null;
14335c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14345c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (message.obj != null) {
14355c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        handoverSelect = ((Bundle) message.obj)
14365c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                                .getString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE);
14375c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14385c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14395c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (handoverSelect != null
14405c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            && mWifiNative.initiatorReportNfcHandover(handoverSelect)) {
14415c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_SUCCEEDED);
14425c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        transitionTo(mGroupCreatingState);
14435c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    } else {
14445c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED);
14455c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14465c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
14475c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiP2pManager.RESPONDER_REPORT_NFC_HANDOVER:
14485c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    String handoverRequest = null;
14495c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14505c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (message.obj != null) {
14515c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        handoverRequest = ((Bundle) message.obj)
14525c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                                .getString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE);
14535c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14545c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
14555c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    if (handoverRequest != null
14565c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                            && mWifiNative.responderReportNfcHandover(handoverRequest)) {
14575c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_SUCCEEDED);
14585c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        transitionTo(mGroupCreatingState);
14595c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    } else {
14605c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                        replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED);
14615c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    }
14625c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
1463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class GroupCreatingState extends State {
1471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
1475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
1476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
1482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande               case GROUP_CREATING_TIMED_OUT:
1484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroupCreatingTimeoutIndex == message.arg1) {
1485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Group negotiation timed out");
1486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleGroupCreationFailure();
1487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInactiveState);
1488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
1491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
1493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) {
1494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            logd("mSavedPeerConfig " + mSavedPeerConfig.deviceAddress +
1495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                "device " + device.deviceAddress);
1496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Do the regular device lost handling
1498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = NOT_HANDLED;
1499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Do nothing
1502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("Add device to lost list " + device);
1503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeersLostDuringConnection.updateSupplicantDetails(device);
1504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.DISCOVER_PEERS:
1506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* Discovery will break negotiation */
1507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
1508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.BUSY);
1509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CANCEL_CONNECT:
1511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Do a supplicant p2p_cancel which only cancels an ongoing
1512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //group negotiation. This will fail for a pending provision
1513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //discovery or for a pending user action, but at the framework
1514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //level, we always treat cancel as succeeded and enter
1515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //an inactive state
1516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pCancelConnect();
1517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
1520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
15215c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
15225c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    // We hit this scenario when NFC handover is invoked.
15235c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    mAutonomousGroup = false;
15245c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    transitionTo(mGroupNegotiationState);
15255c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    break;
1526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    ret = NOT_HANDLED;
1528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
1530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UserAuthorizingNegotiationRequestState extends State {
1534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationReceived();
1538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
1544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
1546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
1547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    p2pConnectWithPinDisplay(mSavedPeerConfig);
1548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupNegotiationState);
1551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   break;
1552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
1553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("User rejected negotiation " + mSavedPeerConfig);
1554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
1560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: dismiss dialog if not already done
1565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UserAuthorizingInviteRequestState extends State {
1569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationReceived();
1573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            boolean ret = HANDLED;
1579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
1581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
1582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!reinvokePersistentGroup(mSavedPeerConfig)) {
1583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Do negotiation when persistence fails
1584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
1587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendPeersChangedBroadcast();
1588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupNegotiationState);
1589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                   break;
1590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
1591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
1592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return ret;
1598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: dismiss dialog if not already done
1603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class ProvisionDiscoveryState extends State {
1609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
1613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pProvDiscEvent provDisc;
1619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pDevice device;
1620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
1622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = provDisc.device;
1624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1626155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
1627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
1633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = provDisc.device;
1635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
1638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /* we already have the pin */
1640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
1641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            p2pConnectWithPinDisplay(mSavedPeerConfig);
1642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            transitionTo(mGroupNegotiationState);
1643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mJoinExistingGroup = false;
1645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            transitionTo(mUserAuthorizingNegotiationRequestState);
1646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
1650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    provDisc = (WifiP2pProvDiscEvent) message.obj;
1651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = provDisc.device;
1652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
1653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
1655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Found a match " + mSavedPeerConfig);
1656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.pin = provDisc.pin;
1657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        notifyInvitationSent(provDisc.pin, device.deviceAddress);
1659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mGroupNegotiationState);
1660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
1663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("provision discovery failed");
1664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class GroupNegotiationState extends State {
1675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // We ignore these right now, since we get a GROUP_STARTED notification
1685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // afterwards
1686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
1687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
1688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " go success");
1689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mGroup = (WifiP2pGroup) message.obj;
1692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " group started");
1693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
1695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /*
1696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * update cache information and set network id to mGroup.
1697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         */
1698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        updatePersistentNetworks(NO_RELOAD);
1699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        String devAddr = mGroup.getOwner().deviceAddress;
1700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
1701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mGroup.getNetworkName()));
1702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.isGroupOwner()) {
1705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        /* Setting an idle time out on GO causes issues with certain scenarios
1706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * on clients where it can be off-channel for longer and with the power
1707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * save modes used.
1708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         *
1709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * TODO: Verify multi-channel scenarios and supplicant behavior are
1710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         * better before adding a time out in future
1711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                         */
1712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        //Set group idle timeout of 10 sec, to avoid GO beaconing incase of any
1713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        //failure during 4-way Handshake.
1714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (!mAutonomousGroup) {
1715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
1716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        startDhcpServer(mGroup.getInterface());
1718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
1720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
1721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                P2pStateMachine.this, mGroup.getInterface());
1722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // TODO: We should use DHCP state machine PRE message like WifiStateMachine
1723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), false);
1724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
1725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pDevice groupOwner = mGroup.getOwner();
1726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        WifiP2pDevice peer = mPeers.get(groupOwner.deviceAddress);
1727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (peer != null) {
1728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // update group owner details with peer details found at discovery
1729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            groupOwner.updateSupplicantDetails(peer);
1730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
1731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendPeersChangedBroadcast();
1732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // A supplicant bug can lead to reporting an invalid
1734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // group owner address (all zeroes) at times. Avoid a
1735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // crash, but continue group creation since it is not
1736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // essential.
1737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            logw("Unknown group owner " + groupOwner);
1738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupCreatedState);
1741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
1743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    P2pStatus status = (P2pStatus) message.obj;
1744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.NO_COMMON_CHANNEL) {
1745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mFrequencyConflictState);
1746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    /* continue with group removal handling */
1749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " go failure");
1751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // A group formation failure is always followed by
1755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // a group removed event. Flushing things at group formation
1756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // failure causes supplicant issues. Ignore right now.
1757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
1758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    status = (P2pStatus) message.obj;
1759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.NO_COMMON_CHANNEL) {
1760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mFrequencyConflictState);
1761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
1765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    status = (P2pStatus)message.obj;
1766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.SUCCESS) {
1767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // invocation was succeeded.
1768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // wait P2P_GROUP_STARTED_EVENT.
1769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
1770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Invitation result " + status);
1772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
1773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // target device has already removed the credential.
1774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // So, remove this credential accordingly.
1775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        int netId = mSavedPeerConfig.netId;
1776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (netId >= 0) {
1777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Remove unknown client from the list");
1778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
1779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Reinvocation has failed, try group negotiation
1782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
1783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (status == P2pStatus.INFORMATION_IS_CURRENTLY_UNAVAILABLE) {
1785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // Devices setting persistent_reconnect to 0 in wpa_supplicant
1787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // always defer the invocation request and return
1788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // "information is currently unable" error.
1789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // So, try another way to connect for interoperability.
1790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
1791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        p2pConnectWithPinDisplay(mSavedPeerConfig);
1792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (status == P2pStatus.NO_COMMON_CHANNEL) {
1793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mFrequencyConflictState);
1794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleGroupCreationFailure();
1796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInactiveState);
1797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class FrequencyConflictState extends State {
1807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private AlertDialog mFrequencyConflictDialog;
1808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyFrequencyConflict();
1812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private void notifyFrequencyConflict() {
1815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            logd("Notify frequency conflict");
1816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Resources r = Resources.getSystem();
1817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            AlertDialog dialog = new AlertDialog.Builder(mContext)
1819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setMessage(r.getString(R.string.wifi_p2p_frequency_conflict_message,
1820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        getDeviceName(mSavedPeerConfig.deviceAddress)))
1821155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setPositiveButton(r.getString(R.string.dlg_ok), new OnClickListener() {
1822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
1823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
1824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(DROP_WIFI_USER_ACCEPT);
1825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
1827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
1828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
1829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
1830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(DROP_WIFI_USER_REJECT);
1831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
1833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .setOnCancelListener(new DialogInterface.OnCancelListener() {
1834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
1835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onCancel(DialogInterface arg0) {
1836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(DROP_WIFI_USER_REJECT);
1837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
1839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .create();
1840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1841155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
1842123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber            WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
1843123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber            attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
1844123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber            dialog.getWindow().setAttributes(attrs);
1845155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dialog.show();
1846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mFrequencyConflictDialog = dialog;
1847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
1854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
1855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge(getName() + "group sucess during freq conflict!");
1856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
1858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge(getName() + "group started after freq conflict, handle anyway");
1859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
1860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupNegotiationState);
1861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
1863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
1864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
1865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Ignore failures since we retry again
1866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_REJECT:
1868155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // User rejected dropping wifi in favour of p2p
1869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupCreationFailure();
1870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DROP_WIFI_USER_ACCEPT:
1873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // User accepted dropping wifi in favour of p2p
1874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiChannel.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST, 1);
18755c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                    mTemporarilyDisconnectedWifi = true;
1876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1877155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DISCONNECT_WIFI_RESPONSE:
1878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Got a response from wifistatemachine, retry p2p
1879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + "Wifi disconnected, retry p2p");
1880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
1881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
1882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
1884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
1885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
1887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
1890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mFrequencyConflictDialog != null) mFrequencyConflictDialog.dismiss();
1891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class GroupCreatedState extends State {
1895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
1897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
1898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // Once connected, peer config details are invalid
1899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mSavedPeerConfig.invalidate();
1900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
1901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            updateThisDevice(WifiP2pDevice.CONNECTED);
1903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //DHCP server has already been started if I am a group owner
1905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mGroup.isGroupOwner()) {
1906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                setWifiP2pInfoOnGroupFormation(NetworkUtils.numericToInetAddress(SERVER_ADDRESS));
1907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // In case of a negotiation group, connection changed is sent
1910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // after a client joins. For autonomous, send now
1911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mAutonomousGroup) {
1912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                sendP2pConnectionChangedBroadcast();
1913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
1914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
1917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
1918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
1919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
1920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AP_STA_CONNECTED_EVENT:
1921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
1922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    String deviceAddress = device.deviceAddress;
1923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Clear timeout that was set when group was started.
1924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
1925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (deviceAddress != null) {
1926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mPeers.get(deviceAddress) != null) {
1927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mGroup.addClient(mPeers.get(deviceAddress));
1928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            mGroup.addClient(deviceAddress);
1930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED);
1932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd(getName() + " ap sta connected");
1933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Connect on null device address, ignore");
1936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendP2pConnectionChangedBroadcast();
1938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
1940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = (WifiP2pDevice) message.obj;
1941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deviceAddress = device.deviceAddress;
1942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (deviceAddress != null) {
1943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
1944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (mGroup.removeClient(deviceAddress)) {
1945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Removed client " + deviceAddress);
1946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (!mAutonomousGroup && mGroup.isClientListEmpty()) {
1947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                logd("Client list empty, remove non-persistent p2p group");
1948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
1949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // We end up sending connection changed broadcast
1950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // when this happens at exit()
1951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            } else {
1952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // Notify when a client disconnects from group
1953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                sendP2pConnectionChangedBroadcast();
1954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
1955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
1956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Failed to remove client " + deviceAddress);
1957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            for (WifiP2pDevice c : mGroup.getClientList()) {
1958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                if (DBG) logd("client " + c.deviceAddress);
1959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
1960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
1961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
1962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd(getName() + " ap sta disconnected");
1963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Disconnect on unknown device: " + device);
1965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
1968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    DhcpResults dhcpResults = (DhcpResults) message.obj;
1969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
1970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            dhcpResults != null) {
1971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("DhcpResults: " + dhcpResults);
1972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        setWifiP2pInfoOnGroupFormation(dhcpResults.serverAddress);
1973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendP2pConnectionChangedBroadcast();
1974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        //Turn on power save on client
1975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
19766751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                        try {
19773b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                            String iface = mGroup.getInterface();
19783b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                            mNwService.addInterfaceToLocalNetwork(iface,
19793b26801d62a06475b722bbf29cba7f48f376654eLorenzo Colitti                                                                  dhcpResults.getRoutes(iface));
19806751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                        } catch (RemoteException e) {
19816751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                            loge("Failed to add iface to local network " + e);
19826751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                        }
1983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("DHCP failed");
1985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
1986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
1988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
1989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " remove group");
1990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
1991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mOngoingGroupRemovalState);
1992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
1993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
1994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        handleGroupRemoved();
1995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        transitionTo(mInactiveState);
1996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
1997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
1998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
1999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                /* We do not listen to NETWORK_DISCONNECTION_EVENT for group removal
2001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * handling since supplicant actually tries to reconnect after a temporary
2002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * disconnect until group idle time out. Eventually, a group removal event
2003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * will come when group has been removed.
2004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 *
2005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * When there are connectivity issues during temporary disconnect, the application
2006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * will also just remove the group.
2007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 *
2008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * Treating network disconnection as group removal causes race conditions since
2009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * supplicant would still maintain the group at that stage.
2010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 */
2011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
2012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd(getName() + " group removed");
2013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    handleGroupRemoved();
2014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mInactiveState);
2015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
2017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    device = (WifiP2pDevice) message.obj;
2018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Device loss for a connected device indicates it is not in discovery any more
2019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mGroup.contains(device)) {
2020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (DBG) logd("Add device to lost list " + device);
2021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeersLostDuringConnection.updateSupplicantDetails(device);
2022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return HANDLED;
2023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Do the regular device lost handling
2025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
2027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sendMessage(WifiP2pManager.REMOVE_GROUP);
2028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    deferMessage(message);
2029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // This allows any client to join the GO during the
2031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // WPS window
2032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.START_WPS:
2033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WpsInfo wps = (WpsInfo) message.obj;
2034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (wps == null) {
2035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.START_WPS_FAILED);
2036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
2037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    boolean ret = true;
2039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (wps.setup == WpsInfo.PBC) {
2040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        ret = mWifiNative.startWpsPbc(mGroup.getInterface(), null);
2041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (wps.pin == null) {
2043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
2044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            try {
2045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                Integer.parseInt(pin);
2046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                notifyInvitationSent(pin, "any");
2047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            } catch (NumberFormatException ignore) {
2048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                ret = false;
2049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
2050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        } else {
2051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            ret = mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
2052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    wps.pin);
2053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, ret ? WifiP2pManager.START_WPS_SUCCEEDED :
2056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            WifiP2pManager.START_WPS_FAILED);
2057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.CONNECT:
2059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
2060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (isConfigInvalid(config)) {
2061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        loge("Dropping connect requeset " + config);
2062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
2063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
2064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    logd("Inviting device : " + config.deviceAddress);
2066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = config;
2067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
2068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
2069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendPeersChangedBroadcast();
2070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
2071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
2073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                WifiP2pManager.ERROR);
2074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // TODO: figure out updating the status to declined when invitation is rejected
2076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
2078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    P2pStatus status = (P2pStatus)message.obj;
2079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.SUCCESS) {
2080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // invocation was succeeded.
2081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        break;
2082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Invitation result " + status);
2084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
2085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // target device has already removed the credential.
2086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        // So, remove this credential accordingly.
2087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        int netId = mGroup.getNetworkId();
2088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        if (netId >= 0) {
2089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd("Remove unknown client from the list");
2090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (!removeClientFromList(netId,
2091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                    mSavedPeerConfig.deviceAddress, false)) {
2092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                // not found the client on the list
2093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                loge("Already removed the client, ignore");
2094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                break;
2095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
2096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            // try invitation.
2097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
2098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
2102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
2103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
2104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
2105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig = new WifiP2pConfig();
2106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
2107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
2108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
2109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
2110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
2111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.pin = provDisc.pin;
2112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
2114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mUserAuthorizingJoinState);
2116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
2118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("Duplicate group creation event notice, ignore");
2119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
2121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
2124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
2127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            updateThisDevice(WifiP2pDevice.AVAILABLE);
2128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            resetWifiP2pInfo();
2129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
2130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pConnectionChangedBroadcast();
2131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class UserAuthorizingJoinState extends State {
2135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
2137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
2138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationReceived();
2139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
2143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
2144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
2145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
2146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
2147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
2148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Ignore more client requests
2149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_ACCEPT:
2151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    //Stop discovery to avoid failure due to channel switch
2152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    mWifiNative.p2pStopFind();
2153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
2154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startWpsPbc(mGroup.getInterface(), null);
2155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    } else {
2156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
2157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mSavedPeerConfig.wps.pin);
2158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupCreatedState);
2160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case PEER_CONNECTION_USER_REJECT:
2162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("User rejected incoming request");
2163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    transitionTo(mGroupCreatedState);
2164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
2166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
2169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void exit() {
2173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            //TODO: dismiss dialog if not already done
2174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    class OngoingGroupRemovalState extends State {
2178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public void enter() {
2180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName());
2181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        @Override
2184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        public boolean processMessage(Message message) {
2185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd(getName() + message.toString());
2186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            switch (message.what) {
2187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Group removal ongoing. Multiple calls
2188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // end up removing persisted network. Do nothing.
2189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                case WifiP2pManager.REMOVE_GROUP:
2190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
2191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    break;
2192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Parent state will transition out of this state
2193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // when removal is complete
2194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                default:
2195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return NOT_HANDLED;
2196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return HANDLED;
2198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        super.dump(fd, pw, args);
2204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mWifiP2pInfo " + mWifiP2pInfo);
2205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mGroup " + mGroup);
2206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mSavedPeerConfig " + mSavedPeerConfig);
2207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println("mSavedP2pGroup " + mSavedP2pGroup);
2208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        pw.println();
2209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pStateChangedBroadcast(boolean enabled) {
2212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
2213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (enabled) {
2215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
2216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
2217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
2218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
2219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
2220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pDiscoveryChangedBroadcast(boolean started) {
2225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mDiscoveryStarted == started) return;
2226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mDiscoveryStarted = started;
2227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("discovery change broadcast " + started);
2229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
2231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, started ?
2233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED :
2234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
2235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendThisDeviceChangedBroadcast() {
2239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
2240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
2242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendPeersChangedBroadcast() {
2246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
2247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, new WifiP2pDeviceList(mPeers));
2248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
2250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pConnectionChangedBroadcast() {
2253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("sending p2p connection changed broadcast");
2254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
2255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
2256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
2257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
2258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
2259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, new WifiP2pGroup(mGroup));
2260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiChannel.sendMessage(WifiP2pServiceImpl.P2P_CONNECTION_CHANGED,
2262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                new NetworkInfo(mNetworkInfo));
2263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendP2pPersistentGroupsChangedBroadcast() {
2266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("sending p2p persistent groups changed broadcast");
2267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
2268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void startDhcpServer(String intf) {
2273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        InterfaceConfiguration ifcg = null;
2274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
2275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg = mNwService.getInterfaceConfig(intf);
2276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
2277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        SERVER_ADDRESS), 24));
2278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            ifcg.setInterfaceUp();
2279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.setInterfaceConfig(intf, ifcg);
2280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* This starts the dnsmasq server */
22818c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
22828c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                    Context.CONNECTIVITY_SERVICE);
22838c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            String[] tetheringDhcpRanges = cm.getTetheredDhcpRanges();
22848c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            if (mNwService.isTetheringStarted()) {
22858c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                if (DBG) logd("Stop existing tethering and restart it");
22868c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                mNwService.stopTethering();
22878c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            }
22888c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            mNwService.tetherInterface(intf);
22898c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            mNwService.startTethering(tetheringDhcpRanges);
2290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
2291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Error configuring interface " + intf + ", :" + e);
2292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
2293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        logd("Started Dhcp server on " + intf);
2296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande   }
2297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void stopDhcpServer(String intf) {
2299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
23008c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            mNwService.untetherInterface(intf);
23018c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            for (String temp : mNwService.listTetheredInterfaces()) {
23028c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                logd("List all interfaces " + temp);
23038c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                if (temp.compareTo(intf) != 0) {
23048c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                    logd("Found other tethering interfaces, so keep tethering alive");
23058c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                    return;
23068c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt                }
23078c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            }
2308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.stopTethering();
2309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
2310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Error stopping Dhcp server" + e);
2311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
23128c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt        } finally {
23138c2ff3f4bfa8d5a1f8c9dd6e74aa9a404452d85dRobert Greenwalt            logd("Stopped Dhcp server");
2314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyP2pEnableFailure() {
2318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        AlertDialog dialog = new AlertDialog.Builder(mContext)
2320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
2321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
2322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setPositiveButton(r.getString(R.string.ok), null)
2323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .create();
2324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2325123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
2326123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2327123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        dialog.getWindow().setAttributes(attrs);
2328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.show();
2329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void addRowToDialog(ViewGroup group, int stringId, String value) {
2332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
2334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group, false);
2335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
2336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ((TextView) row.findViewById(R.id.value)).setText(value);
2337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        group.addView(row);
2338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyInvitationSent(String pin, String peerAddress) {
2341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final View textEntryView = LayoutInflater.from(mContext)
2344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .inflate(R.layout.wifi_p2p_dialog, null);
2345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
2347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
2348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
2349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        AlertDialog dialog = new AlertDialog.Builder(mContext)
2351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
2352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setView(textEntryView)
2353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setPositiveButton(r.getString(R.string.ok), null)
2354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .create();
2355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2356123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
2357123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2358123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        dialog.getWindow().setAttributes(attrs);
2359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.show();
2360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void notifyInvitationReceived() {
2363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Resources r = Resources.getSystem();
2364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final WpsInfo wps = mSavedPeerConfig.wps;
2365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final View textEntryView = LayoutInflater.from(mContext)
2366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                .inflate(R.layout.wifi_p2p_dialog, null);
2367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
2369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
2370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mSavedPeerConfig.deviceAddress));
2371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
2373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        AlertDialog dialog = new AlertDialog.Builder(mContext)
2375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
2376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setView(textEntryView)
2377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
2378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
2379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (wps.setup == WpsInfo.KEYPAD) {
2380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                                mSavedPeerConfig.wps.pin = pin.getText().toString();
2381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            }
2382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
2383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
2384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
2386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
2387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
2388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onClick(DialogInterface dialog, int which) {
2389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd(getName() + " ignore connect");
2390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(PEER_CONNECTION_USER_REJECT);
2391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
2393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .setOnCancelListener(new DialogInterface.OnCancelListener() {
2394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        @Override
2395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        public void onCancel(DialogInterface arg0) {
2396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            if (DBG) logd(getName() + " ignore connect");
2397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                            sendMessage(PEER_CONNECTION_USER_REJECT);
2398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        }
2399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    })
2400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            .create();
2401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //make the enter pin area or the display pin area visible
2403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        switch (wps.setup) {
2404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.KEYPAD:
2405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("Enter pin section visible");
2406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
2407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
2408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            case WpsInfo.DISPLAY:
2409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("Shown pin section visible");
2410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
2411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
2412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            default:
2413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
2414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2415155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if ((r.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_APPLIANCE) ==
2417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Configuration.UI_MODE_TYPE_APPLIANCE) {
2418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // For appliance devices, add a key listener which accepts.
2419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
2420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                @Override
2422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
2423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // TODO: make the actual key come from a config value.
2424155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
2425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        sendMessage(PEER_CONNECTION_USER_ACCEPT);
2426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        dialog.dismiss();
2427155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                        return true;
2428155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    }
2429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return false;
2430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2431155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            });
2432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // TODO: add timeout for this dialog.
2433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // TODO: update UI in appliance mode to tell user what to do.
2434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2436155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2437123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
2438123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
2439123e33c0fa492be4f1a8c656cc835ab05c5cda55Sky Faber        dialog.getWindow().setAttributes(attrs);
2440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dialog.show();
2441155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Synchronize the persistent group list between
2445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * wpa_supplicant and mGroups.
2446155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2447155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void updatePersistentNetworks(boolean reload) {
2448155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String listStr = mWifiNative.listNetworks();
2449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (listStr == null) return;
2450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2451155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean isSaveRequired = false;
2452155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] lines = listStr.split("\n");
2453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (lines == null) return;
2454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (reload) mGroups.clear();
2456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Skip the first line, which is a header
2458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (int i = 1; i < lines.length; i++) {
2459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] result = lines[i].split("\t");
2460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (result == null || result.length < 4) {
2461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // network-id | ssid | bssid | flags
2464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = -1;
2465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String ssid = result[1];
2466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String bssid = result[2];
2467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String flags = result[3];
2468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
2469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                netId = Integer.parseInt(result[0]);
2470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch(NumberFormatException e) {
2471155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                e.printStackTrace();
2472155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2473155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2474155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (flags.indexOf("[CURRENT]") != -1) {
2476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
2479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                /*
2480155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * The unused profile is sometimes remained when the p2p group formation is failed.
2481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 * So, we clean up the p2p group here.
2482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                 */
2483155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("clean up the unused persistent group. netId=" + netId);
2484155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.removeNetwork(netId);
2485155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                isSaveRequired = true;
2486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2488155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mGroups.contains(netId)) {
2490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                continue;
2491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2493155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pGroup group = new WifiP2pGroup();
2494155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            group.setNetworkId(netId);
2495155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            group.setNetworkName(ssid);
2496155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String mode = mWifiNative.getNetworkVariable(netId, "mode");
2497155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mode != null && mode.equals("3")) {
2498155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group.setIsGroupOwner(true);
2499155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2500155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
2501155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group.setOwner(mThisDevice);
2502155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
2503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                WifiP2pDevice device = new WifiP2pDevice();
2504155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                device.deviceAddress = bssid;
2505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                group.setOwner(device);
2506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2507155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mGroups.add(group);
2508155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            isSaveRequired = true;
2509155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2511155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (reload || isSaveRequired) {
2512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.saveConfig();
2513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendP2pPersistentGroupsChangedBroadcast();
2514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2517155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2518155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * A config is valid if it has a peer address that has already been
2519155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * discovered
2520155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return true if it is invalid, false otherwise
2521155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2522155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean isConfigInvalid(WifiP2pConfig config) {
2523155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (config == null) return true;
2524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (TextUtils.isEmpty(config.deviceAddress)) return true;
2525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mPeers.get(config.deviceAddress) == null) return true;
2526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
2527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2528155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2529155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* TODO: The supplicant does not provide group capability changes as an event.
2530155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Having it pushed as an event would avoid polling for this information right
2531155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * before a connection
2532155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2533155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private WifiP2pDevice fetchCurrentDeviceDetails(WifiP2pConfig config) {
2534155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /* Fetch & update group capability from supplicant on the device */
2535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        int gc = mWifiNative.getGroupCapability(config.deviceAddress);
2536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPeers.updateGroupCapability(config.deviceAddress, gc);
2537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return mPeers.get(config.deviceAddress);
2538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2539155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2540155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2541155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start a p2p group negotiation and display pin if necessary
2542155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param config for the peer
2543155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2544155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
2545155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
2546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
2548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
2549155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Integer.parseInt(pin);
2550155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            notifyInvitationSent(pin, config.deviceAddress);
2551155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (NumberFormatException ignore) {
2552155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // do nothing if p2pConnect did not return a pin
2553155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2554155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2555155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2556155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2557155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Reinvoke a persistent group.
2558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param config for the peer
2560155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return true on success, false on failure
2561155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2562155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean reinvokePersistentGroup(WifiP2pConfig config) {
2563155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
2564155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2565155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean join = dev.isGroupOwner();
2566155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
2567155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("target ssid is " + ssid + " join:" + join);
2568155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (join && dev.isGroupLimit()) {
2570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("target device reaches group limit.");
2571155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2572155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // if the target group has reached the limit,
2573155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // try group formation.
2574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            join = false;
2575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else if (join) {
2576155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
2577155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (netId >= 0) {
2578155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Skip WPS and start 4way handshake immediately.
2579155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (!mWifiNative.p2pGroupAdd(netId)) {
2580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return false;
2581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2582155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return true;
2583155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2586155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!join && dev.isDeviceLimit()) {
2587155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("target device reaches the device limit.");
2588155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2589155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2590155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!join && dev.isInvitationCapable()) {
2592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = WifiP2pGroup.PERSISTENT_NET_ID;
2593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (config.netId >= 0) {
2594155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
2595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    netId = config.netId;
2596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2597155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } else {
2598155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                netId = mGroups.getNetworkId(dev.deviceAddress);
2599155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2600155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (netId < 0) {
2601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                netId = getNetworkIdFromClientList(dev.deviceAddress);
2602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
2604155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (netId >= 0) {
2605155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                // Invoke the persistent group.
2606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
2607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    // Save network id. It'll be used when an invitation result event is received.
2608155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    config.netId = netId;
2609155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return true;
2610155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
2611155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    loge("p2pReinvoke() failed, update networks");
2612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    updatePersistentNetworks(RELOAD);
2613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return false;
2614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2615155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2618155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return false;
2619155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2620155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2621155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2622155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Return the network id of the group owner profile which has the p2p client with
2623155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * the specified device address in it's client list.
2624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * If more than one persistent group of the same address is present in its client
2625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * lists, return the first one.
2626155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
2627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param deviceAddress p2p device address.
2628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return the network id. if not found, return -1.
2629155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2630155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private int getNetworkIdFromClientList(String deviceAddress) {
2631155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (deviceAddress == null) return -1;
2632155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Collection<WifiP2pGroup> groups = mGroups.getGroupList();
2634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (WifiP2pGroup group : groups) {
2635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int netId = group.getNetworkId();
2636155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String[] p2pClientList = getClientList(netId);
2637155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (p2pClientList == null) continue;
2638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String client : p2pClientList) {
2639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (deviceAddress.equalsIgnoreCase(client)) {
2640155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return netId;
2641155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2642155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2643155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2644155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return -1;
2645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2647155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2648155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Return p2p client list associated with the specified network id.
2649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param netId network id.
2650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return p2p client list. if not found, return null.
2651155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2652155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String[] getClientList(int netId) {
2653155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
2654155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (p2pClients == null) {
2655155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return null;
2656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return p2pClients.split(" ");
2658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Remove the specified p2p client from the specified profile.
2662155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param netId network id of the profile.
2663155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param addr p2p client address to be removed.
2664155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param isRemovable if true, remove the specified profile if its client list becomes empty.
2665155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return whether removing the specified p2p client is successful or not.
2666155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
2668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        StringBuilder modifiedClientList =  new StringBuilder();
2669155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String[] currentClientList = getClientList(netId);
2670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean isClientRemoved = false;
2671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (currentClientList != null) {
2672155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (String client : currentClientList) {
2673155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (!client.equalsIgnoreCase(addr)) {
2674155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    modifiedClientList.append(" ");
2675155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    modifiedClientList.append(client);
2676155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } else {
2677155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    isClientRemoved = true;
2678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2680155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (modifiedClientList.length() == 0 && isRemovable) {
2682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // the client list is empty. so remove it.
2683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("Remove unknown network");
2684155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mGroups.remove(netId);
2685155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return true;
2686155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2687155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!isClientRemoved) {
2689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            // specified p2p client is not found. already removed.
2690155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2693155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("Modified client list: " + modifiedClientList);
2694155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (modifiedClientList.length() == 0) {
2695155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            modifiedClientList.append("\"\"");
2696155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2697155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setNetworkVariable(netId,
2698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                "p2p_client_list", modifiedClientList.toString());
2699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.saveConfig();
2700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void setWifiP2pInfoOnGroupFormation(InetAddress serverInetAddress) {
2704155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupFormed = true;
2705155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
2706155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupOwnerAddress = serverInetAddress;
2707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2709155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void resetWifiP2pInfo() {
2710155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupFormed = false;
2711155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.isGroupOwner = false;
2712155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiP2pInfo.groupOwnerAddress = null;
2713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String getDeviceName(String deviceAddress) {
2716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        WifiP2pDevice d = mPeers.get(deviceAddress);
2717155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (d != null) {
2718155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                return d.deviceName;
2719155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //Treat the address as name if there is no match
2721155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return deviceAddress;
2722155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2723155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private String getPersistedDeviceName() {
2725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String deviceName = Settings.Global.getString(mContext.getContentResolver(),
2726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_P2P_DEVICE_NAME);
2727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (deviceName == null) {
2728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            /* We use the 4 digits of the ANDROID_ID to have a friendly
2729155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande             * default that has low likelihood of collision with a peer */
2730155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            String id = Settings.Secure.getString(mContext.getContentResolver(),
2731155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    Settings.Secure.ANDROID_ID);
2732155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return "Android_" + id.substring(0,4);
2733155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2734155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return deviceName;
2735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2737155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean setAndPersistDeviceName(String devName) {
2738155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (devName == null) return false;
2739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2740155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!mWifiNative.setDeviceName(devName)) {
2741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to set device name " + devName);
2742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2743155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2744155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.deviceName = devName;
2746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
2747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Settings.Global.putString(mContext.getContentResolver(),
2749155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_P2P_DEVICE_NAME, devName);
2750155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendThisDeviceChangedBroadcast();
2751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2752155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2753155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2754155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
2755155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean success;
2756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!wfdInfo.isWfdEnabled()) {
2758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            success = mWifiNative.setWfdEnable(false);
2759155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
2760155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            success =
2761155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                mWifiNative.setWfdEnable(true)
2762155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                && mWifiNative.setWfdDeviceInfo(wfdInfo.getDeviceInfoHex());
2763155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2764155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!success) {
2766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to set wfd properties");
2767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2769155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2770155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.wfdInfo = wfdInfo;
2771155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendThisDeviceChangedBroadcast();
2772155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2773155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2774155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void initializeP2pSettings() {
2776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setPersistentReconnect(true);
2777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.deviceName = getPersistedDeviceName();
2778155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setDeviceName(mThisDevice.deviceName);
2779155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // DIRECT-XY-DEVICENAME (XY is randomly generated)
2780155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
2781155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
2782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Supplicant defaults to using virtual display with display
2783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // which refers to a remote display. Use physical_display
2784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setConfigMethods("virtual_push_button physical_display keypad");
2785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // STA has higher priority over P2P
2786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setConcurrencyPriority("sta");
2787155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2788155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
2789155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updateThisDevice(WifiP2pDevice.AVAILABLE);
2790155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (DBG) logd("DeviceAddress: " + mThisDevice.deviceAddress);
2791155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2792155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mClientInfoList.clear();
2793155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pFlush();
2794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pServiceFlush();
2795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceTransactionId = 0;
2796155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2797155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2798155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
2799155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Settings.Global.WIFI_COUNTRY_CODE);
2800155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (countryCode != null && !countryCode.isEmpty()) {
2801155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mP2pStateMachine.sendMessage(SET_COUNTRY_CODE, countryCode);
2802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2804155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updatePersistentNetworks(RELOAD);
2805155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2806155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2807155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void updateThisDevice(int status) {
2808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mThisDevice.status = status;
2809155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendThisDeviceChangedBroadcast();
2810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleGroupCreationFailure() {
2813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        resetWifiP2pInfo();
2814155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.FAILED, null, null);
2815155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendP2pConnectionChangedBroadcast();
2816155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2817155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Remove only the peer we failed to connect to so that other devices discovered
2818155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // that have not timed out still remain in list for connection
2819155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean peersChanged = mPeers.remove(mPeersLostDuringConnection);
282084befe36af491f26ae46243017a1aca4dd5b24d5Vinit Deshpande        if (TextUtils.isEmpty(mSavedPeerConfig.deviceAddress) == false &&
28215c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales                mPeers.remove(mSavedPeerConfig.deviceAddress) != null) {
2822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            peersChanged = true;
2823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2824155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (peersChanged) {
2825155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendPeersChangedBroadcast();
2826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2827155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPeersLostDuringConnection.clear();
2829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2830155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        sendMessage(WifiP2pManager.DISCOVER_PEERS);
2831155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void handleGroupRemoved() {
2834155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mGroup.isGroupOwner()) {
2835155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            stopDhcpServer(mGroup.getInterface());
2836155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
2837155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("stop DHCP client");
2838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
2839155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpStateMachine.doQuit();
2840155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mDhcpStateMachine = null;
28416751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran            try {
28426751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                mNwService.removeInterfaceFromLocalNetwork(mGroup.getInterface());
28436751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran            } catch (RemoteException e) {
28446751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran                loge("Failed to remove iface from local network " + e);
28456751767bfe5d3a82c594e7abba77b27b0aecb28dSreeram Ramachandran            }
2846155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2847155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2848155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        try {
2849155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mNwService.clearInterfaceAddresses(mGroup.getInterface());
2850155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } catch (Exception e) {
2851155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            loge("Failed to clear addresses " + e);
2852155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2853155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        NetworkUtils.resetConnections(mGroup.getInterface(), NetworkUtils.RESET_ALL_ADDRESSES);
2854155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2855155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Clear any timeout that was set. This is essential for devices
2856155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // that reuse the main p2p interface for a created group.
2857155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
2858155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean peersChanged = false;
2860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // Remove only peers part of the group, so that other devices discovered
2861155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        // that have not timed out still remain in list for connection
2862155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (WifiP2pDevice d : mGroup.getClientList()) {
2863155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (mPeers.remove(d)) peersChanged = true;
2864155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2865155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mPeers.remove(mGroup.getOwner())) peersChanged = true;
2866155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mPeers.remove(mPeersLostDuringConnection)) peersChanged = true;
2867155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (peersChanged) {
2868155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            sendPeersChangedBroadcast();
2869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mGroup = null;
2872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mPeersLostDuringConnection.clear();
2873155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2874155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
28755c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales        if (mTemporarilyDisconnectedWifi) {
2876155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiChannel.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST, 0);
28775c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales            mTemporarilyDisconnectedWifi = false;
2878155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2879155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande   }
2880155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2881155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //State machine initiated requests can have replyTo set to null indicating
2882155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    //there are no recipients, we ignore those reply actions
2883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what) {
2884155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
2885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message dstMsg = obtainMessage(msg);
2886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.what = what;
2887155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
2888155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2889155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what, int arg1) {
2891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
2892155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message dstMsg = obtainMessage(msg);
2893155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.what = what;
2894155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.arg1 = arg1;
2895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
2896155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2897155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2898155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void replyToMessage(Message msg, int what, Object obj) {
2899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (msg.replyTo == null) return;
2900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message dstMsg = obtainMessage(msg);
2901155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.what = what;
2902155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        dstMsg.obj = obj;
2903155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mReplyChannel.replyToMessage(msg, dstMsg);
2904155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2905155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2906155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* arg2 on the source message has a hash code that needs to be retained in replies
2907155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * see WifiP2pManager for details */
2908155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private Message obtainMessage(Message srcMsg) {
2909155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Message msg = Message.obtain();
2910155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        msg.arg2 = srcMsg.arg2;
2911155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return msg;
2912155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2913155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2914155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2915155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    protected void logd(String s) {
2916155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Slog.d(TAG, s);
2917155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2918155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2919155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    @Override
2920155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    protected void loge(String s) {
2921155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        Slog.e(TAG, s);
2922155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2923155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2924155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2925155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Update service discovery request to wpa_supplicant.
2926155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2927155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean updateSupplicantServiceRequest() {
2928155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearSupplicantServiceRequest();
2929155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2930155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        StringBuffer sb = new StringBuffer();
2931155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (ClientInfo c: mClientInfoList.values()) {
2932155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            int key;
2933155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pServiceRequest req;
2934155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            for (int i=0; i < c.mReqList.size(); i++) {
2935155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                req = c.mReqList.valueAt(i);
2936155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (req != null) {
2937155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    sb.append(req.getSupplicantQuery());
2938155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
2939155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
2940155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2941155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2942155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (sb.length() == 0) {
2943155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2944155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2945155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2946155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
2947155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
2948155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2949155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2950155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
2951155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2952155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2953155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
2954155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Clear service discovery request in wpa_supplicant
2955155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2956155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearSupplicantServiceRequest() {
2957155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) return;
2958155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2959155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pServDiscCancelReq(mServiceDiscReqId);
2960155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mServiceDiscReqId = null;
2961155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2962155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2963155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /* TODO: We could track individual service adds separately and avoid
2964155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * having to do update all service requests on every new request
2965155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
2966155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean addServiceRequest(Messenger m, WifiP2pServiceRequest req) {
2967155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearClientDeadChannels();
2968155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, true);
2969155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
2970155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
2971155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2972155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2973155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ++mServiceTransactionId;
2974155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //The Wi-Fi p2p spec says transaction id should be non-zero
2975155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceTransactionId == 0) ++mServiceTransactionId;
2976155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        req.setTransactionId(mServiceTransactionId);
2977155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mReqList.put(mServiceTransactionId, req);
2978155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2979155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
2980155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return true;
2981155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2982155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2983155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return updateSupplicantServiceRequest();
2984155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
2985155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
2987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
2988155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
2989155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
2990155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
2991155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
2992155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //Application does not have transaction id information
2993155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        //go through stored requests to remove
2994155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        boolean removed = false;
2995155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (int i=0; i<clientInfo.mReqList.size(); i++) {
2996155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (req.equals(clientInfo.mReqList.valueAt(i))) {
2997155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                removed = true;
2998155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                clientInfo.mReqList.removeAt(i);
2999155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                break;
3000155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3001155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3002155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3003155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!removed) return;
3004155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3005155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
3006155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove client information from framework");
3007155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3008155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3009155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3010155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
3011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3012155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updateSupplicantServiceRequest();
3015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3016155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3017155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearServiceRequests(Messenger m) {
3018155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3019155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3020155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3021155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3022155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3023155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0) {
3025155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3026155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3027155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3028155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mReqList.clear();
3029155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3030155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mServList.size() == 0) {
3031155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove channel information from framework");
3032155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3033155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3034155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (mServiceDiscReqId == null) {
3036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        updateSupplicantServiceRequest();
3040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private boolean addLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
3043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearClientDeadChannels();
3044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, true);
3045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
3047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!clientInfo.mServList.add(servInfo)) {
3050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
3051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (!mWifiNative.p2pServiceAdd(servInfo)) {
3054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            clientInfo.mServList.remove(servInfo);
3055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
3056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return true;
3059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void removeLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
3062155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3063155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mWifiNative.p2pServiceDel(servInfo);
3068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mServList.remove(servInfo);
3070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
3071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove client information from framework");
3072155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3073155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3074155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearLocalServices(Messenger m) {
3077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = getClientInfo(m, false);
3078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null) {
3079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return;
3080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3082155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (WifiP2pServiceInfo servInfo: clientInfo.mServList) {
3083155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mWifiNative.p2pServiceDel(servInfo);
3084155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3085155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clientInfo.mServList.clear();
3087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo.mReqList.size() == 0) {
3088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("remove client information from framework");
3089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.remove(clientInfo.mMessenger);
3090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3093155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearClientInfo(Messenger m) {
3094155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearLocalServices(m);
3095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        clearServiceRequests(m);
3096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3099155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Send the service response to the WifiP2pManager.Channel.
3100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param resp
3102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void sendServiceResponse(WifiP2pServiceResponse resp) {
3104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (ClientInfo c : mClientInfoList.values()) {
3105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            WifiP2pServiceRequest req = c.mReqList.get(resp.getTransactionId());
3106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (req != null) {
3107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                Message msg = Message.obtain();
3108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.what = WifiP2pManager.RESPONSE_SERVICE;
3109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.arg1 = 0;
3110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.arg2 = 0;
3111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                msg.obj = resp;
3112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                try {
3113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    c.mMessenger.send(msg);
3114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                } catch (RemoteException e) {
3115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    if (DBG) logd("detect dead channel");
3116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    clearClientInfo(c.mMessenger);
3117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                    return;
3118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                }
3119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * We dont get notifications of clients that have gone away.
3125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * We detect this actively when services are added and throw
3126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * them away.
3127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
3128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * TODO: This can be done better with full async channels.
3129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private void clearClientDeadChannels() {
3131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
3132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (ClientInfo c : mClientInfoList.values()) {
3134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            Message msg = Message.obtain();
3135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.what = WifiP2pManager.PING;
3136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.arg1 = 0;
3137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.arg2 = 0;
3138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            msg.obj = null;
3139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            try {
3140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                c.mMessenger.send(msg);
3141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            } catch (RemoteException e) {
3142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                if (DBG) logd("detect dead channel");
3143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande                deadClients.add(c.mMessenger);
3144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            }
3145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        for (Messenger m : deadClients) {
3148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            clearClientInfo(m);
3149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Return the specified ClientInfo.
3154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param m Messenger
3155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @param createIfNotExist if true and the specified channel info does not exist,
3156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * create new client info.
3157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return the specified ClientInfo.
3158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private ClientInfo getClientInfo(Messenger m, boolean createIfNotExist) {
3160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        ClientInfo clientInfo = mClientInfoList.get(m);
3161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        if (clientInfo == null && createIfNotExist) {
3163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            if (DBG) logd("add a new client");
3164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            clientInfo = new ClientInfo(m);
3165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mClientInfoList.put(m, clientInfo);
3166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        return clientInfo;
3169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3172155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3173155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
3174155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Information about a particular client and we track the service discovery requests
3175155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and the local services registered by the client.
3176155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
3177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    private class ClientInfo {
3178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3179155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
3180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * A reference to WifiP2pManager.Channel handler.
3181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * The response of this request is notified to WifiP2pManager.Channel handler
3182155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
3183155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private Messenger mMessenger;
3184155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3185155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
3186155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * A service discovery request list.
3187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
3188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private SparseArray<WifiP2pServiceRequest> mReqList;
3189155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        /*
3191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         * A local service information list.
3192155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande         */
3193155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private List<WifiP2pServiceInfo> mServList;
3194155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
3195155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        private ClientInfo(Messenger m) {
3196155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mMessenger = m;
3197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mReqList = new SparseArray();
3198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            mServList = new ArrayList<WifiP2pServiceInfo>();
3199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
3200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
3201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
3202