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