1 /* 2 * Copyright (C) 2022 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.mockwifi; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.ServiceConnection; 23 import android.net.wifi.nl80211.WifiNl80211Manager; 24 import android.os.IBinder; 25 import android.util.Log; 26 27 import com.android.server.wifi.WifiMonitor; 28 29 /** This class provides wrapper APIs for binding interfaces to mock service. */ 30 public class MockWifiServiceUtil { 31 private static final String TAG = "MockWifiModemUtil"; 32 private static final String BIND_NL80211 = "android.wifi.mockwifimodem.nl80211"; 33 private static final int MOCK_NL80211_SERVICE = 0; 34 35 public static final int MIN_SERVICE_IDX = MOCK_NL80211_SERVICE; 36 public static final int NUM_SERVICES = 1; 37 public static final int BINDER_RETRY_MILLIS = 3 * 100; 38 public static final int BINDER_MAX_RETRY = 3; 39 40 public static final String METHOD_SEPARATOR = ","; 41 public static final String CLASS_IDENTIFIER = "-"; 42 43 private static final String TAG_MOCK_NL80211 = "WifiNL80211ManagerImp"; 44 45 private Context mContext; 46 private WifiMonitor mWifiMonitor; 47 private String mServiceName; 48 private String mPackageName; 49 private MockWifiNl80211Manager mMockWifiNl80211Manager; 50 private IBinder mMockNl80211Binder; 51 private ServiceConnection mMockNl80211ServiceConnection; 52 MockWifiServiceUtil(Context context, String serviceName, WifiMonitor wifiMonitor)53 public MockWifiServiceUtil(Context context, String serviceName, WifiMonitor wifiMonitor) { 54 mContext = context; 55 mWifiMonitor = wifiMonitor; 56 String[] componentInfo = serviceName.split("/", 2); 57 mPackageName = componentInfo[0]; 58 mServiceName = componentInfo[1]; 59 } 60 61 private class MockModemConnection implements ServiceConnection { 62 private int mService; 63 MockModemConnection(int module)64 MockModemConnection(int module) { 65 mService = module; 66 } 67 68 @Override onServiceConnected(ComponentName name, IBinder binder)69 public void onServiceConnected(ComponentName name, IBinder binder) { 70 Log.d(TAG, "Wifi mock Service " + getModuleName(mService) + " - onServiceConnected"); 71 if (mService == MOCK_NL80211_SERVICE) { 72 mMockNl80211Binder = binder; 73 mMockWifiNl80211Manager = new MockWifiNl80211Manager(mMockNl80211Binder, mContext, 74 mWifiMonitor); 75 } 76 77 } 78 79 @Override onServiceDisconnected(ComponentName name)80 public void onServiceDisconnected(ComponentName name) { 81 Log.d(TAG, "Wifi mock Service " + getModuleName(mService) 82 + " - onServiceDisconnected"); 83 if (mService == MOCK_NL80211_SERVICE) { 84 mMockNl80211Binder = null; 85 mMockWifiNl80211Manager = null; 86 } 87 } 88 } 89 bindModuleToMockModemService( String actionName, ServiceConnection serviceConnection)90 private boolean bindModuleToMockModemService( 91 String actionName, ServiceConnection serviceConnection) { 92 boolean status = false; 93 94 Intent intent = new Intent(); 95 intent.setComponent(new ComponentName(mPackageName, mServiceName)); 96 intent.setAction(actionName); 97 98 status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); 99 return status; 100 } 101 102 /** waitForBinder */ getServiceBinder(int service)103 public IBinder getServiceBinder(int service) { 104 switch (service) { 105 case MOCK_NL80211_SERVICE: 106 return mMockNl80211Binder; 107 default: 108 return null; 109 } 110 } 111 112 /** Binding interfaces with mock modem service */ bindAllMockModemService()113 public void bindAllMockModemService() { 114 for (int service = MIN_SERVICE_IDX; service < NUM_SERVICES; service++) { 115 bindToMockModemService(service); 116 } 117 } 118 119 /** bindToMockModemService */ bindToMockModemService(int service)120 public void bindToMockModemService(int service) { 121 // Based on {@code service} to get each mocked HAL binder 122 if (service == MOCK_NL80211_SERVICE) { 123 mMockNl80211ServiceConnection = new MockModemConnection(MOCK_NL80211_SERVICE); 124 125 boolean status = 126 bindModuleToMockModemService(BIND_NL80211, mMockNl80211ServiceConnection); 127 if (!status) { 128 Log.d(TAG, getModuleName(service) + " bind fail"); 129 mMockNl80211ServiceConnection = null; 130 } 131 } 132 } 133 getServiceName()134 public String getServiceName() { 135 return mServiceName; 136 } 137 getServiceConnection(int service)138 private ServiceConnection getServiceConnection(int service) { 139 switch (service) { 140 case MOCK_NL80211_SERVICE: 141 return mMockNl80211ServiceConnection; 142 default: 143 return null; 144 } 145 } 146 147 /** 148 * Returns name of the provided service. 149 */ getModuleName(int service)150 public String getModuleName(int service) { 151 switch (service) { 152 case MOCK_NL80211_SERVICE: 153 return "nl80211"; 154 default: 155 return "none"; 156 } 157 } 158 159 /** 160 * set mocked methods. 161 * 162 * @param methods mocked methods with format HAL-method, ... 163 */ setMockedMethods(String methods)164 public boolean setMockedMethods(String methods) { 165 Log.i(TAG, "setMockedMethods - " + methods); 166 if (methods == null) { 167 return false; 168 } 169 if (mMockWifiNl80211Manager != null) { 170 mMockWifiNl80211Manager.resetMockedMethods(); 171 } 172 String[] mockedMethods = methods.split(METHOD_SEPARATOR); 173 for (String mockedMethod : mockedMethods) { 174 String[] mockedMethodInfo = mockedMethod.split(CLASS_IDENTIFIER); 175 if (mockedMethodInfo.length != 2) { 176 return false; 177 } 178 String mockedClassName = mockedMethodInfo[0]; 179 String mockedMethodName = mockedMethodInfo[1]; 180 if (TAG_MOCK_NL80211.equals(mockedClassName) && mMockWifiNl80211Manager != null) { 181 mMockWifiNl80211Manager.addMockedMethod(mockedMethodName); 182 } 183 } 184 return true; 185 } 186 getMockWifiNl80211Manager()187 public MockWifiNl80211Manager getMockWifiNl80211Manager() { 188 return mMockWifiNl80211Manager; 189 } 190 getWifiNl80211Manager()191 public WifiNl80211Manager getWifiNl80211Manager() { 192 return mMockWifiNl80211Manager == null 193 ? null : mMockWifiNl80211Manager.getWifiNl80211Manager(); 194 } 195 } 196