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