SupplicantStaIfaceHal.java revision d95fa596d07855b70ff18a50a48e773155a919f5
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
18240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
19240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
2096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
21240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
2296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
23240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
24240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
25240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
26240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
27240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
2866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
298c6d09c03532b3936fab2fed6f8b84c895333565Roshan Piusimport android.os.HandlerThread;
30240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
3296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.util.MutableBoolean;
3396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
34d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
35240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
36240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
37d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
39240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
40240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
41240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
42b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
4396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /** Invalid Supplicant Iface type */
4496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static final int INVALID_IFACE_TYPE = -1;
45240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static final boolean DBG = false;
46b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
4798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private static final String SERVICE_MANAGER_NAME = "manager";
4898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private IServiceManager mIServiceManager = null;
4998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
5098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
5198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
52240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private final Object mLock = new Object();
5398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private final HandlerThread mHandlerThread;
54b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    public SupplicantStaIfaceHal(HandlerThread handlerThread) {
5598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        mHandlerThread = handlerThread;
568c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
57240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
58240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
5998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
6098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
61240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
62240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
63240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
6498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        if (DBG) Log.i(TAG, "Registering ISupplicant service ready callback.");
65240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
6698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
6798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
6898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
6998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
7098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
7198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
7298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
73240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
7498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
7598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
76240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
77240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
78240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
7998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.linkToDeath(cookie -> {
80240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "IServiceManager died: cookie=" + cookie);
81240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    synchronized (mLock) {
82240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        supplicantServiceDiedHandler();
8398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mIServiceManager = null; // Will need to register a new ServiceNotification
84240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
85240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }, 0)) {
86240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
87240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantServiceDiedHandler();
8898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
89240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
90240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
91240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                IServiceNotification serviceNotificationCb = new IServiceNotification.Stub() {
92240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    public void onRegistration(String fqName, String name, boolean preexisting) {
9398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        synchronized (mLock) {
9498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (DBG) {
9598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
9698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                        + ", " + name + " preexisting=" + preexisting);
9798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
9898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (!initSupplicantService() || !initSupplicantStaIface()) {
9998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.e(TAG, "initalizing ISupplicantIfaces failed.");
10098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                supplicantServiceDiedHandler();
10198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            } else {
10298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
10398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
104240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        }
105240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
106240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                };
107240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
108240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
10998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.registerForNotifications(ISupplicant.kInterfaceName,
110240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        "", serviceNotificationCb)) {
111240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
112240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
11398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
114240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
115240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
116240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
117240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
118240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
11998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
120240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
121240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
122240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
123240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
124240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
12598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
126240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
127240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
12898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
129240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
130240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
131240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
132240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
13398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
134240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
135240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
136240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
137240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
138240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
139240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
140240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
14198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
142240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
143240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
144240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
145240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
14698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
147240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
148240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
149240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
150240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
151240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
152240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
153240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
154240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
155240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
15698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
157240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
158240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
16098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
161240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
163240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
16498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
165240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
16698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
167240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
168240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
169240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
171240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
172240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
173240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
174240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
175240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
17698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
177240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
178240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
179240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
180240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
18198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
18298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
183240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
18598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
186240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
187240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
188240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
19098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
191240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
19298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
19398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
195240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
196240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
19798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
19898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Signals whether Initialization completed successfully. Only necessary for testing, is not
19998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * needed to guard calls etc.
20098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
20198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
20298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
2038c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2048c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
2058c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
20698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
2078c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
20898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
20998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return IServiceManager.getService(SERVICE_MANAGER_NAME);
21098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
21198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
21298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
21398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
21498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
21598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
21698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
21798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
2188c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2198c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
22096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
22166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Add a network configuration to wpa_supplicant, via HAL
222d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
22366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
22466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
22566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
226d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
22766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
22866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
22966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
23066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
23166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
23266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
23366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
23466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
23566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
23666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
23766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network.saveWifiConfiguration(config)) {
23866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return network;
23966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        } else {
24066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
24166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
24266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
24366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
24466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
24566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
246d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate connection to the provided network.
247d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
248d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param config Config corresponding to the network.
249d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param shouldDisconnect Whether to trigger a disconnect first.
250d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
25166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
252d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) {
253d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        logd("connectToNetwork " + config.configKey()
25466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                + " (shouldDisconnect " + shouldDisconnect + ")");
25566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (shouldDisconnect && !disconnect()) {
25666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to trigger disconnect");
25766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
25866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
25966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
26066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
26166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
26266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
263d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        SupplicantStaNetworkHal network = addNetwork(config);
26466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
265d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
26666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
26766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
26866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!network.getId()) {
269d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to get network id for configuration: " + config.configKey());
27066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
27166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
27266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!network.select()) {
273d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
27466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
27566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
27666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
27766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
27866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
27966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
28066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
28166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * TODO(b/34454675) use ISupplicantIface.removeAllNetworks when it exists
28266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
28366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
28466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
28566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
28666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
28766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
28866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
28966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
29066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
29166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
29266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
29366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
29466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
29566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
29666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
29766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
29866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
29966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
30066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
301d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Gets the interface name.
302d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
30396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return returns the name of Iface or null if the call fails
30496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
30596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private String getName() {
30696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
30796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
30896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getName";
30996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
31096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
31196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final StringBuilder builder = new StringBuilder();
31296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
31396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getName((SupplicantStatus status, String name) -> {
31496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
31596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
31696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
31796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
31896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        builder.append(name);
31996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
32096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
32196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
32296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
32396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
32496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
32596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
32696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return builder.toString();
32796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
32896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
32996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
33096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
33196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
332d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
33396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
334d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
335d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
33696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
33796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
33896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
33996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
34096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
34196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
34296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
34396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
34496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
34596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
34696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
34796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
34896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
34996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
35096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
35196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
35296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
35396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
35496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
35596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
35696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
35796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
35896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
35996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
36096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return new SupplicantStaNetworkHal(ISupplicantStaNetwork.asInterface(
36166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                        newNetwork.value.asBinder()), mHandlerThread);
36296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
36396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
36496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
36596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
36696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
367d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
36896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
36996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
370d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
371d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
37296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
37396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
37496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
37596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
37696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
37796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
37896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
37996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
38096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
38196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
38296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
38396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
38496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
38596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
38696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
38796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
388d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
38996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
39096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
39196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
39296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
39396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
39496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
39596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
39696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
39796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
39896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
39996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
40096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
40196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
40296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
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                        gotNetwork.value = network;
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 new SupplicantStaNetworkHal(ISupplicantStaNetwork.asInterface(
41666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                        gotNetwork.value.asBinder()), mHandlerThread);
41796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
41896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
41996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
42096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
42196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
42296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
42396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
42496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
42596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
42696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
42796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
42896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
42996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
43096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
43196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
43296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
43396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
43496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
43596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
43696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
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                        networkIdList.value = networkIds;
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) {
44996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return networkIdList.value;
45096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
45196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
45296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
45396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
45496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
455d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
456d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
457d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
458d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
459d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
460d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
461d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
46296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
46396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
46496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
46596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
46696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
46796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
46896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
46996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
47096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
47196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
47296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
47396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
47496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
47596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
476d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
477d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
478d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
479d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
480d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
481d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
482d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
48396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
48496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
48596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
48696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
48796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
48896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
48996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
49096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
49196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
49296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
49396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
49496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
49596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
49696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
497d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
498d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
499d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
500d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
501d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
502d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
503d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
50496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
50596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
50696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
50796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
50896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
50996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
51096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
51196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
51296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
51396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
51496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
51596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
51696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
51796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
518d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
519d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
520d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
521d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
522d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
523d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
524d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
525d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
52696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
52796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
52896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
52996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
53096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
53196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
53296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
53396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
53496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
53596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
53696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
53796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
53896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
53996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
540d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
541d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
542d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
543d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
544d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
545d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
546d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
547d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
548d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
549d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
550b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
55196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
55296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
55396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
55496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
55596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
55696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
55796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
55896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
55996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
56096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
56196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
56296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
56396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
56496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
56596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
566d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
567d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
568d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
569d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
570d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
571d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
572d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
573d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
574d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
575d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
576b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
57796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
57896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
57996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
58096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
58196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
58296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
58396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
58496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
58596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
58696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
58796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
58896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
58996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
59096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
59196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
592d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
593d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
594d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
595d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
596d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
597d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
598d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
599d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
600d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
601d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
602b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
60396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
60496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
60596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
60696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
60796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
60896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
60996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
61096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
61196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
61296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
61396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
61496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
61596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
61696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
61796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
618d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
619d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
620d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
621d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
622d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
623d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
624d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
625d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
626d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
627d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
628d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
629d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateAnqpQuery(
630d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
631d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
632d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
633b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
63496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
63596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
63696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
63796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
63996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
64096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
64196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
64296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
64396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
64496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
64596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
64696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
64796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
64896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
64996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
65096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
651d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
652d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
653d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
654d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
655d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
656d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
657d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
658d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
659d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
660d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
661d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
662d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
663b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
66496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
66596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
66696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
66796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
66896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
66996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
67096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
67196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
67296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
67396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
67496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
67596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
67696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
67796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
67896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
67996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
680d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
68196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
68296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
683d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
68496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
68596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
686d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
68796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
68896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            MutableBoolean statusSuccess = new MutableBoolean(false);
68996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
69096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
69196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
69296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
69396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
69496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
69596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
69696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS;
69796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    if (!statusSuccess.value) {
69896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        Log.e(TAG, methodStr + " failed: " + status.debugMessage);
69996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    } else {
700d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
70196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
70296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
70396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
70496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
70596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
70696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
70796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (statusSuccess.value) {
70896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return gotMac.value;
70996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
71096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
71196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
71296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
71396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
714d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
715d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
716d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
717d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
718d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
719d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
720d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
72196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
72296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
72396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
72496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
72596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
72696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
72796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
72896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
72996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
73096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
73196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
73296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
73396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
73496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
735d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
736d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
737d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
738d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
739d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
740d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
741d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
74296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
74396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
74496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
74596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
74696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
74796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
74896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
74996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
75096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
75196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
75296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
75396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
75496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
75596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
756d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
757d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V4_MULTICAST =
758d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
759d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V6_MULTICAST =
760d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
761d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
762d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
763d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
764d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
765d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
766d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
767d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
76896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean addRxFilter(byte type) {
76996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
77096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
77196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
77296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
77396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
77496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
77596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
77696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
77796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
77896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
77996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
78096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
78196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
78296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
783d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
784d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
785d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
786d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
787d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
788d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
789d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
790d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
79196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeRxFilter(byte type) {
79296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
79396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
79496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
79596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
79696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
79796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
79896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
79996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
80096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
80196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
80296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
80396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
80496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
80596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
806d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
807d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
808d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
809d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE;
810d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
811d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
812d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
813d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED}
814d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *             or {@link #BT_COEX_MODE_SENSE} values.
815d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
816d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
817d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceMode(byte mode) {
81896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
81996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
82096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
82196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
82296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
82396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
82496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
82596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
82696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
82796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
82896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
82996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
83096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
83196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
832d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
833d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
834d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
835d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
836d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
837d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
838d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
83996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
84096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
84196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
84296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
84396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
84496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
84596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
84696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
84796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
84896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
84996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
85096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
85196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
85296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
85396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
854d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
855d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
856d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
857d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
858d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
859d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
860d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
86196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
86296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
86396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
86496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
86596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
86696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
86796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
86896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
86996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
87096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
87196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
87296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
87396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
87496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
875d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
876d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
877d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
878d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
879d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
880d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
881d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
882d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
883d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
884d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
885d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
886b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
88796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
88896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
88996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
89096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
89196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
89296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
89396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
89496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
89596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
89696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
89796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
89896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
89996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
90096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
90196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
90296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
90396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
90496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
90596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
90696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
90796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (DBG) Log.i(TAG, methodStr);
90896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
90996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
91096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
91196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
91296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
91396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
91496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
91596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
91696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
91796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
91896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private static boolean checkStatusAndLogFailure(SupplicantStatus status,
92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
92196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (DBG) Log.i(TAG, methodStr);
92296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
92396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, methodStr + " failed: " + supplicantStatusCodeToString(status.code) + ", "
92496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    + status.debugMessage);
92596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
92696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
92796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
92896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
92996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
93096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
93196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
93296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
93396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
93496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
93596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
93696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
93796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
93896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
93996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
94096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
94196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
94296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
94396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
94496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
94596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
94696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
95196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
95296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
95396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
95496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
95596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
95696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
95996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
96096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
961240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
962240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
963240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
964240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
965240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
966240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
967240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
968240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
969240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
970240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
971240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
97266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
97366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
97466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
97566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
97666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
97766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
97866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
97966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
98066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
98166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
98266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
98366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
984240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
985