• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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