1 /* 2 * Copyright (C) 2024 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 17 package com.android.server.wifi.b2b; 18 19 import android.hardware.wifi.WifiStatusCode; 20 import android.net.wifi.WifiManager; 21 import android.net.wifi.WifiSsid; 22 import android.util.Log; 23 24 import com.android.server.wifi.ActiveModeWarden; 25 import com.android.server.wifi.WifiNative; 26 import com.android.server.wifi.WifiRoamingConfigStore; 27 28 import java.io.FileDescriptor; 29 import java.io.PrintWriter; 30 import java.util.Map; 31 32 public class WifiRoamingModeManager { 33 private static final String TAG = "WifiRoamingModeManager"; 34 private final WifiNative mWifiNative; 35 private final WifiRoamingConfigStore mWifiRoamingConfigStore; 36 private final ActiveModeWarden mActiveModeWarden; 37 private boolean mVerboseLoggingEnabled = false; 38 WifiRoamingModeManager(WifiNative wifiNative, ActiveModeWarden activeModeWarden, WifiRoamingConfigStore wifiRoamingConfigStore)39 public WifiRoamingModeManager(WifiNative wifiNative, 40 ActiveModeWarden activeModeWarden, 41 WifiRoamingConfigStore wifiRoamingConfigStore) { 42 this.mWifiNative = wifiNative; 43 this.mWifiRoamingConfigStore = wifiRoamingConfigStore; 44 this.mActiveModeWarden = activeModeWarden; 45 } 46 47 /** 48 * To handle policy updates when device is already in connected state 49 * and also when policy get removed in connected state. 50 */ checkAndUpdatePolicy(String updatedSsid)51 private void checkAndUpdatePolicy(String updatedSsid) { 52 String currentSsid = mActiveModeWarden.getConnectionInfo().getSSID(); 53 if (!updatedSsid.equals(currentSsid)) return; 54 String ifaceName = mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName(); 55 if (currentSsid != null && ifaceName != null) { 56 if (mVerboseLoggingEnabled) { 57 Log.i(TAG, "Re-applying roaming policy as it updated"); 58 } 59 applyWifiRoamingMode(ifaceName, currentSsid); 60 } 61 } 62 63 /** 64 * Add a new network roaming policy. 65 * 66 * @param ssid name of the network on which policy is to be added. 67 * @param roamingMode denotes roaming mode value configured. 68 * @param isDeviceOwner flag denoting whether API is called by the device owner. 69 */ setPerSsidRoamingMode(WifiSsid ssid, @WifiManager.RoamingMode int roamingMode, boolean isDeviceOwner)70 public void setPerSsidRoamingMode(WifiSsid ssid, @WifiManager.RoamingMode int roamingMode, 71 boolean isDeviceOwner) { 72 mWifiRoamingConfigStore.addRoamingMode(ssid.toString(), roamingMode, isDeviceOwner); 73 checkAndUpdatePolicy(ssid.toString()); 74 } 75 76 /** 77 * Remove the network roaming policy for the given ssid. 78 * 79 * @param ssid name of the network on which policy is to be removed. 80 * @param isDeviceOwner flag denoting whether API is called by the device owner. 81 */ removePerSsidRoamingMode(WifiSsid ssid, boolean isDeviceOwner)82 public void removePerSsidRoamingMode(WifiSsid ssid, boolean isDeviceOwner) { 83 mWifiRoamingConfigStore.removeRoamingMode(ssid.toString(), isDeviceOwner); 84 checkAndUpdatePolicy(ssid.toString()); 85 } 86 87 /** 88 * Get all the network roaming policies configured. 89 * 90 * @param isDeviceOwner flag denoting whether API is called by the device owner. 91 * @return Map of corresponding policies for the API caller, 92 * where key is ssid and value is roaming mode/policy configured for that ssid. 93 */ getPerSsidRoamingModes(boolean isDeviceOwner)94 public Map<String, Integer> getPerSsidRoamingModes(boolean isDeviceOwner) { 95 return mWifiRoamingConfigStore.getPerSsidRoamingModes(isDeviceOwner); 96 } 97 98 /** 99 * Apply roaming policy to the provided network. 100 * If policy does not exist, apply normal roaming policy. 101 * 102 * @param iface represents the name of the wifi interface. 103 * @param ssid represents the name of the network. 104 */ applyWifiRoamingMode(String iface, String ssid)105 public void applyWifiRoamingMode(String iface, String ssid) { 106 int roamingMode = mWifiRoamingConfigStore.getRoamingMode(ssid); 107 if (mVerboseLoggingEnabled) { 108 Log.i(TAG, "Applying roaming policy for network " 109 + ssid + " with value " + roamingMode); 110 } 111 @WifiStatusCode int errorCode = mWifiNative.setRoamingMode(iface, roamingMode); 112 switch (errorCode) { 113 case WifiStatusCode.SUCCESS: 114 if (mVerboseLoggingEnabled) { 115 Log.d(TAG, "Roaming mode value successfully set to: " + roamingMode); 116 } 117 break; 118 case WifiStatusCode.ERROR_NOT_STARTED: 119 Log.e(TAG, "Failed to set roaming mode as WifiStaIfaceAidlImpl" 120 + " instance is not created."); 121 break; 122 case WifiStatusCode.ERROR_WIFI_IFACE_INVALID: 123 Log.e(TAG, "Failed to set roaming mode as interface is invalid."); 124 break; 125 case WifiStatusCode.ERROR_INVALID_ARGS: 126 Log.e(TAG, "Failed to set roaming mode due to invalid parameter " 127 + roamingMode); 128 break; 129 default: 130 Log.e(TAG, "Failed to set roaming mode due to unknown error."); 131 } 132 } 133 134 /** 135 * Enable verbose logging. 136 */ enableVerboseLogging(boolean verboseEnabled)137 public void enableVerboseLogging(boolean verboseEnabled) { 138 mVerboseLoggingEnabled = verboseEnabled; 139 } 140 141 /** 142 * Dump roaming policies for debugging. 143 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)144 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 145 mWifiRoamingConfigStore.dump(fd, pw, args); 146 } 147 } 148