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