WifiAwareNativeManager.java revision 9572e8b6de6cb7912df530ae2376452bf1469b33
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi.aware; 18 19import android.hardware.wifi.V1_0.IWifiNanIface; 20import android.hardware.wifi.V1_0.IfaceType; 21import android.hardware.wifi.V1_0.WifiStatus; 22import android.hardware.wifi.V1_0.WifiStatusCode; 23import android.os.RemoteException; 24import android.util.Log; 25 26import com.android.internal.annotations.VisibleForTesting; 27import com.android.server.wifi.HalDeviceManager; 28 29import java.io.FileDescriptor; 30import java.io.PrintWriter; 31 32/** 33 * Manages the interface to Wi-Fi Aware HIDL (HAL). 34 */ 35public class WifiAwareNativeManager { 36 private static final String TAG = "WifiAwareNativeManager"; 37 private static final boolean DBG = false; 38 39 // to be used for synchronizing access to any of the WifiAwareNative objects 40 private final Object mLock = new Object(); 41 42 private WifiAwareStateManager mWifiAwareStateManager; 43 private HalDeviceManager mHalDeviceManager; 44 private WifiAwareNativeCallback mWifiAwareNativeCallback; 45 private IWifiNanIface mWifiNanIface = null; 46 private InterfaceDestroyedListener mInterfaceDestroyedListener = 47 new InterfaceDestroyedListener(); 48 private InterfaceAvailableForRequestListener mInterfaceAvailableForRequestListener = 49 new InterfaceAvailableForRequestListener(); 50 51 WifiAwareNativeManager(WifiAwareStateManager awareStateManager, 52 HalDeviceManager halDeviceManager, 53 WifiAwareNativeCallback wifiAwareNativeCallback) { 54 mWifiAwareStateManager = awareStateManager; 55 mHalDeviceManager = halDeviceManager; 56 mWifiAwareNativeCallback = wifiAwareNativeCallback; 57 } 58 59 public void start() { 60 mHalDeviceManager.registerStatusListener( 61 new HalDeviceManager.ManagerStatusListener() { 62 @Override 63 public void onStatusChanged() { 64 if (DBG) Log.d(TAG, "onStatusChanged"); 65 // only care about isStarted (Wi-Fi started) not isReady - since if not 66 // ready then Wi-Fi will also be down. 67 if (mHalDeviceManager.isStarted()) { 68 // 1. no problem registering duplicates - only one will be called 69 // 2. will be called immediately if available 70 mHalDeviceManager.registerInterfaceAvailableForRequestListener( 71 IfaceType.NAN, mInterfaceAvailableForRequestListener, null); 72 } else { 73 awareIsDown(); 74 } 75 } 76 }, null); 77 if (mHalDeviceManager.isStarted()) { 78 mHalDeviceManager.registerInterfaceAvailableForRequestListener( 79 IfaceType.NAN, mInterfaceAvailableForRequestListener, null); 80 tryToGetAware(); 81 } 82 } 83 84 /** 85 * Returns the native HAL WifiNanIface through which commands to the NAN HAL are dispatched. 86 * Return may be null if not initialized/available. 87 */ 88 @VisibleForTesting 89 public IWifiNanIface getWifiNanIface() { 90 synchronized (mLock) { 91 return mWifiNanIface; 92 } 93 } 94 95 /** 96 * Attempt to obtain the HAL NAN interface. If available then enables Aware usage. 97 */ 98 private void tryToGetAware() { 99 synchronized (mLock) { 100 if (DBG) Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface); 101 102 if (mWifiNanIface != null) { 103 return; 104 } 105 IWifiNanIface iface = mHalDeviceManager.createNanIface(mInterfaceDestroyedListener, 106 null); 107 if (iface == null) { 108 if (DBG) Log.d(TAG, "Was not able to obtain an IWifiNanIface"); 109 } else { 110 if (DBG) Log.d(TAG, "Obtained an IWifiNanIface"); 111 112 try { 113 WifiStatus status = iface.registerEventCallback(mWifiAwareNativeCallback); 114 if (status.code != WifiStatusCode.SUCCESS) { 115 Log.e(TAG, "IWifiNanIface.registerEventCallback error: " + statusString( 116 status)); 117 mHalDeviceManager.removeIface(iface); 118 return; 119 } 120 } catch (RemoteException e) { 121 Log.e(TAG, "IWifiNanIface.registerEventCallback exception: " + e); 122 mHalDeviceManager.removeIface(iface); 123 return; 124 } 125 mWifiNanIface = iface; 126 mWifiAwareStateManager.enableUsage(); 127 } 128 } 129 } 130 131 private void awareIsDown() { 132 synchronized (mLock) { 133 if (DBG) Log.d(TAG, "awareIsDown: mWifiNanIface=" + mWifiNanIface); 134 if (mWifiNanIface != null) { 135 mWifiNanIface = null; 136 mWifiAwareStateManager.disableUsage(); 137 } 138 } 139 } 140 141 private class InterfaceDestroyedListener implements 142 HalDeviceManager.InterfaceDestroyedListener { 143 @Override 144 public void onDestroyed() { 145 if (DBG) Log.d(TAG, "Interface was destroyed"); 146 awareIsDown(); 147 } 148 } 149 150 private class InterfaceAvailableForRequestListener implements 151 HalDeviceManager.InterfaceAvailableForRequestListener { 152 @Override 153 public void onAvailableForRequest() { 154 if (DBG) Log.d(TAG, "Interface is possibly available"); 155 tryToGetAware(); 156 } 157 } 158 159 private static String statusString(WifiStatus status) { 160 if (status == null) { 161 return "status=null"; 162 } 163 StringBuilder sb = new StringBuilder(); 164 sb.append(status.code).append(" (").append(status.description).append(")"); 165 return sb.toString(); 166 } 167 168 /** 169 * Dump the internal state of the class. 170 */ 171 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 172 pw.println("WifiAwareNativeManager:"); 173 pw.println(" mWifiNanIface: " + mWifiNanIface); 174 mWifiAwareNativeCallback.dump(fd, pw, args); 175 mHalDeviceManager.dump(fd, pw, args); 176 } 177} 178