From f5749a73fe63a3e01db62a9752be365fb40ec633 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 24 Apr 2018 15:55:38 -0700 Subject: WifiVendorHal: Add callbacks for radio mode change detection Plumb the radio change callbacks to WifiNative. We're interested in collecting metrics for each of these radio mode changes. Note: Plumbing to WifiNative and WifiMetrics will be taken up in follow up CL's. Bug: 69117051 Test: Unit tests Test: Manually verified logs using STA + AP in DBS & SCC mode. Change-Id: I6e49e9522b75d1661f1a8be2805f21d16a5b3bbe --- .../java/com/android/server/wifi/WifiNative.java | 39 ++++++++ .../com/android/server/wifi/WifiVendorHal.java | 101 ++++++++++++++++++++- 2 files changed, 136 insertions(+), 4 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 8a76c4d3b..0be2b199d 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -1880,6 +1880,45 @@ public class WifiNative { void onDeath(); } + /** + * Callback to notify when vendor HAL detects that a change in radio mode. + */ + public interface VendorHalRadioModeChangeEventHandler { + /** + * Invoked when the vendor HAL detects a change to MCC mode. + * MCC (Multi channel concurrency) = Multiple interfaces are active on the same band, + * different channels, same radios. + * + * @param band Band on which MCC is detected (specified by one of the + * WifiScanner.WIFI_BAND_* constants) + */ + void onMcc(int band); + /** + * Invoked when the vendor HAL detects a change to SCC mode. + * SCC (Single channel concurrency) = Multiple interfaces are active on the same band, same + * channels, same radios. + * + * @param band Band on which SCC is detected (specified by one of the + * WifiScanner.WIFI_BAND_* constants) + */ + void onScc(int band); + /** + * Invoked when the vendor HAL detects a change to SBS mode. + * SBS (Single Band Simultaneous) = Multiple interfaces are active on the same band, + * different channels, different radios. + * + * @param band Band on which SBS is detected (specified by one of the + * WifiScanner.WIFI_BAND_* constants) + */ + void onSbs(int band); + /** + * Invoked when the vendor HAL detects a change to DBS mode. + * DBS (Dual Band Simultaneous) = Multiple interfaces are active on the different bands, + * different channels, different radios. + */ + void onDbs(); + } + /** * Tests whether the HAL is running or not */ diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java index 16a279833..8dd4509f6 100644 --- a/service/java/com/android/server/wifi/WifiVendorHal.java +++ b/service/java/com/android/server/wifi/WifiVendorHal.java @@ -85,7 +85,9 @@ import libcore.util.NonNull; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** * Vendor HAL via HIDL @@ -302,6 +304,20 @@ public class WifiVendorHal { } } + private WifiNative.VendorHalRadioModeChangeEventHandler mRadioModeChangeEventHandler; + + /** + * Register to listen for radio mode change events from the HAL. + * + * @param handler Handler to notify when the vendor HAL detects a radio mode change. + */ + public void registerRadioModeChangeHandler( + WifiNative.VendorHalRadioModeChangeEventHandler handler) { + synchronized (sLock) { + mRadioModeChangeEventHandler = handler; + } + } + /** * Returns whether the vendor HAL is supported on this device or not. */ @@ -2920,12 +2936,89 @@ public class WifiVendorHal { mIWifiChipEventCallback.onDebugErrorAlert(errorCode, debugData); } + private boolean areSameIfaceNames(List ifaceList1, List ifaceList2) { + List ifaceNamesList1 = ifaceList1 + .stream() + .map(i -> i.name) + .collect(Collectors.toList()); + List ifaceNamesList2 = ifaceList2 + .stream() + .map(i -> i.name) + .collect(Collectors.toList()); + return ifaceNamesList1.containsAll(ifaceNamesList2); + } + + private boolean areSameIfaces(List ifaceList1, List ifaceList2) { + return ifaceList1.containsAll(ifaceList2); + } + @Override - public void onRadioModeChange( - ArrayList - radioModeInfoList) { - // Need to handle this callback. + public void onRadioModeChange(ArrayList radioModeInfoList) { mVerboseLog.d("onRadioModeChange " + radioModeInfoList); + WifiNative.VendorHalRadioModeChangeEventHandler handler; + synchronized (sLock) { + if (mRadioModeChangeEventHandler == null || radioModeInfoList == null) return; + handler = mRadioModeChangeEventHandler; + } + // Should only contain 1 or 2 radio infos. + if (radioModeInfoList.size() == 0 || radioModeInfoList.size() > 2) { + mLog.e("Unexpected number of radio info in list " + radioModeInfoList.size()); + return; + } + // Not concurrency scenario, uninteresting... + if (radioModeInfoList.size() == 1) return; + + RadioModeInfo radioModeInfo0 = radioModeInfoList.get(0); + RadioModeInfo radioModeInfo1 = radioModeInfoList.get(1); + // Number of ifaces on each radio should be equal. + if (radioModeInfo0.ifaceInfos.size() != radioModeInfo1.ifaceInfos.size()) { + mLog.e("Unexpected number of iface info in list " + + radioModeInfo0.ifaceInfos.size() + ", " + + radioModeInfo1.ifaceInfos.size()); + return; + } + int numIfacesOnEachRadio = radioModeInfo0.ifaceInfos.size(); + // Only 1 or 2 ifaces should be present on each radio. + if (numIfacesOnEachRadio == 0 || numIfacesOnEachRadio > 2) { + mLog.e("Unexpected number of iface info in list " + numIfacesOnEachRadio); + return; + } + // 2 ifaces simultaneous on 2 radios. + if (numIfacesOnEachRadio == 1) { + // Iface on radio0 should be different from the iface on radio1 for DBS & SBS. + if (areSameIfaceNames(radioModeInfo0.ifaceInfos, radioModeInfo1.ifaceInfos)) { + mLog.e("Unexpected for both radio infos to have same iface"); + return; + } + if (radioModeInfo0.bandInfo != radioModeInfo1.bandInfo) { + mLog.i("Device is in DBS mode now"); + handler.onDbs(); + } else { + mLog.i("Device is in SBS mode now"); + handler.onSbs(radioModeInfo0.bandInfo); + } + // 2 ifaces time sharing on 2 radios. + } else { + // Ifaces on radio0 & radio1 should be the same for MCC & SCC. + if (!areSameIfaces(radioModeInfo0.ifaceInfos, radioModeInfo1.ifaceInfos)) { + mLog.e("Unexpected for both radio infos to have different ifaces"); + return; + } + // Both radio0 & radio1 should now be in the same band (could be 5G or 2G). + if (radioModeInfo0.bandInfo != radioModeInfo1.bandInfo) { + mLog.e("Unexpected for both radio infos to have different band"); + return; + } + IfaceInfo ifaceInfo0 = radioModeInfo0.ifaceInfos.get(0); + IfaceInfo ifaceInfo1 = radioModeInfo0.ifaceInfos.get(1); + if (ifaceInfo0.channel != ifaceInfo1.channel) { + mLog.i("Device is in MCC mode now"); + handler.onMcc(radioModeInfo0.bandInfo); + } else { + mLog.i("Device is in SCC mode now"); + handler.onScc(radioModeInfo0.bandInfo); + } + } } } -- cgit v1.2.3