WifiAwareNativeManager.java revision 0b31edb987c0552b75667e05f0d589937a16f1ad
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 1964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport android.hardware.wifi.V1_0.IWifiNanIface; 20448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohenimport android.hardware.wifi.V1_0.IfaceType; 21db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatus; 22db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatusCode; 23db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.os.RemoteException; 2464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport android.util.Log; 2564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 2664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenimport com.android.server.wifi.HalDeviceManager; 2764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 28db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.FileDescriptor; 29db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.PrintWriter; 30db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen 3164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen/** 3264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen * Manages the interface to Wi-Fi Aware HIDL (HAL). 3364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen */ 3464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohenclass WifiAwareNativeManager { 3564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private static final String TAG = "WifiAwareNativeManager"; 3664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private static final boolean DBG = false; 3764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 3864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen // to be used for synchronizing access to any of the WifiAwareNative objects 3964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private final Object mLock = new Object(); 4064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 4164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private WifiAwareStateManager mWifiAwareStateManager; 4264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private HalDeviceManager mHalDeviceManager; 43db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen private WifiAwareNativeCallback mWifiAwareNativeCallback; 4464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private IWifiNanIface mWifiNanIface = null; 4564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private InterfaceDestroyedListener mInterfaceDestroyedListener = 4664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen new InterfaceDestroyedListener(); 4764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private InterfaceAvailableForRequestListener mInterfaceAvailableForRequestListener = 4864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen new InterfaceAvailableForRequestListener(); 4964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 5064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen WifiAwareNativeManager(WifiAwareStateManager awareStateManager, 51db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen HalDeviceManager halDeviceManager, 52db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen WifiAwareNativeCallback wifiAwareNativeCallback) { 5364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiAwareStateManager = awareStateManager; 5464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mHalDeviceManager = halDeviceManager; 55db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mWifiAwareNativeCallback = wifiAwareNativeCallback; 560b31edb987c0552b75667e05f0d589937a16f1adEtan Cohen } 570b31edb987c0552b75667e05f0d589937a16f1adEtan Cohen 580b31edb987c0552b75667e05f0d589937a16f1adEtan Cohen public void start() { 593145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen mHalDeviceManager.registerStatusListener( 603145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen new HalDeviceManager.ManagerStatusListener() { 6164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen @Override 623145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen public void onStatusChanged() { 633145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (DBG) Log.d(TAG, "onStatusChanged"); 643145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen // only care about isStarted (Wi-Fi started) not isReady - since if not 653145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen // ready then Wi-Fi will also be down. 663145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (mHalDeviceManager.isStarted()) { 67448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen // 1. no problem registering duplicates - only one will be called 68448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen // 2. will be called immediately if available 69448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen mHalDeviceManager.registerInterfaceAvailableForRequestListener( 70448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen IfaceType.NAN, mInterfaceAvailableForRequestListener, null); 713145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } else { 723145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen awareIsDown(); 733145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } 7464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 7564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen }, null); 763145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (mHalDeviceManager.isStarted()) { 773145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen tryToGetAware(); 783145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } 7964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 8064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 8164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen /* package */ IWifiNanIface getWifiNanIface() { 8264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen synchronized (mLock) { 8364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen return mWifiNanIface; 8464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 8564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 8664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 8764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private void tryToGetAware() { 8864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen synchronized (mLock) { 89448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen if (DBG) Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface); 90448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen 913145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen if (mWifiNanIface != null) { 923145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen return; 933145bb4d3359647cccd9b4aba1734066f36bb2e6Etan Cohen } 94448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen IWifiNanIface iface = mHalDeviceManager.createNanIface(mInterfaceDestroyedListener, 95448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen null); 9664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (iface == null) { 9764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Was not able to obtain an IWifiNanIface"); 9864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } else { 9964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Obtained an IWifiNanIface"); 10064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 101db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen try { 102db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen WifiStatus status = iface.registerEventCallback(mWifiAwareNativeCallback); 103db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen if (status.code != WifiStatusCode.SUCCESS) { 104db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen Log.e(TAG, "IWifiNanIface.registerEventCallback error: " + statusString( 105db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen status)); 106db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mHalDeviceManager.removeIface(iface); 107db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return; 108db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 109db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } catch (RemoteException e) { 110db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen Log.e(TAG, "IWifiNanIface.registerEventCallback exception: " + e); 111db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mHalDeviceManager.removeIface(iface); 112db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return; 113db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 11464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiNanIface = iface; 11564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiAwareStateManager.enableUsage(); 11664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 11764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 11864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 11964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 12064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private void awareIsDown() { 121448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen synchronized (mLock) { 122448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen if (DBG) Log.d(TAG, "awareIsDown: mWifiNanIface=" + mWifiNanIface); 123448a7b6b7b16cf39ed25729ceaf61edb30368567Etan Cohen if (mWifiNanIface != null) { 12464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiNanIface = null; 12564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen mWifiAwareStateManager.disableUsage(); 12664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 12764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 12864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 12964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 13064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private class InterfaceDestroyedListener implements 13164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen HalDeviceManager.InterfaceDestroyedListener { 13264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen @Override 13364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen public void onDestroyed() { 13464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Interface was destroyed"); 13564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen awareIsDown(); 13664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 13764ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 13864ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen 13964ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen private class InterfaceAvailableForRequestListener implements 14064ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen HalDeviceManager.InterfaceAvailableForRequestListener { 14164ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen @Override 14264ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen public void onAvailableForRequest() { 14364ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen if (DBG) Log.d(TAG, "Interface is possibly available"); 14464ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen tryToGetAware(); 14564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 14664ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen } 147db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen 148db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen private static String statusString(WifiStatus status) { 149db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen if (status == null) { 150db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return "status=null"; 151db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 152db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen StringBuilder sb = new StringBuilder(); 153db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen sb.append(status.code).append(" (").append(status.description).append(")"); 154db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen return sb.toString(); 155db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 156db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen 157db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen /** 158db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Dump the internal state of the class. 159db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen */ 160db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 161db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen pw.println("WifiAwareNativeManager:"); 162db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen pw.println(" mWifiNanIface: " + mWifiNanIface); 163db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen mHalDeviceManager.dump(fd, pw, args); 164db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen } 16564ce9f185eb6097c1c358c44710be6e1ca7c7055Etan Cohen} 166