summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2018-04-24 15:55:38 -0700
committerRoshan Pius <rpius@google.com>2018-04-30 14:17:13 -0700
commitf5749a73fe63a3e01db62a9752be365fb40ec633 (patch)
treec1d955c805db677cbe5d432d50f8a0a5dc5d63b1 /service
parent7d8f472a86f2d2dee7719c1e467d808608fcfe0a (diff)
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
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java39
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java101
2 files changed, 136 insertions, 4 deletions
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
@@ -1881,6 +1881,45 @@ public class WifiNative {
}
/**
+ * 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
*/
public boolean isHalStarted() {
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<IfaceInfo> ifaceList1, List<IfaceInfo> ifaceList2) {
+ List<String> ifaceNamesList1 = ifaceList1
+ .stream()
+ .map(i -> i.name)
+ .collect(Collectors.toList());
+ List<String> ifaceNamesList2 = ifaceList2
+ .stream()
+ .map(i -> i.name)
+ .collect(Collectors.toList());
+ return ifaceNamesList1.containsAll(ifaceNamesList2);
+ }
+
+ private boolean areSameIfaces(List<IfaceInfo> ifaceList1, List<IfaceInfo> ifaceList2) {
+ return ifaceList1.containsAll(ifaceList2);
+ }
+
@Override
- public void onRadioModeChange(
- ArrayList<android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo>
- radioModeInfoList) {
- // Need to handle this callback.
+ public void onRadioModeChange(ArrayList<RadioModeInfo> 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);
+ }
+ }
}
}