SupplicantStaIfaceHal.java revision c7a4b6706fa09042bb36a64036d86d88eb6e4126
1240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/*
298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Copyright (C) 2017 The Android Open Source Project
3240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
4240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License");
5240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * you may not use this file except in compliance with the License.
6240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * You may obtain a copy of the License at
7240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
8240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *      http://www.apache.org/licenses/LICENSE-2.0
9240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
10240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Unless required by applicable law or agreed to in writing, software
11240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS,
12240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * See the License for the specific language governing permissions and
14240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * limitations under the License.
15240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
16240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhnepackage com.android.server.wifi;
17240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
18c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Piusimport android.content.Context;
19240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
20240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
2196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
22240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
2396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
24240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
25240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
26240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
27240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
28240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
29f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration;
3066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
32240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
3396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.util.MutableBoolean;
34f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray;
3596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
36d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
37240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
39f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap;
40f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List;
41f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map;
42d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
43240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
44240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
45240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
46240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
47b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
48240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static final boolean DBG = false;
49b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
5098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private static final String SERVICE_MANAGER_NAME = "manager";
5198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private IServiceManager mIServiceManager = null;
5298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
5398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
5498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
557c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network in wpa_supplicant
567c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private SupplicantStaNetworkHal mCurrentNetwork;
577c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network's framework network Id.
587c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private int mFrameworkNetworkId;
59240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private final Object mLock = new Object();
60c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final Context mContext;
61c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final WifiMonitor mWifiMonitor;
627c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
63c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {
64c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mContext = context;
65c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mWifiMonitor = monitor;
668c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
67240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
68240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
6998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
7098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
71240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
72240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
73240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
7498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        if (DBG) Log.i(TAG, "Registering ISupplicant service ready callback.");
75240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
7698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
7798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
7898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
7998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
8098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
8198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
8298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
83240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
8498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
8598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
86240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
87240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
88240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
8998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.linkToDeath(cookie -> {
90240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "IServiceManager died: cookie=" + cookie);
91240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    synchronized (mLock) {
92240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        supplicantServiceDiedHandler();
9398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mIServiceManager = null; // Will need to register a new ServiceNotification
94240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
95240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }, 0)) {
96240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
97240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantServiceDiedHandler();
9898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
99240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
100240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
101240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                IServiceNotification serviceNotificationCb = new IServiceNotification.Stub() {
102240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    public void onRegistration(String fqName, String name, boolean preexisting) {
10398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        synchronized (mLock) {
10498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (DBG) {
10598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
10698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                        + ", " + name + " preexisting=" + preexisting);
10798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
10898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (!initSupplicantService() || !initSupplicantStaIface()) {
10998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.e(TAG, "initalizing ISupplicantIfaces failed.");
11098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                supplicantServiceDiedHandler();
11198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            } else {
11298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
11398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
114240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        }
115240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
116240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                };
117240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
118240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
11998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.registerForNotifications(ISupplicant.kInterfaceName,
120240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        "", serviceNotificationCb)) {
121240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
122240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
12398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
124240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
125240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
126240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
127240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
128240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
12998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
130240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
131240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
132240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
133240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
134240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
13598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
136240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
137240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
13898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
139240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
140240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
141240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
142240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
14398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
144240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
145240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
146240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
147240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
148240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
149240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
150240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
15198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
152240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
153240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
154240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
155240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
15698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
157240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
158240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
160240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
161240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
163240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
164240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
165240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
16698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
167240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
168240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
169240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
17098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
171240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
172240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
173240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
17498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
175240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
17698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
177240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
178240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
179240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
180240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
181240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
182240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
183240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
185240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
18698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
187240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
188240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
190240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
19198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
19298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
193240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
19598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
196240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
197240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
198240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
199240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
20098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
201240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
20298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
20398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
204240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
205240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
206240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
20798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
20898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Signals whether Initialization completed successfully. Only necessary for testing, is not
20998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * needed to guard calls etc.
21098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
21198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
21298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
2138c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2148c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
2158c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
21698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
2178c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
21898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
21998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return IServiceManager.getService(SERVICE_MANAGER_NAME);
22098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
22198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
22298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
22398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
22498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
22598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
22698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
22798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
2288c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2298c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
23096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
2317c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
232d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
23366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
23466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
23566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
236d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
23766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
23866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
23966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
24066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
24166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
24266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
24366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
24466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
24566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
24666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
24766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network.saveWifiConfiguration(config)) {
24866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return network;
24966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        } else {
25066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
25166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
25266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
25366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
25466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
25566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
2567c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
2577c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
2587c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
2597c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Remove any existing network in wpa_supplicant.
2607c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Add a new network to wpa_supplicant.
2617c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 4. Save the provided configuration to wpa_supplicant.
2627c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 5. Select the new network in wpa_supplicant.
263d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
2647c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
2657c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
2667c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
26766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
268d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) {
2697c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
2707c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = null;
271d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        logd("connectToNetwork " + config.configKey()
27266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                + " (shouldDisconnect " + shouldDisconnect + ")");
27366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (shouldDisconnect && !disconnect()) {
27466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to trigger disconnect");
27566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
27666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
27766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
27866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
27966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
28066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
2817c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = addNetwork(config);
2827c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mCurrentNetwork == null) {
283d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
28466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
28566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
2867c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.select()) {
287d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
28866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
28966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
2907c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = config.networkId;
2917c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
2927c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
2937c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
2947c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
2957c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
2967c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
2977c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
2987c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
2997c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
3007c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
3017c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
3027c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
3037c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3047c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
3057c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
3067c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
3077c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
3087c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
3097c0ec884188660f72977c8a80366049705c48ffaRoshan Pius                    + "Current network ID: " + mFrameworkNetworkId);
3107c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return connectToNetwork(config, false);
3117c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
3127c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
3137c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
3147c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.setBssid(bssid)) {
3157c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
3167c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
3177c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
3187c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
3197c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
3207c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
3217c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
32266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
32366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
32466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
32566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
326f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
327f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
328f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
329f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
330f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
331f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
332f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
333f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
334f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
335f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
336f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
337f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
338f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
339f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
340f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
341f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
342f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
343f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
344f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
345f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
346f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
347f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
348f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (!network.loadWifiConfiguration(config, networkExtra)) {
349f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId);
350f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
351f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
352f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
353f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
354f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
355f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
356f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
357f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
358f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
359f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
360f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
361f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
362f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
363f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
364f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
365f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
366f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
367f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
368f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
369f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
37066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
37166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
37266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
37366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
37466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
37566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
37666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
37766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
37866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
37966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
38066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
38166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
38266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
38366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
38466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
38566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
38666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
38766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
38866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
38966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
390d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Gets the interface name.
391d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
39296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return returns the name of Iface or null if the call fails
39396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
39496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private String getName() {
39596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
39696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
39796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getName";
39896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
39996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
40096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final StringBuilder builder = new StringBuilder();
40196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
40296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getName((SupplicantStatus status, String name) -> {
40396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
40496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
40596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
40696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
40796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        builder.append(name);
40896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
40996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
41096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
41196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
41296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
41396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
41496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
41596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return builder.toString();
41696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
41796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
41896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
41996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
42096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
421d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
42296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
423d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
424d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
42596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
42696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
42796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
42896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
42996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
43096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
43196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
43296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
43396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
43496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
43596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
43696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
43796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
43896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
43996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
44096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
44196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
44296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
44396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
44496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
44596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
44696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
44796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
44896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
449c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
450c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
45196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
45296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
45396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
45496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
45596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
456d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
45796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
45896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
459d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
460d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
46196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
46296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
46396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
46496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
46596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
46696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
46796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
46896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
46996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
47096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
47196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
47296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
47396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
47496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
47596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
47696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
477d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
47896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
479f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
480f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
481f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
482f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
483f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
484f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
485f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
486c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
487c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        return new SupplicantStaNetworkHal(iSupplicantStaNetwork, mContext, mWifiMonitor);
488f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
489f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
490f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
49196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
49296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
49396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
49496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
49596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
49696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
49796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
49896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
49996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
50096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
50196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
50296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
50396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
50496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
50596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
50696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
50796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
50896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
50996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
51096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
51196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
51296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
51396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
51496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
51596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
516c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
517c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
51896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
51996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
52096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
52196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
52296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
52396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
52496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
52596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
52696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
52796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
52896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
52996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
53096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
53196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
53296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
53396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
53496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
53596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
53696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
53796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
53896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
53996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
54096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
54196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
54296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
54396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
54496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
54596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
54696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
54796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
54896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
54996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
55096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return networkIdList.value;
55196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
55296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
55396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
55496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
55596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
556d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
557d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
558d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
559d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
560d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
561d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
562d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
56396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
56496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
56596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
56696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
56796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
56896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
56996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
57096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
57196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
57296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
57396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
57496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
57596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
57696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
577d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
578d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
579d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
580d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
581d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
582d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
583d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
58496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
58596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
58696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
58796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
58896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
58996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
59096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
59196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
59296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
59396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
59496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
59596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
59696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
59796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
598d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
599d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
600d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
601d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
602d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
603d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
604d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
60596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
60696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
60796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
60896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
60996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
61096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
61196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
61296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
61396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
61496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
61596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
61696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
61796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
61896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
619d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
620d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
621d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
622d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
623d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
624d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
625d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
626d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
62796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
62896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
62996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
63096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
63196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
63296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
63396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
63496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
63596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
63696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
63796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
63996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
64096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
641d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
642d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
643d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
644d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
645d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
646d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
647d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
648d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
649d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
650d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
651b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
65296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
65396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
65496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
65596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
65696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
65796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
65896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
65996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
66096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
66196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
66296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
66396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
66496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
66596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
66696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
667d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
668d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
669d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
670d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
671d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
672d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
673d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
674d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
675d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
676d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
677b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
67896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
67996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
68096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
68196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
68296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
68396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
68496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
68596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
68696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
68796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
68896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
68996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
69096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
69196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
69296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
693d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
694d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
695d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
696d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
697d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
698d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
699d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
700d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
701d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
702d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
703b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
70496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
70596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
70696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
70796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
70896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
70996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
71096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
71196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
71296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
71396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
71496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
71596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
71696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
71796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
71896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
719d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
720d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
721d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
722d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
723d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
724d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
725d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
726d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
727d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
728d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
729d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
730d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateAnqpQuery(
731d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
732d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
733d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
734b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
73596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
73696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
73796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
73896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
73996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
74096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
74196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
74296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
74396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
74496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
74596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
74696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
74796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
74896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
74996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
75096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
75196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
752d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
753d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
754d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
755d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
756d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
757d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
758d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
759d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
760d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
761d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
762d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
763d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
764b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
76596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
76696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
76796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
76896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
76996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
77096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
77196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
77296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
77396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
77496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
77596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
77696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
77796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
77896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
77996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
78096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
781d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
78296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
78396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
784d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
78596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
78696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
787d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
78896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
78996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
79096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
79196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
79296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
79396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
79496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
79596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
79696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
79796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
79896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
79996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
80096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
801d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
80296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
80396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
80496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
80596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
80696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
80796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
80896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
80996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return gotMac.value;
81096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
81196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
81296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
81396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
81496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
815d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
816d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
817d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
818d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
819d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
820d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
821d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
82296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
82396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
82496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
82596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
82696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
82796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
82896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
82996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
83096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
83196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
83296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
83396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
83496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
83596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
836d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
837d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
838d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
839d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
840d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
841d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
842d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
84396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
84496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
84596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
84696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
84796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
84896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
84996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
85096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
85196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
85296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
85396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
85496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
85596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
85696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
857d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
858d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V4_MULTICAST =
859d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
860d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V6_MULTICAST =
861d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
862d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
863d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
864d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
865d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
866d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
867d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
868d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
86996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean addRxFilter(byte type) {
87096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
87196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
87296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
87396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
87496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
87596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
87696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
87796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
87896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
87996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
88096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
88196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
88296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
88396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
884d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
885d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
886d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
887d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
888d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
889d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
890d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
891d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
89296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeRxFilter(byte type) {
89396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
89496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
89596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
89696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
89796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
89896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
89996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
90096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
90196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
90296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
90396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
90496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
90596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
90696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
907d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
908d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
909d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
910d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE;
911d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
912d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
913d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
914d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED}
915d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *             or {@link #BT_COEX_MODE_SENSE} values.
916d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
917d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
918d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceMode(byte mode) {
91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
92196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
92296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
92396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
92496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
92596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
92696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
92796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
92896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
92996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
93096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
93196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
93296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
933d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
934d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
935d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
936d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
937d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
938d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
939d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
94096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
94196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
94296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
94396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
94496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
94596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
94696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
95196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
95296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
95396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
95496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
955d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
956d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
957d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
958d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
959d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
960d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
961d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
96296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
96396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
96496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
96596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
96696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
96996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
97096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
97196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
97296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
97396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
97496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
97596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
976d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
977d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
978d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
979d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
980d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
981d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
982d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
983d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
984d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
985d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
986d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
987b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
98896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
98996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
99096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
99396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
99496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
99696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
99896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
99996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
100096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
100196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
100296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
100396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
100496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
100596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
100696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
100796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
100896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (DBG) Log.i(TAG, methodStr);
100996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
101096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
101196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
101296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
101396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
101496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
101696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
101796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
101896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
101996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
102096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private static boolean checkStatusAndLogFailure(SupplicantStatus status,
102196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
102296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (DBG) Log.i(TAG, methodStr);
102396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
102496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, methodStr + " failed: " + supplicantStatusCodeToString(status.code) + ", "
102596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    + status.debugMessage);
102696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
102796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
102896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
102996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
103096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
103196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
103296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
103396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
103496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
103596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
103696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
103796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
103896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
103996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
104096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
104196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
104296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
104396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
104496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
104596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
104696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
104796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
104896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
104996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
105096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
105196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
105296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
105396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
105496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
105596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
105696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
105796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
105896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
105996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
106096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
106196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
1062240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1063240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1064240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1065240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1066240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1067240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1068240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1069240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1070240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1071240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1072240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
107366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
107466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
107566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
107666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
107766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
107866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
107966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
108066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
108166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
108266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
108366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
108466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
1085240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
1086