WifiAwareNativeManager.java revision 19c6781efe4ad552dec3423c858b2ab64f447d8e
164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen/* 264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Copyright (C) 2016 The Android Open Source Project 364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * 464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Licensed under the Apache License, Version 2.0 (the "License"); 564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * you may not use this file except in compliance with the License. 664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * You may obtain a copy of the License at 764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * 864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * http://www.apache.org/licenses/LICENSE-2.0 964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * 1064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Unless required by applicable law or agreed to in writing, software 1164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * distributed under the License is distributed on an "AS IS" BASIS, 1264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * See the License for the specific language governing permissions and 1464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * limitations under the License. 1564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen */ 1664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 1764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenpackage com.android.server.wifi.aware; 1864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 19968a755132c525e5e1f1224a05eef7a58809fbd9Roshan Piusimport android.annotation.NonNull; 2064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport android.hardware.wifi.V1_0.IWifiNanIface; 21448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohenimport android.hardware.wifi.V1_0.IfaceType; 22db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatus; 23db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatusCode; 240d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohenimport android.os.Handler; 25db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.os.RemoteException; 2664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport android.util.Log; 2764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 28c760a66378bbd844eb421658799b4d55c76b98faEtan Cohenimport com.android.internal.annotations.VisibleForTesting; 2964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport com.android.server.wifi.HalDeviceManager; 3064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 31db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.FileDescriptor; 32db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.PrintWriter; 33db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen 3464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen/** 3564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Manages the interface to Wi-Fi Aware HIDL (HAL). 3664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen */ 37c760a66378bbd844eb421658799b4d55c76b98faEtan Cohenpublic class WifiAwareNativeManager { 3864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private static final String TAG = "WifiAwareNativeManager"; 3964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private static final boolean DBG = false; 4064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 4164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen // to be used for synchronizing access to any of the WifiAwareNative objects 4264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private final Object mLock = new Object(); 4364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 4464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private WifiAwareStateManager mWifiAwareStateManager; 4564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private HalDeviceManager mHalDeviceManager; 460d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen private Handler mHandler; 47db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen private WifiAwareNativeCallback mWifiAwareNativeCallback; 4864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private IWifiNanIface mWifiNanIface = null; 4964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private InterfaceDestroyedListener mInterfaceDestroyedListener = 5064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen new InterfaceDestroyedListener(); 5164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private InterfaceAvailableForRequestListener mInterfaceAvailableForRequestListener = 5264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen new InterfaceAvailableForRequestListener(); 5364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 5464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen WifiAwareNativeManager(WifiAwareStateManager awareStateManager, 55db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen HalDeviceManager halDeviceManager, 56db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen WifiAwareNativeCallback wifiAwareNativeCallback) { 5764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiAwareStateManager = awareStateManager; 5864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mHalDeviceManager = halDeviceManager; 59db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mWifiAwareNativeCallback = wifiAwareNativeCallback; 600b31edb987c0552b75667e05f0d589937a16f1adEtan Cohen } 610b31edb987c0552b75667e05f0d589937a16f1adEtan Cohen 620d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen /** 630d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen * Initialize the class - intended for late initialization. 640d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen * 650d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen * @param handler Handler on which to execute interface available callbacks. 660d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen */ 670d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen public void start(Handler handler) { 680d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen mHandler = handler; 699b37a65ec7b89ca58639443fd899824b28d04191Etan Cohen mHalDeviceManager.initialize(); 703145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen mHalDeviceManager.registerStatusListener( 713145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen new HalDeviceManager.ManagerStatusListener() { 7264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen @Override 733145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen public void onStatusChanged() { 743145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (DBG) Log.d(TAG, "onStatusChanged"); 753145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen // only care about isStarted (Wi-Fi started) not isReady - since if not 763145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen // ready then Wi-Fi will also be down. 773145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (mHalDeviceManager.isStarted()) { 78448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen // 1. no problem registering duplicates - only one will be called 79448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen // 2. will be called immediately if available 80448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen mHalDeviceManager.registerInterfaceAvailableForRequestListener( 810d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen IfaceType.NAN, mInterfaceAvailableForRequestListener, mHandler); 823145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } else { 833145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen awareIsDown(); 843145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } 8564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 8619c6781efe4ad552dec3423c858b2ab64f447d8eRoshan Pius }, mHandler); 873145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (mHalDeviceManager.isStarted()) { 88ef6de4b88b850e9df98a9ffe51c71ac493f6c51bEtan Cohen mHalDeviceManager.registerInterfaceAvailableForRequestListener( 890d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen IfaceType.NAN, mInterfaceAvailableForRequestListener, mHandler); 903145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen tryToGetAware(); 913145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } 9264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 9364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 94c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen /** 95c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen * Returns the native HAL WifiNanIface through which commands to the NAN HAL are dispatched. 96c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen * Return may be null if not initialized/available. 97c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen */ 98c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen @VisibleForTesting 99c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen public IWifiNanIface getWifiNanIface() { 10064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen synchronized (mLock) { 10164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen return mWifiNanIface; 10264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 10364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 10464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 105c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen /** 106c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen * Attempt to obtain the HAL NAN interface. If available then enables Aware usage. 107c760a66378bbd844eb421658799b4d55c76b98faEtan Cohen */ 10864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private void tryToGetAware() { 10964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen synchronized (mLock) { 110448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen if (DBG) Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface); 111448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen 1123145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (mWifiNanIface != null) { 1133145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen return; 1143145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } 115448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen IWifiNanIface iface = mHalDeviceManager.createNanIface(mInterfaceDestroyedListener, 1160d5a9d5c9f0914ad145926beb96fb72b39089e02Etan Cohen mHandler); 11764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (iface == null) { 11864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Was not able to obtain an IWifiNanIface"); 11964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } else { 12064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Obtained an IWifiNanIface"); 12164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 122db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen try { 123db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen WifiStatus status = iface.registerEventCallback(mWifiAwareNativeCallback); 124db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen if (status.code != WifiStatusCode.SUCCESS) { 125db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen Log.e(TAG, "IWifiNanIface.registerEventCallback error: " + statusString( 126db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen status)); 127db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mHalDeviceManager.removeIface(iface); 128db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return; 129db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 130db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } catch (RemoteException e) { 131db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen Log.e(TAG, "IWifiNanIface.registerEventCallback exception: " + e); 132db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mHalDeviceManager.removeIface(iface); 133db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return; 134db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 13564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiNanIface = iface; 13664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiAwareStateManager.enableUsage(); 13764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 13864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 13964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 14064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 14164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private void awareIsDown() { 142448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen synchronized (mLock) { 143448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen if (DBG) Log.d(TAG, "awareIsDown: mWifiNanIface=" + mWifiNanIface); 144448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen if (mWifiNanIface != null) { 14564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiNanIface = null; 14664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiAwareStateManager.disableUsage(); 14764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 14864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 14964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 15064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 15164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private class InterfaceDestroyedListener implements 15264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen HalDeviceManager.InterfaceDestroyedListener { 15364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen @Override 154968a755132c525e5e1f1224a05eef7a58809fbd9Roshan Pius public void onDestroyed(@NonNull String ifaceName) { 15564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Interface was destroyed"); 15664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen awareIsDown(); 15764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 15864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 15964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 16064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private class InterfaceAvailableForRequestListener implements 16164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen HalDeviceManager.InterfaceAvailableForRequestListener { 16264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen @Override 16364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen public void onAvailableForRequest() { 16464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Interface is possibly available"); 16564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen tryToGetAware(); 16664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 16764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 168db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen 169db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen private static String statusString(WifiStatus status) { 170db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen if (status == null) { 171db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return "status=null"; 172db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 173db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen StringBuilder sb = new StringBuilder(); 174db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen sb.append(status.code).append(" (").append(status.description).append(")"); 175db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return sb.toString(); 176db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 177db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen 178db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen /** 179db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Dump the internal state of the class. 180db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen */ 181db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 182db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen pw.println("WifiAwareNativeManager:"); 183db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen pw.println(" mWifiNanIface: " + mWifiNanIface); 1849572e8b6de6cb7912df530ae2376452bf1469b33Etan Cohen mWifiAwareNativeCallback.dump(fd, pw, args); 185db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mHalDeviceManager.dump(fd, pw, args); 186db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 18764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen} 188