• 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.hal;
18 
19 import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_160;
20 import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_320;
21 import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_40;
22 import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_80;
23 import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_80P80;
24 import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE;
25 
26 import android.annotation.NonNull;
27 import android.annotation.Nullable;
28 import android.content.Context;
29 import android.content.res.Resources;
30 import android.hardware.wifi.V1_0.IWifiChipEventCallback;
31 import android.hardware.wifi.V1_0.IfaceType;
32 import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
33 import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
34 import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
35 import android.hardware.wifi.V1_0.WifiStatus;
36 import android.hardware.wifi.V1_0.WifiStatusCode;
37 import android.hardware.wifi.V1_5.WifiBand;
38 import android.hardware.wifi.V1_5.WifiIfaceMode;
39 import android.hardware.wifi.V1_6.IfaceConcurrencyType;
40 import android.hardware.wifi.V1_6.WifiAntennaMode;
41 import android.hardware.wifi.V1_6.WifiRadioCombination;
42 import android.hardware.wifi.V1_6.WifiRadioConfiguration;
43 import android.net.wifi.CoexUnsafeChannel;
44 import android.net.wifi.OuiKeyedData;
45 import android.net.wifi.ScanResult;
46 import android.net.wifi.WifiAnnotations;
47 import android.net.wifi.WifiAvailableChannel;
48 import android.net.wifi.WifiManager;
49 import android.net.wifi.WifiScanner;
50 import android.os.RemoteException;
51 import android.util.Log;
52 import android.util.SparseIntArray;
53 
54 import com.android.internal.annotations.VisibleForTesting;
55 import com.android.modules.utils.build.SdkLevel;
56 import com.android.server.wifi.SarInfo;
57 import com.android.server.wifi.SsidTranslator;
58 import com.android.server.wifi.WifiNative;
59 import com.android.server.wifi.WlanWakeReasonAndCounts;
60 import com.android.server.wifi.util.BitMask;
61 import com.android.server.wifi.util.GeneralUtil.Mutable;
62 import com.android.server.wifi.util.NativeUtil;
63 import com.android.wifi.resources.R;
64 
65 import java.util.ArrayList;
66 import java.util.Arrays;
67 import java.util.List;
68 import java.util.function.Supplier;
69 
70 /**
71  * HIDL implementation of the WifiChip interface.
72  */
73 public class WifiChipHidlImpl implements IWifiChip {
74     private static final String TAG = "WifiChipHidlImpl";
75     private android.hardware.wifi.V1_0.IWifiChip mWifiChip;
76     private android.hardware.wifi.V1_0.IWifiChipEventCallback mHalCallback10;
77     private android.hardware.wifi.V1_2.IWifiChipEventCallback mHalCallback12;
78     private android.hardware.wifi.V1_4.IWifiChipEventCallback mHalCallback14;
79     private WifiChip.Callback mFrameworkCallback;
80     private Context mContext;
81     private SsidTranslator mSsidTranslator;
82     private boolean mIsBridgedSoftApSupported;
83     private boolean mIsStaWithBridgedSoftApConcurrencySupported;
84 
WifiChipHidlImpl(@onNull android.hardware.wifi.V1_0.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)85     public WifiChipHidlImpl(@NonNull android.hardware.wifi.V1_0.IWifiChip chip,
86             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
87         mWifiChip = chip;
88         mContext = context;
89         mSsidTranslator = ssidTranslator;
90         Resources res = context.getResources();
91         mIsBridgedSoftApSupported = res.getBoolean(R.bool.config_wifiBridgedSoftApSupported);
92         mIsStaWithBridgedSoftApConcurrencySupported =
93                 res.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported);
94     }
95 
96     /**
97      * See comments for {@link IWifiChip#configureChip(int)}
98      */
99     @Override
configureChip(int modeId)100     public boolean configureChip(int modeId) {
101         String methodStr = "configureChip";
102         return validateAndCall(methodStr, false,
103                 () -> configureChipInternal(methodStr, modeId));
104     }
105 
106     /**
107      * See comments for {@link IWifiChip#createApIface(List)}
108      */
109     @Override
110     @Nullable
createApIface(@onNull List<OuiKeyedData> vendorData)111     public WifiApIface createApIface(@NonNull List<OuiKeyedData> vendorData) {
112         String methodStr = "createApIface";
113         return validateAndCall(methodStr, null,
114                 () -> createApIfaceInternal(methodStr));
115     }
116 
117     /**
118      * See comments for {@link IWifiChip#createBridgedApIface(List)}
119      */
120     @Override
121     @Nullable
createBridgedApIface(@onNull List<OuiKeyedData> vendorData)122     public WifiApIface createBridgedApIface(@NonNull List<OuiKeyedData> vendorData) {
123         String methodStr = "createBridgedApIface";
124         return validateAndCall(methodStr, null,
125                 () -> createBridgedApIfaceInternal(methodStr));
126     }
127 
128     /**
129      * See comments for {@link IWifiChip#createNanIface()}
130      */
131     @Override
132     @Nullable
createNanIface()133     public WifiNanIface createNanIface() {
134         String methodStr = "createNanIface";
135         return validateAndCall(methodStr, null,
136                 () -> createNanIfaceInternal(methodStr));
137     }
138 
139     /**
140      * See comments for {@link IWifiChip#createP2pIface()}
141      */
142     @Override
143     @Nullable
createP2pIface()144     public WifiP2pIface createP2pIface() {
145         String methodStr = "createP2pIface";
146         return validateAndCall(methodStr, null,
147                 () -> createP2pIfaceInternal(methodStr));
148     }
149 
150     /**
151      * See comments for {@link IWifiChip#createRttController()}
152      */
153     @Override
154     @Nullable
createRttController()155     public WifiRttController createRttController() {
156         String methodStr = "createRttController";
157         return validateAndCall(methodStr, null,
158                 () -> createRttControllerInternal(methodStr));
159     }
160 
161     /**
162      * See comments for {@link IWifiChip#createStaIface()}
163      */
164     @Override
165     @Nullable
createStaIface()166     public WifiStaIface createStaIface() {
167         String methodStr = "createStaIface";
168         return validateAndCall(methodStr, null,
169                 () -> createStaIfaceInternal(methodStr));
170     }
171 
172     /**
173      * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)}
174      */
175     @Override
enableDebugErrorAlerts(boolean enable)176     public boolean enableDebugErrorAlerts(boolean enable) {
177         String methodStr = "enableDebugErrorAlerts";
178         return validateAndCall(methodStr, false,
179                 () -> enableDebugErrorAlertsInternal(methodStr, enable));
180     }
181 
182     /**
183      * See comments for {@link IWifiChip#flushRingBufferToFile()}
184      */
185     @Override
flushRingBufferToFile()186     public boolean flushRingBufferToFile() {
187         String methodStr = "flushRingBufferToFile";
188         return validateAndCall(methodStr, false,
189                 () -> flushRingBufferToFileInternal(methodStr));
190     }
191 
192     /**
193      * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)}
194      */
195     @Override
forceDumpToDebugRingBuffer(String ringName)196     public boolean forceDumpToDebugRingBuffer(String ringName) {
197         String methodStr = "forceDumpToDebugRingBuffer";
198         return validateAndCall(methodStr, false,
199                 () -> forceDumpToDebugRingBufferInternal(methodStr, ringName));
200     }
201 
202     /**
203      * See comments for {@link IWifiChip#getApIface(String)}
204      */
205     @Override
206     @Nullable
getApIface(String ifaceName)207     public WifiApIface getApIface(String ifaceName) {
208         String methodStr = "getApIface";
209         return validateAndCall(methodStr, null,
210                 () -> getApIfaceInternal(methodStr, ifaceName));
211     }
212 
213     /**
214      * See comments for {@link IWifiChip#getApIfaceNames()}
215      */
216     @Override
217     @Nullable
getApIfaceNames()218     public List<String> getApIfaceNames() {
219         String methodStr = "getApIfaceNames";
220         return validateAndCall(methodStr, null,
221                 () -> getApIfaceNamesInternal(methodStr));
222     }
223 
224     /**
225      * See comments for {@link IWifiChip#getAvailableModes()}
226      */
227     @Override
228     @Nullable
getAvailableModes()229     public List<WifiChip.ChipMode> getAvailableModes() {
230         String methodStr = "getAvailableModes";
231         return validateAndCall(methodStr, null,
232                 () -> getAvailableModesInternal(methodStr));
233     }
234 
235     /**
236      * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
237      */
238     @Override
getCapabilitiesBeforeIfacesExist()239     public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() {
240         String methodStr = "getCapabilitiesBeforeIfacesExist";
241         return validateAndCall(methodStr, new WifiChip.Response<>(0L),
242                 () -> getCapabilitiesBeforeIfacesExistInternal(methodStr));
243     }
244 
245     /**
246      * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
247      */
248     @Override
getCapabilitiesAfterIfacesExist()249     public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() {
250         String methodStr = "getCapabilitiesAfterIfacesExist";
251         return validateAndCall(methodStr, new WifiChip.Response<>(0L),
252                 () -> getCapabilitiesAfterIfacesExistInternal(methodStr));
253     }
254 
255     /**
256      * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()}
257      */
258     @Override
259     @Nullable
getDebugHostWakeReasonStats()260     public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() {
261         String methodStr = "getDebugHostWakeReasonStats";
262         return validateAndCall(methodStr, null,
263                 () -> getDebugHostWakeReasonStatsInternal(methodStr));
264     }
265 
266     /**
267      * See comments for {@link IWifiChip#getDebugRingBuffersStatus()}
268      */
269     @Override
270     @Nullable
getDebugRingBuffersStatus()271     public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() {
272         String methodStr = "getDebugRingBuffersStatus";
273         return validateAndCall(methodStr, null,
274                 () -> getDebugRingBuffersStatusInternal(methodStr));
275     }
276 
277     /**
278      * See comments for {@link IWifiChip#getId()}
279      */
280     @Override
getId()281     public int getId() {
282         String methodStr = "getId";
283         return validateAndCall(methodStr, -1, () -> getIdInternal(methodStr));
284     }
285 
286     /**
287      * See comments for {@link IWifiChip#getMode()}
288      */
289     @Override
getMode()290     public WifiChip.Response<Integer> getMode() {
291         String methodStr = "getMode";
292         return validateAndCall(methodStr, new WifiChip.Response<>(0),
293                 () -> getModeInternal(methodStr));
294     }
295 
296     /**
297      * See comments for {@link IWifiChip#getNanIface(String)}
298      */
299     @Override
300     @Nullable
getNanIface(String ifaceName)301     public WifiNanIface getNanIface(String ifaceName) {
302         String methodStr = "getNanIface";
303         return validateAndCall(methodStr, null,
304                 () -> getNanIfaceInternal(methodStr, ifaceName));
305     }
306 
307     /**
308      * See comments for {@link IWifiChip#getNanIfaceNames()}
309      */
310     @Override
311     @Nullable
getNanIfaceNames()312     public List<String> getNanIfaceNames() {
313         String methodStr = "getNanIfaceNames";
314         return validateAndCall(methodStr, null,
315                 () -> getNanIfaceNamesInternal(methodStr));
316     }
317 
318     /**
319      * See comments for {@link IWifiChip#getP2pIface(String)}
320      */
321     @Override
322     @Nullable
getP2pIface(String ifaceName)323     public WifiP2pIface getP2pIface(String ifaceName) {
324         String methodStr = "getP2pIface";
325         return validateAndCall(methodStr, null,
326                 () -> getP2pIfaceInternal(methodStr, ifaceName));
327     }
328 
329     /**
330      * See comments for {@link IWifiChip#getP2pIfaceNames()}
331      */
332     @Override
333     @Nullable
getP2pIfaceNames()334     public List<String> getP2pIfaceNames() {
335         String methodStr = "getP2pIfaceNames";
336         return validateAndCall(methodStr, null,
337                 () -> getP2pIfaceNamesInternal(methodStr));
338     }
339 
340     /**
341      * See comments for {@link IWifiChip#getStaIface(String)}
342      */
343     @Override
344     @Nullable
getStaIface(String ifaceName)345     public WifiStaIface getStaIface(String ifaceName) {
346         String methodStr = "getStaIface";
347         return validateAndCall(methodStr, null,
348                 () -> getStaIfaceInternal(methodStr, ifaceName));
349     }
350 
351     /**
352      * See comments for {@link IWifiChip#getStaIfaceNames()}
353      */
354     @Override
355     @Nullable
getStaIfaceNames()356     public List<String> getStaIfaceNames() {
357         String methodStr = "getStaIfaceNames";
358         return validateAndCall(methodStr, null,
359                 () -> getStaIfaceNamesInternal(methodStr));
360     }
361 
362     /**
363      * See comments for {@link IWifiChip#getSupportedRadioCombinations()}
364      */
365     @Override
366     @Nullable
getSupportedRadioCombinations()367     public List<WifiChip.WifiRadioCombination> getSupportedRadioCombinations() {
368         String methodStr = "getSupportedRadioCombinations";
369         return validateAndCall(methodStr, null,
370                 () -> getSupportedRadioCombinationsInternal(methodStr));
371     }
372 
373     /**
374      * See comments for {@link IWifiChip#getWifiChipCapabilities()}
375      */
getWifiChipCapabilities()376     public WifiChip.WifiChipCapabilities getWifiChipCapabilities() {
377         return null;
378     }
379 
380     /**
381      * See comments for {@link IWifiChip#getUsableChannels(int, int, int)}
382      */
383     @Override
384     @Nullable
getUsableChannels(@ifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter)385     public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
386             @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) {
387         String methodStr = "getUsableChannels";
388         return validateAndCall(methodStr, null,
389                 () -> getUsableChannelsInternal(methodStr, band, mode, filter));
390     }
391 
392     /**
393      * See comments for {@link IWifiChip#registerCallback(WifiChip.Callback)}
394      */
395     @Override
registerCallback(WifiChip.Callback callback)396     public boolean registerCallback(WifiChip.Callback callback) {
397         String methodStr = "registerCallback";
398         return validateAndCall(methodStr, false,
399                 () -> registerCallbackInternal(methodStr, callback));
400     }
401 
402     /**
403      * See comments for {@link IWifiChip#removeApIface(String)}
404      */
405     @Override
removeApIface(String ifaceName)406     public boolean removeApIface(String ifaceName) {
407         String methodStr = "removeApIface";
408         return validateAndCall(methodStr, false,
409                 () -> removeApIfaceInternal(methodStr, ifaceName));
410     }
411 
412     /**
413      * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)}
414      */
415     @Override
removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName)416     public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) {
417         String methodStr = "removeIfaceInstanceFromBridgedApIface";
418         return validateAndCall(methodStr, false,
419                 () -> removeIfaceInstanceFromBridgedApIfaceInternal(methodStr,
420                         brIfaceName, ifaceName));
421     }
422 
423     /**
424      * See comments for {@link IWifiChip#removeNanIface(String)}
425      */
426     @Override
removeNanIface(String ifaceName)427     public boolean removeNanIface(String ifaceName) {
428         String methodStr = "removeNanIface";
429         return validateAndCall(methodStr, false,
430                 () -> removeNanIfaceInternal(methodStr, ifaceName));
431     }
432 
433     /**
434      * See comments for {@link IWifiChip#removeP2pIface(String)}
435      */
436     @Override
removeP2pIface(String ifaceName)437     public boolean removeP2pIface(String ifaceName) {
438         String methodStr = "removeP2pIface";
439         return validateAndCall(methodStr, false,
440                 () -> removeP2pIfaceInternal(methodStr, ifaceName));
441     }
442 
443     /**
444      * See comments for {@link IWifiChip#removeStaIface(String)}
445      */
446     @Override
removeStaIface(String ifaceName)447     public boolean removeStaIface(String ifaceName) {
448         String methodStr = "removeStaIface";
449         return validateAndCall(methodStr, false,
450                 () -> removeStaIfaceInternal(methodStr, ifaceName));
451     }
452 
453     /**
454      * See comments for {@link IWifiChip#requestChipDebugInfo()}
455      */
456     @Override
457     @Nullable
requestChipDebugInfo()458     public WifiChip.ChipDebugInfo requestChipDebugInfo() {
459         String methodStr = "requestChipDebugInfo";
460         return validateAndCall(methodStr, null,
461                 () -> requestChipDebugInfoInternal(methodStr));
462     }
463 
464     /**
465      * See comments for {@link IWifiChip#requestDriverDebugDump()}
466      */
467     @Override
468     @Nullable
requestDriverDebugDump()469     public byte[] requestDriverDebugDump() {
470         String methodStr = "requestDriverDebugDump";
471         return validateAndCall(methodStr, null,
472                 () -> requestDriverDebugDumpInternal(methodStr));
473     }
474 
475     /**
476      * See comments for {@link IWifiChip#requestFirmwareDebugDump()}
477      */
478     @Override
479     @Nullable
requestFirmwareDebugDump()480     public byte[] requestFirmwareDebugDump() {
481         String methodStr = "requestFirmwareDebugDump";
482         return validateAndCall(methodStr, null,
483                 () -> requestFirmwareDebugDumpInternal(methodStr));
484     }
485 
486     /**
487      * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)}
488      */
489     @Override
selectTxPowerScenario(SarInfo sarInfo)490     public boolean selectTxPowerScenario(SarInfo sarInfo) {
491         String methodStr = "selectTxPowerScenario";
492         return validateAndCall(methodStr, false,
493                 () -> selectTxPowerScenarioInternal(methodStr, sarInfo));
494     }
495 
496     /**
497      * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)}
498      */
499     @Override
setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions)500     public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
501         String methodStr = "setCoexUnsafeChannels";
502         return validateAndCall(methodStr, false,
503                 () -> setCoexUnsafeChannelsInternal(methodStr, unsafeChannels,
504                         restrictions));
505     }
506 
507     /**
508      * See comments for {@link IWifiChip#setCountryCode(byte[])}
509      */
510     @Override
setCountryCode(byte[] code)511     public boolean setCountryCode(byte[] code) {
512         String methodStr = "setCountryCode";
513         return validateAndCall(methodStr, false,
514                 () -> setCountryCodeInternal(methodStr, code));
515     }
516 
517     /**
518      * See comments for {@link IWifiChip#setLowLatencyMode(boolean)}
519      */
520     @Override
setLowLatencyMode(boolean enable)521     public boolean setLowLatencyMode(boolean enable) {
522         String methodStr = "setLowLatencyMode";
523         return validateAndCall(methodStr, false,
524                 () -> setLowLatencyModeInternal(methodStr, enable));
525     }
526 
527     /**
528      * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)}
529      */
530     @Override
setMultiStaPrimaryConnection(String ifaceName)531     public boolean setMultiStaPrimaryConnection(String ifaceName) {
532         String methodStr = "setMultiStaPrimaryConnection";
533         return validateAndCall(methodStr, false,
534                 () -> setMultiStaPrimaryConnectionInternal(methodStr, ifaceName));
535     }
536 
537     /**
538      * See comments for {@link IWifiChip#setMultiStaUseCase(int)}
539      */
540     @Override
setMultiStaUseCase(@ifiNative.MultiStaUseCase int useCase)541     public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) {
542         String methodStr = "setMultiStaUseCase";
543         return validateAndCall(methodStr, false,
544                 () -> setMultiStaUseCaseInternal(methodStr, useCase));
545     }
546 
547     /**
548      * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)}
549      */
550     @Override
startLoggingToDebugRingBuffer(String ringName, int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes)551     public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel,
552             int maxIntervalInSec, int minDataSizeInBytes) {
553         String methodStr = "startLoggingToDebugRingBuffer";
554         return validateAndCall(methodStr, false,
555                 () -> startLoggingToDebugRingBufferInternal(methodStr, ringName,
556                         verboseLevel, maxIntervalInSec, minDataSizeInBytes));
557     }
558 
559     /**
560      * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()}
561      */
562     @Override
stopLoggingToDebugRingBuffer()563     public boolean stopLoggingToDebugRingBuffer() {
564         String methodStr = "stopLoggingToDebugRingBuffer";
565         return validateAndCall(methodStr, false,
566                 () -> stopLoggingToDebugRingBufferInternal(methodStr));
567     }
568 
569     /**
570      * See comments for {@link IWifiChip#triggerSubsystemRestart()}
571      */
572     @Override
triggerSubsystemRestart()573     public boolean triggerSubsystemRestart() {
574         String methodStr = "triggerSubsystemRestart";
575         return validateAndCall(methodStr, false,
576                 () -> triggerSubsystemRestartInternal(methodStr));
577     }
578 
579     /**
580      * See comments for {@link IWifiChip#setMloMode(int)}.
581      */
582     @Override
setMloMode(@ifiManager.MloMode int mode)583     public @android.hardware.wifi.WifiStatusCode int setMloMode(@WifiManager.MloMode int mode) {
584         return android.hardware.wifi.WifiStatusCode.ERROR_NOT_SUPPORTED;
585     }
586 
587     /**
588      * See comments for {@link IWifiChip#enableStaChannelForPeerNetwork(boolean, boolean)}
589      */
590     @Override
enableStaChannelForPeerNetwork(boolean enableIndoorChannel, boolean enableDfsChannel)591     public boolean enableStaChannelForPeerNetwork(boolean enableIndoorChannel,
592             boolean enableDfsChannel) {
593         Log.d(TAG, "enableStaChannelForPeerNetwork() is not implemented in hidl.");
594         return false;
595     }
596 
597     /**
598      * See comments for {@link IWifiChip#setAfcChannelAllowance(WifiChip.AfcChannelAllowance)}
599      */
600     @Override
setAfcChannelAllowance(WifiChip.AfcChannelAllowance afcChannelAllowance)601     public boolean setAfcChannelAllowance(WifiChip.AfcChannelAllowance afcChannelAllowance) {
602         Log.d(TAG, "setAfcChannelAllowance() is not implemented in hidl.");
603         return false;
604     }
605 
606     // Internal Implementations
607 
configureChipInternal(String methodStr, int modeId)608     private boolean configureChipInternal(String methodStr, int modeId) {
609         try {
610             WifiStatus status = mWifiChip.configureChip(modeId);
611             return isOk(status, methodStr);
612         } catch (RemoteException e) {
613             handleRemoteException(e, methodStr);
614             return false;
615         }
616     }
617 
createApIfaceInternal(String methodStr)618     private WifiApIface createApIfaceInternal(String methodStr) {
619         Mutable<WifiApIface> ifaceResp = new Mutable<>();
620         try {
621             mWifiChip.createApIface((status, iface) -> {
622                 if (isOk(status, methodStr)) {
623                     ifaceResp.value = new WifiApIface(iface);
624                 }
625             });
626         } catch (RemoteException e) {
627             handleRemoteException(e, methodStr);
628         }
629         return ifaceResp.value;
630     }
631 
createBridgedApIfaceInternal(String methodStr)632     private WifiApIface createBridgedApIfaceInternal(String methodStr) {
633         Mutable<WifiApIface> ifaceResp = new Mutable<>();
634         try {
635             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
636             if (chip15 == null) return null;
637             chip15.createBridgedApIface((status, iface) -> {
638                 if (isOk(status, methodStr)) {
639                     ifaceResp.value = new WifiApIface(iface);
640                 }
641             });
642         } catch (RemoteException e) {
643             handleRemoteException(e, methodStr);
644         }
645         return ifaceResp.value;
646     }
647 
createNanIfaceInternal(String methodStr)648     private WifiNanIface createNanIfaceInternal(String methodStr) {
649         Mutable<WifiNanIface> ifaceResp = new Mutable<>();
650         try {
651             mWifiChip.createNanIface((status, iface) -> {
652                 if (isOk(status, methodStr)) {
653                     ifaceResp.value = new WifiNanIface(iface);
654                 }
655             });
656         } catch (RemoteException e) {
657             handleRemoteException(e, methodStr);
658         }
659         return ifaceResp.value;
660     }
661 
createP2pIfaceInternal(String methodStr)662     private WifiP2pIface createP2pIfaceInternal(String methodStr) {
663         Mutable<WifiP2pIface> ifaceResp = new Mutable<>();
664         try {
665             mWifiChip.createP2pIface((status, iface) -> {
666                 if (isOk(status, methodStr)) {
667                     ifaceResp.value = new WifiP2pIface(iface);
668                 }
669             });
670         } catch (RemoteException e) {
671             handleRemoteException(e, methodStr);
672         }
673         return ifaceResp.value;
674     }
675 
createRttControllerInternal(String methodStr)676     private WifiRttController createRttControllerInternal(String methodStr) {
677         Mutable<WifiRttController> controllerResp = new Mutable<>();
678         try {
679             android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
680             android.hardware.wifi.V1_4.IWifiChip chip14 = getWifiChipV1_4Mockable();
681             if (chip16 != null) {
682                 chip16.createRttController_1_6(null, (status, controller) -> {
683                     if (isOk(status, methodStr)) {
684                         controllerResp.value = new WifiRttController(controller);
685                     }
686                 });
687             } else if (chip14 != null) {
688                 chip14.createRttController_1_4(null, (status, controller) -> {
689                     if (isOk(status, methodStr)) {
690                         controllerResp.value = new WifiRttController(controller);
691                     }
692                 });
693             } else {
694                 mWifiChip.createRttController(null, (status, controller) -> {
695                     if (isOk(status, methodStr)) {
696                         controllerResp.value = new WifiRttController(controller);
697                     }
698                 });
699             }
700         } catch (RemoteException e) {
701             handleRemoteException(e, methodStr);
702         }
703         return controllerResp.value;
704     }
705 
createStaIfaceInternal(String methodStr)706     private WifiStaIface createStaIfaceInternal(String methodStr) {
707         Mutable<WifiStaIface> ifaceResp = new Mutable<>();
708         try {
709             mWifiChip.createStaIface((status, iface) -> {
710                 if (isOk(status, methodStr)) {
711                     ifaceResp.value = new WifiStaIface(iface, mContext, mSsidTranslator);
712                 }
713             });
714         } catch (RemoteException e) {
715             handleRemoteException(e, methodStr);
716         }
717         return ifaceResp.value;
718     }
719 
enableDebugErrorAlertsInternal(String methodStr, boolean enable)720     private boolean enableDebugErrorAlertsInternal(String methodStr, boolean enable) {
721         try {
722             WifiStatus status = mWifiChip.enableDebugErrorAlerts(enable);
723             return isOk(status, methodStr);
724         } catch (RemoteException e) {
725             handleRemoteException(e, methodStr);
726             return false;
727         }
728     }
729 
flushRingBufferToFileInternal(String methodStr)730     private boolean flushRingBufferToFileInternal(String methodStr) {
731         try {
732             android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
733             if (chip13 == null) return false;
734             WifiStatus status = chip13.flushRingBufferToFile();
735             return isOk(status, methodStr);
736         } catch (RemoteException e) {
737             handleRemoteException(e, methodStr);
738             return false;
739         }
740     }
741 
forceDumpToDebugRingBufferInternal(String methodStr, String ringName)742     private boolean forceDumpToDebugRingBufferInternal(String methodStr, String ringName) {
743         try {
744             WifiStatus status = mWifiChip.forceDumpToDebugRingBuffer(ringName);
745             return isOk(status, methodStr);
746         } catch (RemoteException e) {
747             handleRemoteException(e, methodStr);
748             return false;
749         }
750     }
751 
getApIfaceInternal(String methodStr, String ifaceName)752     private WifiApIface getApIfaceInternal(String methodStr, String ifaceName) {
753         Mutable<WifiApIface> ifaceResp = new Mutable<>();
754         try {
755             mWifiChip.getApIface(ifaceName, (status, iface) -> {
756                 if (isOk(status, methodStr)) {
757                     ifaceResp.value = new WifiApIface(iface);
758                 }
759             });
760         } catch (RemoteException e) {
761             handleRemoteException(e, methodStr);
762         }
763         return ifaceResp.value;
764     }
765 
getApIfaceNamesInternal(String methodStr)766     private List<String> getApIfaceNamesInternal(String methodStr) {
767         Mutable<List<String>> ifaceNameResp = new Mutable<>();
768         try {
769             mWifiChip.getApIfaceNames((status, ifaceNames) -> {
770                 if (isOk(status, methodStr)) {
771                     ifaceNameResp.value = ifaceNames;
772                 }
773             });
774         } catch (RemoteException e) {
775             handleRemoteException(e, methodStr);
776         }
777         return ifaceNameResp.value;
778     }
779 
getAvailableModesInternal(String methodStr)780     private List<WifiChip.ChipMode> getAvailableModesInternal(String methodStr) {
781         Mutable<List<WifiChip.ChipMode>> modeResp = new Mutable<>();
782         try {
783             android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
784             if (chip16 != null) {
785                 chip16.getAvailableModes_1_6((status, modes) -> {
786                     if (isOk(status, methodStr)) {
787                         modeResp.value = halToFrameworkChipModeListV1_6(modes);
788                     }
789                 });
790             } else {
791                 mWifiChip.getAvailableModes((status, modes) -> {
792                     if (isOk(status, methodStr)) {
793                         modeResp.value = halToFrameworkChipModeListV1_0(modes);
794                     }
795                 });
796             }
797         } catch (RemoteException e) {
798             handleRemoteException(e, methodStr);
799         }
800         return modeResp.value;
801     }
802 
getCapabilitiesBeforeIfacesExistInternal(String methodStr)803     private WifiChip.Response<Long> getCapabilitiesBeforeIfacesExistInternal(String methodStr) {
804         WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
805         try {
806             // HAL newer than v1.5 supports getting capabilities before creating an interface.
807             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
808             if (chip15 != null) {
809                 chip15.getCapabilities_1_5((status, caps) -> {
810                     if (isOk(status, methodStr)) {
811                         capsResp.setValue(wifiFeatureMaskFromChipCapabilities_1_5(caps));
812                         capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
813                     } else {
814                         capsResp.setStatusCode(
815                                 WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
816                     }
817                 });
818             }
819         } catch (RemoteException e) {
820             handleRemoteException(e, methodStr);
821             capsResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
822         }
823         return capsResp;
824     }
825 
getCapabilitiesAfterIfacesExistInternal(String methodStr)826     private WifiChip.Response<Long> getCapabilitiesAfterIfacesExistInternal(String methodStr) {
827         WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
828         try {
829             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
830             android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
831             if (chip15 != null) {
832                 chip15.getCapabilities_1_5((status, caps) -> {
833                     if (isOk(status, methodStr)) {
834                         capsResp.setValue(wifiFeatureMaskFromChipCapabilities_1_5(caps));
835                         capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
836                     } else {
837                         capsResp.setStatusCode(
838                                 WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
839                     }
840                 });
841             } else if (chip13 != null) {
842                 chip13.getCapabilities_1_3((status, caps) -> {
843                     if (isOk(status, methodStr)) {
844                         capsResp.setValue(wifiFeatureMaskFromChipCapabilities_1_3(caps));
845                         capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
846                     } else {
847                         capsResp.setStatusCode(
848                                 WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
849                     }
850                 });
851             } else {
852                 mWifiChip.getCapabilities((status, caps) -> {
853                     if (isOk(status, methodStr)) {
854                         capsResp.setValue((long) wifiFeatureMaskFromChipCapabilities(caps));
855                         capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
856                     } else {
857                         capsResp.setStatusCode(
858                                 WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
859                     }
860                 });
861             }
862         } catch (RemoteException e) {
863             handleRemoteException(e, methodStr);
864             capsResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
865         }
866         return capsResp;
867     }
868 
getDebugHostWakeReasonStatsInternal(String methodStr)869     private WlanWakeReasonAndCounts getDebugHostWakeReasonStatsInternal(String methodStr) {
870         Mutable<WlanWakeReasonAndCounts> debugResp = new Mutable<>();
871         try {
872             mWifiChip.getDebugHostWakeReasonStats((status, debugStats) -> {
873                 if (isOk(status, methodStr)) {
874                     debugResp.value = halToFrameworkWakeReasons(debugStats);
875                 }
876             });
877         } catch (RemoteException e) {
878             handleRemoteException(e, methodStr);
879         }
880         return debugResp.value;
881     }
882 
getDebugRingBuffersStatusInternal(String methodStr)883     private List<WifiNative.RingBufferStatus> getDebugRingBuffersStatusInternal(String methodStr) {
884         Mutable<List<WifiNative.RingBufferStatus>> ringBufResp = new Mutable<>();
885         try {
886             mWifiChip.getDebugRingBuffersStatus((status, ringBuffers) -> {
887                 if (isOk(status, methodStr)) {
888                     WifiNative.RingBufferStatus[] ringBufArray =
889                             makeRingBufferStatusArray(ringBuffers);
890                     ringBufResp.value = Arrays.asList(ringBufArray);
891                 }
892             });
893         } catch (RemoteException e) {
894             handleRemoteException(e, methodStr);
895         }
896         return ringBufResp.value;
897     }
898 
getIdInternal(String methodStr)899     private int getIdInternal(String methodStr) {
900         Mutable<Integer> idResp = new Mutable<>(-1);
901         try {
902             mWifiChip.getId((status, id) -> {
903                 if (isOk(status, methodStr)) {
904                     idResp.value = id;
905                 }
906             });
907         } catch (RemoteException e) {
908             handleRemoteException(e, methodStr);
909         }
910         return idResp.value;
911     }
912 
getModeInternal(String methodStr)913     private WifiChip.Response<Integer> getModeInternal(String methodStr) {
914         WifiChip.Response<Integer> modeResp = new WifiChip.Response<>(0);
915         try {
916             mWifiChip.getMode((status, mode) -> {
917                 if (isOk(status, methodStr)) {
918                     modeResp.setValue(mode);
919                     modeResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
920                 } else {
921                     modeResp.setStatusCode(
922                             WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
923                 }
924             });
925         } catch (RemoteException e) {
926             handleRemoteException(e, methodStr);
927             modeResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
928         }
929         return modeResp;
930     }
931 
getNanIfaceInternal(String methodStr, String ifaceName)932     private WifiNanIface getNanIfaceInternal(String methodStr, String ifaceName) {
933         Mutable<WifiNanIface> ifaceResp = new Mutable<>();
934         try {
935             mWifiChip.getNanIface(ifaceName, (status, iface) -> {
936                 if (isOk(status, methodStr)) {
937                     ifaceResp.value = new WifiNanIface(iface);
938                 }
939             });
940         } catch (RemoteException e) {
941             handleRemoteException(e, methodStr);
942         }
943         return ifaceResp.value;
944     }
945 
getNanIfaceNamesInternal(String methodStr)946     private List<String> getNanIfaceNamesInternal(String methodStr) {
947         Mutable<List<String>> ifaceNameResp = new Mutable<>();
948         try {
949             mWifiChip.getNanIfaceNames((status, ifaceNames) -> {
950                 if (isOk(status, methodStr)) {
951                     ifaceNameResp.value = ifaceNames;
952                 }
953             });
954         } catch (RemoteException e) {
955             handleRemoteException(e, methodStr);
956         }
957         return ifaceNameResp.value;
958     }
959 
getP2pIfaceInternal(String methodStr, String ifaceName)960     private WifiP2pIface getP2pIfaceInternal(String methodStr, String ifaceName) {
961         Mutable<WifiP2pIface> ifaceResp = new Mutable<>();
962         try {
963             mWifiChip.getP2pIface(ifaceName, (status, iface) -> {
964                 if (isOk(status, methodStr)) {
965                     ifaceResp.value = new WifiP2pIface(iface);
966                 }
967             });
968         } catch (RemoteException e) {
969             handleRemoteException(e, methodStr);
970         }
971         return ifaceResp.value;
972     }
973 
getP2pIfaceNamesInternal(String methodStr)974     private List<String> getP2pIfaceNamesInternal(String methodStr) {
975         Mutable<List<String>> ifaceNameResp = new Mutable<>();
976         try {
977             mWifiChip.getP2pIfaceNames((status, ifaceNames) -> {
978                 if (isOk(status, methodStr)) {
979                     ifaceNameResp.value = ifaceNames;
980                 }
981             });
982         } catch (RemoteException e) {
983             handleRemoteException(e, methodStr);
984         }
985         return ifaceNameResp.value;
986     }
987 
getStaIfaceInternal(String methodStr, String ifaceName)988     private WifiStaIface getStaIfaceInternal(String methodStr, String ifaceName) {
989         Mutable<WifiStaIface> ifaceResp = new Mutable<>();
990         try {
991             mWifiChip.getStaIface(ifaceName, (status, iface) -> {
992                 if (isOk(status, methodStr)) {
993                     ifaceResp.value = new WifiStaIface(iface, mContext, mSsidTranslator);
994                 }
995             });
996         } catch (RemoteException e) {
997             handleRemoteException(e, methodStr);
998         }
999         return ifaceResp.value;
1000     }
1001 
getStaIfaceNamesInternal(String methodStr)1002     private List<String> getStaIfaceNamesInternal(String methodStr) {
1003         Mutable<List<String>> ifaceNameResp = new Mutable<>();
1004         try {
1005             mWifiChip.getStaIfaceNames((status, ifaceNames) -> {
1006                 if (isOk(status, methodStr)) {
1007                     ifaceNameResp.value = ifaceNames;
1008                 }
1009             });
1010         } catch (RemoteException e) {
1011             handleRemoteException(e, methodStr);
1012         }
1013         return ifaceNameResp.value;
1014     }
1015 
getSupportedRadioCombinationsInternal( String methodStr)1016     private List<WifiChip.WifiRadioCombination> getSupportedRadioCombinationsInternal(
1017             String methodStr) {
1018         Mutable<List<WifiChip.WifiRadioCombination>> radioComboResp = new Mutable<>();
1019         try {
1020             android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
1021             if (chip16 == null) return null;
1022             chip16.getSupportedRadioCombinationsMatrix((status, matrix) -> {
1023                 if (matrix != null) {
1024                     radioComboResp.value =
1025                             halToFrameworkRadioCombinations(matrix.radioCombinations);
1026                 }
1027             });
1028         } catch (RemoteException e) {
1029             handleRemoteException(e, methodStr);
1030         }
1031         return radioComboResp.value;
1032     }
1033 
getUsableChannelsInternal(String methodStr, @WifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter)1034     private List<WifiAvailableChannel> getUsableChannelsInternal(String methodStr,
1035             @WifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode,
1036             @WifiAvailableChannel.Filter int filter) {
1037         Mutable<List<WifiAvailableChannel>> channelResp = new Mutable<>();
1038         try {
1039             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1040             android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
1041             if (chip15 == null && chip16 == null) return null;
1042             if (chip16 != null) {
1043                 chip16.getUsableChannels_1_6(
1044                         frameworkToHalWifiBand(band),
1045                         frameworkToHalIfaceMode(mode),
1046                         frameworkToHalUsableFilter_1_6(filter),
1047                         (status, channels) -> {
1048                             if (isOk(status, methodStr)) {
1049                                 channelResp.value = new ArrayList<>();
1050                                 for (android.hardware.wifi.V1_6.WifiUsableChannel ch : channels) {
1051                                     channelResp.value.add(new WifiAvailableChannel(ch.channel,
1052                                             halToFrameworkIfaceMode(ch.ifaceModeMask),
1053                                             halToFrameworkChannelWidth(ch.channelBandwidth)));
1054                                 }
1055                             }
1056                         });
1057             } else {
1058                 chip15.getUsableChannels(
1059                         frameworkToHalWifiBand(band),
1060                         frameworkToHalIfaceMode(mode),
1061                         frameworkToHalUsableFilter(filter),
1062                         (status, channels) -> {
1063                             if (isOk(status, methodStr)) {
1064                                 channelResp.value = new ArrayList<>();
1065                                 for (android.hardware.wifi.V1_5.WifiUsableChannel ch : channels) {
1066                                     channelResp.value.add(new WifiAvailableChannel(ch.channel,
1067                                             halToFrameworkIfaceMode(ch.ifaceModeMask),
1068                                             halToFrameworkChannelWidth(ch.channelBandwidth)));
1069                                 }
1070                             }
1071                         });
1072             }
1073         } catch (RemoteException e) {
1074             handleRemoteException(e, methodStr);
1075         }
1076         return channelResp.value;
1077     }
1078 
halToFrameworkChannelWidth(int channelBandwidth)1079     private @WifiAnnotations.ChannelWidth int halToFrameworkChannelWidth(int channelBandwidth) {
1080         switch (channelBandwidth) {
1081             case WIDTH_40:
1082                 return ScanResult.CHANNEL_WIDTH_40MHZ;
1083             case WIDTH_80:
1084                 return ScanResult.CHANNEL_WIDTH_80MHZ;
1085             case WIDTH_160:
1086                 return ScanResult.CHANNEL_WIDTH_160MHZ;
1087             case WIDTH_80P80:
1088                 return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
1089             case WIDTH_320:
1090                 return ScanResult.CHANNEL_WIDTH_320MHZ;
1091             default:
1092                 return ScanResult.CHANNEL_WIDTH_20MHZ;
1093         }
1094     }
1095 
registerCallbackInternal(String methodStr, WifiChip.Callback callback)1096     private boolean registerCallbackInternal(String methodStr, WifiChip.Callback callback) {
1097         if (mFrameworkCallback != null) {
1098             Log.e(TAG, "Framework callback is already registered");
1099             return false;
1100         } else if (callback == null) {
1101             Log.e(TAG, "Cannot register a null callback");
1102             return false;
1103         }
1104 
1105         try {
1106             android.hardware.wifi.V1_2.IWifiChip chip12 = getWifiChipV1_2Mockable();
1107             android.hardware.wifi.V1_4.IWifiChip chip14 = getWifiChipV1_4Mockable();
1108             mHalCallback10 = new ChipEventCallback();
1109             WifiStatus status;
1110             if (chip14 != null) {
1111                 mHalCallback12 = new ChipEventCallbackV12();
1112                 mHalCallback14 = new ChipEventCallbackV14();
1113                 status = chip14.registerEventCallback_1_4(mHalCallback14);
1114             } else if (chip12 != null) {
1115                 mHalCallback12 = new ChipEventCallbackV12();
1116                 status = chip12.registerEventCallback_1_2(mHalCallback12);
1117             } else {
1118                 status = mWifiChip.registerEventCallback(mHalCallback10);
1119             }
1120             if (!isOk(status, methodStr)) return false;
1121             mFrameworkCallback = callback;
1122             return true;
1123         } catch (RemoteException e) {
1124             handleRemoteException(e, methodStr);
1125             return false;
1126         }
1127     }
1128 
removeApIfaceInternal(String methodStr, String ifaceName)1129     private boolean removeApIfaceInternal(String methodStr, String ifaceName) {
1130         try {
1131             WifiStatus status = mWifiChip.removeApIface(ifaceName);
1132             return isOk(status, methodStr);
1133         } catch (RemoteException e) {
1134             handleRemoteException(e, methodStr);
1135             return false;
1136         }
1137     }
1138 
removeIfaceInstanceFromBridgedApIfaceInternal(String methodStr, String brIfaceName, String ifaceName)1139     private boolean removeIfaceInstanceFromBridgedApIfaceInternal(String methodStr,
1140             String brIfaceName, String ifaceName) {
1141         try {
1142             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1143             if (chip15 == null) return false;
1144             WifiStatus status =
1145                     chip15.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName);
1146             return isOk(status, methodStr);
1147         } catch (RemoteException e) {
1148             handleRemoteException(e, methodStr);
1149             return false;
1150         }
1151     }
1152 
removeNanIfaceInternal(String methodStr, String ifaceName)1153     private boolean removeNanIfaceInternal(String methodStr, String ifaceName) {
1154         try {
1155             WifiStatus status = mWifiChip.removeNanIface(ifaceName);
1156             return isOk(status, methodStr);
1157         } catch (RemoteException e) {
1158             handleRemoteException(e, methodStr);
1159             return false;
1160         }
1161     }
1162 
removeP2pIfaceInternal(String methodStr, String ifaceName)1163     private boolean removeP2pIfaceInternal(String methodStr, String ifaceName) {
1164         try {
1165             WifiStatus status = mWifiChip.removeP2pIface(ifaceName);
1166             return isOk(status, methodStr);
1167         } catch (RemoteException e) {
1168             handleRemoteException(e, methodStr);
1169             return false;
1170         }
1171     }
1172 
removeStaIfaceInternal(String methodStr, String ifaceName)1173     private boolean removeStaIfaceInternal(String methodStr, String ifaceName) {
1174         try {
1175             WifiStatus status = mWifiChip.removeStaIface(ifaceName);
1176             return isOk(status, methodStr);
1177         } catch (RemoteException e) {
1178             handleRemoteException(e, methodStr);
1179             return false;
1180         }
1181     }
1182 
requestChipDebugInfoInternal(String methodStr)1183     private WifiChip.ChipDebugInfo requestChipDebugInfoInternal(String methodStr) {
1184         Mutable<WifiChip.ChipDebugInfo> debugResp = new Mutable<>();
1185         try {
1186             mWifiChip.requestChipDebugInfo((status, halInfo) -> {
1187                 if (isOk(status, methodStr)) {
1188                     debugResp.value = new WifiChip.ChipDebugInfo(
1189                             halInfo.driverDescription, halInfo.firmwareDescription);
1190                 }
1191             });
1192         } catch (RemoteException e) {
1193             handleRemoteException(e, methodStr);
1194         }
1195         return debugResp.value;
1196     }
1197 
requestDriverDebugDumpInternal(String methodStr)1198     private byte[] requestDriverDebugDumpInternal(String methodStr) {
1199         Mutable<byte[]> debugResp = new Mutable<>();
1200         try {
1201             mWifiChip.requestDriverDebugDump((status, blob) -> {
1202                 if (isOk(status, methodStr)) {
1203                     debugResp.value = NativeUtil.byteArrayFromArrayList(blob);
1204                 }
1205             });
1206         } catch (RemoteException e) {
1207             handleRemoteException(e, methodStr);
1208         }
1209         return debugResp.value;
1210     }
1211 
requestFirmwareDebugDumpInternal(String methodStr)1212     private byte[] requestFirmwareDebugDumpInternal(String methodStr) {
1213         Mutable<byte[]> debugResp = new Mutable<>();
1214         try {
1215             mWifiChip.requestFirmwareDebugDump((status, blob) -> {
1216                 if (isOk(status, methodStr)) {
1217                     debugResp.value = NativeUtil.byteArrayFromArrayList(blob);
1218                 }
1219             });
1220         } catch (RemoteException e) {
1221             handleRemoteException(e, methodStr);
1222         }
1223         return debugResp.value;
1224     }
1225 
selectTxPowerScenarioInternal(String methodStr, SarInfo sarInfo)1226     private boolean selectTxPowerScenarioInternal(String methodStr, SarInfo sarInfo) {
1227         if (getWifiChipV1_2Mockable() != null) {
1228             return selectTxPowerScenarioInternal_1_2(methodStr, sarInfo);
1229         } else if (getWifiChipV1_1Mockable() != null) {
1230             return selectTxPowerScenarioInternal_1_1(methodStr, sarInfo);
1231         }
1232         return false;
1233     }
1234 
selectTxPowerScenarioInternal_1_1(String methodStr, SarInfo sarInfo)1235     private boolean selectTxPowerScenarioInternal_1_1(String methodStr, SarInfo sarInfo) {
1236         methodStr += "_1_1";
1237         try {
1238             WifiStatus status;
1239             android.hardware.wifi.V1_1.IWifiChip chip11 = getWifiChipV1_1Mockable();
1240 
1241             if (sarPowerBackoffRequired_1_1(sarInfo)) {
1242                 // Power backoff is needed, so calculate the required scenario
1243                 // and attempt to set it.
1244                 int halScenario = frameworkToHalTxPowerScenario_1_1(sarInfo);
1245                 if (sarInfo.setSarScenarioNeeded(halScenario)) {
1246                     Log.d(TAG, "Attempting to set SAR scenario to " + halScenario);
1247                     status = chip11.selectTxPowerScenario(halScenario);
1248                     return isOk(status, methodStr);
1249                 }
1250                 // Reaching here means setting SAR scenario would be redundant,
1251                 // do nothing and return with success.
1252                 return true;
1253             }
1254 
1255             // We don't need to perform power backoff, so attempt to reset the SAR scenario.
1256             if (sarInfo.resetSarScenarioNeeded()) {
1257                 status = chip11.resetTxPowerScenario();
1258                 Log.d(TAG, "Attempting to reset the SAR scenario");
1259                 return isOk(status, methodStr);
1260             }
1261 
1262             // Resetting SAR scenario would be redundant; do nothing and return with success.
1263             return true;
1264         } catch (RemoteException e) {
1265             handleRemoteException(e, methodStr);
1266             return false;
1267         } catch (IllegalArgumentException e) {
1268             Log.e(TAG, "IllegalArgumentException in " + methodStr);
1269             return false;
1270         }
1271     }
1272 
selectTxPowerScenarioInternal_1_2(String methodStr, SarInfo sarInfo)1273     private boolean selectTxPowerScenarioInternal_1_2(String methodStr, SarInfo sarInfo) {
1274         methodStr += "_1_2";
1275         try {
1276             WifiStatus status;
1277             android.hardware.wifi.V1_2.IWifiChip chip12 = getWifiChipV1_2Mockable();
1278 
1279             if (sarPowerBackoffRequired_1_2(sarInfo)) {
1280                 // Power backoff is needed, so calculate the required scenario
1281                 // and attempt to set it.
1282                 int halScenario = frameworkToHalTxPowerScenario_1_2(sarInfo);
1283                 if (sarInfo.setSarScenarioNeeded(halScenario)) {
1284                     Log.d(TAG, "Attempting to set SAR scenario to " + halScenario);
1285                     status = chip12.selectTxPowerScenario_1_2(halScenario);
1286                     return isOk(status, methodStr);
1287                 }
1288                 // Reaching here means setting SAR scenario would be redundant,
1289                 // do nothing and return with success.
1290                 return true;
1291             }
1292 
1293             // We don't need to perform power backoff, so attempt to reset the SAR scenario.
1294             if (sarInfo.resetSarScenarioNeeded()) {
1295                 status = chip12.resetTxPowerScenario();
1296                 Log.d(TAG, "Attempting to reset the SAR scenario");
1297                 return isOk(status, methodStr);
1298             }
1299 
1300             // Resetting SAR scenario would be redundant; do nothing and return with success.
1301             return true;
1302         } catch (RemoteException e) {
1303             handleRemoteException(e, methodStr);
1304             return false;
1305         } catch (IllegalArgumentException e) {
1306             Log.e(TAG, "IllegalArgumentException in " + methodStr);
1307             return false;
1308         }
1309     }
1310 
setCoexUnsafeChannelsInternal(String methodStr, List<CoexUnsafeChannel> unsafeChannels, int restrictions)1311     private boolean setCoexUnsafeChannelsInternal(String methodStr,
1312             List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
1313         try {
1314             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1315             if (chip15 == null) return false;
1316             WifiStatus status = chip15.setCoexUnsafeChannels(
1317                     frameworkCoexUnsafeChannelsToHidl(unsafeChannels),
1318                     frameworkCoexRestrictionsToHidl(restrictions));
1319             return isOk(status, methodStr);
1320         } catch (RemoteException e) {
1321             handleRemoteException(e, methodStr);
1322             return false;
1323         }
1324     }
1325 
setCountryCodeInternal(String methodStr, byte[] code)1326     private boolean setCountryCodeInternal(String methodStr, byte[] code) {
1327         try {
1328             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1329             if (chip15 == null) return false;
1330             WifiStatus status = chip15.setCountryCode(code);
1331             return isOk(status, methodStr);
1332         } catch (RemoteException e) {
1333             handleRemoteException(e, methodStr);
1334             return false;
1335         }
1336     }
1337 
setLowLatencyModeInternal(String methodStr, boolean enable)1338     private boolean setLowLatencyModeInternal(String methodStr, boolean enable) {
1339         try {
1340             android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
1341             if (chip13 == null) return false;
1342             int mode;
1343             if (enable) {
1344                 mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.LOW;
1345             } else {
1346                 mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.NORMAL;
1347             }
1348             WifiStatus status = chip13.setLatencyMode(mode);
1349             return isOk(status, methodStr);
1350         } catch (RemoteException e) {
1351             handleRemoteException(e, methodStr);
1352             return false;
1353         }
1354     }
1355 
setMultiStaPrimaryConnectionInternal(String methodStr, String ifaceName)1356     private boolean setMultiStaPrimaryConnectionInternal(String methodStr, String ifaceName) {
1357         try {
1358             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1359             if (chip15 == null) return false;
1360             WifiStatus status = chip15.setMultiStaPrimaryConnection(ifaceName);
1361             return isOk(status, methodStr);
1362         } catch (RemoteException e) {
1363             handleRemoteException(e, methodStr);
1364             return false;
1365         }
1366     }
1367 
setMultiStaUseCaseInternal(String methodStr, @WifiNative.MultiStaUseCase int useCase)1368     private boolean setMultiStaUseCaseInternal(String methodStr,
1369             @WifiNative.MultiStaUseCase int useCase) {
1370         try {
1371             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1372             if (chip15 == null) return false;
1373             WifiStatus status = chip15.setMultiStaUseCase(frameworkMultiStaUseCaseToHidl(useCase));
1374             return isOk(status, methodStr);
1375         } catch (RemoteException e) {
1376             handleRemoteException(e, methodStr);
1377         } catch (IllegalArgumentException e) {
1378             Log.e(TAG, "Invalid argument " + useCase + " in " + methodStr);
1379         }
1380         return false;
1381     }
1382 
startLoggingToDebugRingBufferInternal(String methodStr, String ringName, int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes)1383     private boolean startLoggingToDebugRingBufferInternal(String methodStr, String ringName,
1384             int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes) {
1385         try {
1386             WifiStatus status = mWifiChip.startLoggingToDebugRingBuffer(ringName, verboseLevel,
1387                     maxIntervalInSec, minDataSizeInBytes);
1388             return isOk(status, methodStr);
1389         } catch (RemoteException e) {
1390             handleRemoteException(e, methodStr);
1391             return false;
1392         }
1393     }
1394 
stopLoggingToDebugRingBufferInternal(String methodStr)1395     private boolean stopLoggingToDebugRingBufferInternal(String methodStr) {
1396         try {
1397             WifiStatus status = mWifiChip.stopLoggingToDebugRingBuffer();
1398             return isOk(status, methodStr);
1399         } catch (RemoteException e) {
1400             handleRemoteException(e, methodStr);
1401             return false;
1402         }
1403     }
1404 
triggerSubsystemRestartInternal(String methodStr)1405     private boolean triggerSubsystemRestartInternal(String methodStr) {
1406         try {
1407             android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
1408             if (chip15 == null) return false;
1409             WifiStatus status = chip15.triggerSubsystemRestart();
1410             return isOk(status, methodStr);
1411         } catch (RemoteException e) {
1412             handleRemoteException(e, methodStr);
1413             return false;
1414         }
1415     }
1416 
1417     /**
1418      * Callback for events on the chip.
1419      */
1420     private class ChipEventCallback extends IWifiChipEventCallback.Stub {
1421         @Override
onChipReconfigured(int modeId)1422         public void onChipReconfigured(int modeId) {
1423             if (mFrameworkCallback == null) return;
1424             mFrameworkCallback.onChipReconfigured(modeId);
1425         }
1426 
1427         @Override
onChipReconfigureFailure(WifiStatus status)1428         public void onChipReconfigureFailure(WifiStatus status) {
1429             if (mFrameworkCallback == null) return;
1430             mFrameworkCallback.onChipReconfigureFailure(
1431                     WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
1432         }
1433 
1434         @Override
onIfaceAdded(int type, String name)1435         public void onIfaceAdded(int type, String name) {
1436             if (mFrameworkCallback == null) return;
1437             mFrameworkCallback.onIfaceAdded(halToFrameworkIfaceType(type), name);
1438         }
1439 
1440         @Override
onIfaceRemoved(int type, String name)1441         public void onIfaceRemoved(int type, String name) {
1442             if (mFrameworkCallback == null) return;
1443             mFrameworkCallback.onIfaceRemoved(halToFrameworkIfaceType(type), name);
1444         }
1445 
1446         @Override
onDebugRingBufferDataAvailable( WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)1447         public void onDebugRingBufferDataAvailable(
1448                 WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
1449             if (mFrameworkCallback == null) return;
1450             mFrameworkCallback.onDebugRingBufferDataAvailable(
1451                     halToFrameworkRingBufferStatus(status),
1452                     NativeUtil.byteArrayFromArrayList(data));
1453         }
1454 
1455         @Override
onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)1456         public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
1457             if (mFrameworkCallback == null) return;
1458             mFrameworkCallback.onDebugErrorAlert(errorCode,
1459                     NativeUtil.byteArrayFromArrayList(debugData));
1460         }
1461     }
1462 
1463     /**
1464      * Callback for events on the 1.2 chip.
1465      */
1466     private class ChipEventCallbackV12 extends
1467             android.hardware.wifi.V1_2.IWifiChipEventCallback.Stub {
1468         @Override
onChipReconfigured(int modeId)1469         public void onChipReconfigured(int modeId) throws RemoteException {
1470             mHalCallback10.onChipReconfigured(modeId);
1471         }
1472 
1473         @Override
onChipReconfigureFailure(WifiStatus status)1474         public void onChipReconfigureFailure(WifiStatus status) throws RemoteException {
1475             mHalCallback10.onChipReconfigureFailure(status);
1476         }
1477 
onIfaceAdded(int type, String name)1478         public void onIfaceAdded(int type, String name) throws RemoteException {
1479             mHalCallback10.onIfaceAdded(type, name);
1480         }
1481 
1482         @Override
onIfaceRemoved(int type, String name)1483         public void onIfaceRemoved(int type, String name) throws RemoteException {
1484             mHalCallback10.onIfaceRemoved(type, name);
1485         }
1486 
1487         @Override
onDebugRingBufferDataAvailable( WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)1488         public void onDebugRingBufferDataAvailable(
1489                 WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)
1490                 throws RemoteException {
1491             mHalCallback10.onDebugRingBufferDataAvailable(status, data);
1492         }
1493 
1494         @Override
onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)1495         public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)
1496                 throws RemoteException {
1497             mHalCallback10.onDebugErrorAlert(errorCode, debugData);
1498         }
1499 
1500         @Override
onRadioModeChange(ArrayList<RadioModeInfo> radioModeInfoList)1501         public void onRadioModeChange(ArrayList<RadioModeInfo> radioModeInfoList) {
1502             if (mFrameworkCallback == null) return;
1503             List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>();
1504             for (RadioModeInfo radioInfo : radioModeInfoList) {
1505                 List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>();
1506                 for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) {
1507                     frameworkIfaceInfos.add(
1508                             new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel));
1509                 }
1510                 frameworkRadioModeInfos.add(
1511                         new WifiChip.RadioModeInfo(
1512                                 radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos));
1513             }
1514             mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos);
1515         }
1516     }
1517 
1518     /**
1519      * Callback for events on the 1.4 chip.
1520      */
1521     private class ChipEventCallbackV14 extends
1522             android.hardware.wifi.V1_4.IWifiChipEventCallback.Stub {
1523         @Override
onChipReconfigured(int modeId)1524         public void onChipReconfigured(int modeId) throws RemoteException {
1525             mHalCallback10.onChipReconfigured(modeId);
1526         }
1527 
1528         @Override
onChipReconfigureFailure(WifiStatus status)1529         public void onChipReconfigureFailure(WifiStatus status) throws RemoteException {
1530             mHalCallback10.onChipReconfigureFailure(status);
1531         }
1532 
onIfaceAdded(int type, String name)1533         public void onIfaceAdded(int type, String name) throws RemoteException {
1534             mHalCallback10.onIfaceAdded(type, name);
1535         }
1536 
1537         @Override
onIfaceRemoved(int type, String name)1538         public void onIfaceRemoved(int type, String name) throws RemoteException {
1539             mHalCallback10.onIfaceRemoved(type, name);
1540         }
1541 
1542         @Override
onDebugRingBufferDataAvailable( WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)1543         public void onDebugRingBufferDataAvailable(
1544                 WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)
1545                 throws RemoteException {
1546             mHalCallback10.onDebugRingBufferDataAvailable(status, data);
1547         }
1548 
1549         @Override
onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)1550         public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)
1551                 throws RemoteException {
1552             mHalCallback10.onDebugErrorAlert(errorCode, debugData);
1553         }
1554 
1555         @Override
onRadioModeChange( ArrayList<android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo> radioModeInfoList)1556         public void onRadioModeChange(
1557                 ArrayList<android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo>
1558                         radioModeInfoList) throws RemoteException {
1559             mHalCallback12.onRadioModeChange(radioModeInfoList);
1560         }
1561 
1562         @Override
onRadioModeChange_1_4(ArrayList<RadioModeInfo> radioModeInfoList)1563         public void onRadioModeChange_1_4(ArrayList<RadioModeInfo> radioModeInfoList) {
1564             if (mFrameworkCallback == null) return;
1565             List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>();
1566             for (RadioModeInfo radioInfo : radioModeInfoList) {
1567                 List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>();
1568                 for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) {
1569                     frameworkIfaceInfos.add(
1570                             new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel));
1571                 }
1572                 frameworkRadioModeInfos.add(
1573                         new WifiChip.RadioModeInfo(
1574                                 radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos));
1575             }
1576             mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos);
1577         }
1578     }
1579 
1580 
1581     // Helper Functions
1582 
isBridgedSoftApSupportedMockable()1583     protected boolean isBridgedSoftApSupportedMockable() {
1584         return mIsBridgedSoftApSupported;
1585     }
1586 
isStaWithBridgedSoftApConcurrencySupportedMockable()1587     protected boolean isStaWithBridgedSoftApConcurrencySupportedMockable() {
1588         return mIsStaWithBridgedSoftApConcurrencySupported;
1589     }
1590 
1591     private static final SparseIntArray IFACE_TYPE_TO_CONCURRENCY_TYPE_MAP = new SparseIntArray() {{
1592                 put(IfaceType.STA, android.hardware.wifi.V1_6.IfaceConcurrencyType.STA);
1593                 put(IfaceType.AP, android.hardware.wifi.V1_6.IfaceConcurrencyType.AP);
1594                 put(IfaceType.P2P, android.hardware.wifi.V1_6.IfaceConcurrencyType.P2P);
1595                 put(IfaceType.NAN, android.hardware.wifi.V1_6.IfaceConcurrencyType.NAN);
1596             }};
1597 
upgradeV1_0ChipModesToV1_6( List<android.hardware.wifi.V1_0.IWifiChip.ChipMode> oldChipModes)1598     private List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> upgradeV1_0ChipModesToV1_6(
1599             List<android.hardware.wifi.V1_0.IWifiChip.ChipMode> oldChipModes) {
1600         ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> newChipModes = new ArrayList<>();
1601         for (android.hardware.wifi.V1_0.IWifiChip.ChipMode oldChipMode : oldChipModes) {
1602             android.hardware.wifi.V1_6.IWifiChip.ChipMode newChipMode =
1603                     new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
1604             newChipMode.id = oldChipMode.id;
1605             newChipMode.availableCombinations = new ArrayList<>();
1606             for (android.hardware.wifi.V1_0.IWifiChip.ChipIfaceCombination oldCombo
1607                     : oldChipMode.availableCombinations) {
1608                 android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination
1609                         newCombo = new android.hardware.wifi.V1_6.IWifiChip
1610                                 .ChipConcurrencyCombination();
1611                 newCombo.limits = new ArrayList<>();
1612                 // Define a duplicate combination list with AP converted to AP_BRIDGED
1613                 android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination
1614                         newComboWithBridgedAp =
1615                         new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
1616                 newComboWithBridgedAp.limits = new ArrayList<>();
1617                 android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit
1618                         bridgedApLimit = new android.hardware.wifi.V1_6.IWifiChip
1619                                 .ChipConcurrencyCombinationLimit();
1620                 bridgedApLimit.maxIfaces = 1;
1621                 bridgedApLimit.types = new ArrayList<>();
1622                 bridgedApLimit.types.add(IfaceConcurrencyType.AP_BRIDGED);
1623                 newComboWithBridgedAp.limits.add(bridgedApLimit);
1624 
1625                 boolean apInCombo = false;
1626                 // Populate both the combo with AP_BRIDGED and the combo without AP_BRIDGED
1627                 for (android.hardware.wifi.V1_0.IWifiChip.ChipIfaceCombinationLimit oldLimit
1628                         : oldCombo.limits) {
1629                     android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit newLimit =
1630                             new android.hardware.wifi.V1_6
1631                                     .IWifiChip.ChipConcurrencyCombinationLimit();
1632                     newLimit.types = new ArrayList<>();
1633                     newLimit.maxIfaces = oldLimit.maxIfaces;
1634                     for (int oldType : oldLimit.types) {
1635                         newLimit.types.add(IFACE_TYPE_TO_CONCURRENCY_TYPE_MAP.get(oldType));
1636                     }
1637                     newCombo.limits.add(newLimit);
1638 
1639                     android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit
1640                             newLimitForBridgedApCombo = new android.hardware.wifi.V1_6.IWifiChip
1641                                     .ChipConcurrencyCombinationLimit();
1642                     newLimitForBridgedApCombo.types = new ArrayList<>(newLimit.types);
1643                     newLimitForBridgedApCombo.maxIfaces = newLimit.maxIfaces;
1644                     if (newLimitForBridgedApCombo.types.contains(IfaceConcurrencyType.AP)) {
1645                         // Skip the limit if it contains AP, since this corresponds to the
1646                         // AP_BRIDGED in the duplicate AP_BRIDGED combo.
1647                         apInCombo = true;
1648                     } else if (!isStaWithBridgedSoftApConcurrencySupportedMockable()
1649                             && newLimitForBridgedApCombo.types.contains(IfaceConcurrencyType.STA)) {
1650                         // Don't include STA in the AP_BRIDGED combo if STA + AP_BRIDGED is not
1651                         // supported.
1652                         newLimitForBridgedApCombo.types.remove((Integer) IfaceConcurrencyType.STA);
1653                         if (!newLimitForBridgedApCombo.types.isEmpty()) {
1654                             newComboWithBridgedAp.limits.add(newLimitForBridgedApCombo);
1655                         }
1656                     } else {
1657                         newComboWithBridgedAp.limits.add(newLimitForBridgedApCombo);
1658                     }
1659                 }
1660                 newChipMode.availableCombinations.add(newCombo);
1661                 if (isBridgedSoftApSupportedMockable() && apInCombo) {
1662                     newChipMode.availableCombinations.add(newComboWithBridgedAp);
1663                 }
1664             }
1665             newChipModes.add(newChipMode);
1666         }
1667         return newChipModes;
1668     }
1669 
halToFrameworkChipModeListV1_0( List<android.hardware.wifi.V1_0.IWifiChip.ChipMode> halModes)1670     private List<WifiChip.ChipMode> halToFrameworkChipModeListV1_0(
1671             List<android.hardware.wifi.V1_0.IWifiChip.ChipMode> halModes) {
1672         List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> modes16 =
1673                 upgradeV1_0ChipModesToV1_6(halModes);
1674         return halToFrameworkChipModeListV1_6(modes16);
1675     }
1676 
halToFrameworkChipModeListV1_6( List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> halModes)1677     private static List<WifiChip.ChipMode> halToFrameworkChipModeListV1_6(
1678             List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> halModes) {
1679         List<WifiChip.ChipMode> frameworkModes = new ArrayList<>();
1680         for (android.hardware.wifi.V1_6.IWifiChip.ChipMode halMode : halModes) {
1681             frameworkModes.add(halToFrameworkChipModeV1_6(halMode));
1682         }
1683         return frameworkModes;
1684     }
1685 
halToFrameworkChipModeV1_6( android.hardware.wifi.V1_6.IWifiChip.ChipMode halMode)1686     private static WifiChip.ChipMode halToFrameworkChipModeV1_6(
1687             android.hardware.wifi.V1_6.IWifiChip.ChipMode halMode) {
1688         List<WifiChip.ChipConcurrencyCombination> frameworkCombos = new ArrayList<>();
1689         for (android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination halCombo :
1690                 halMode.availableCombinations) {
1691             frameworkCombos.add(halToFrameworkChipConcurrencyCombinationV1_6(halCombo));
1692         }
1693         return new WifiChip.ChipMode(halMode.id, frameworkCombos);
1694     }
1695 
halToFrameworkChipConcurrencyCombinationV1_6( android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination halCombo)1696     private static WifiChip.ChipConcurrencyCombination halToFrameworkChipConcurrencyCombinationV1_6(
1697             android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination halCombo) {
1698         List<WifiChip.ChipConcurrencyCombinationLimit> frameworkLimits = new ArrayList<>();
1699         for (android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit halLimit :
1700                 halCombo.limits) {
1701             frameworkLimits.add(halToFrameworkChipConcurrencyCombinationLimitV1_6(halLimit));
1702         }
1703         return new WifiChip.ChipConcurrencyCombination(frameworkLimits);
1704     }
1705 
1706     private static WifiChip.ChipConcurrencyCombinationLimit
halToFrameworkChipConcurrencyCombinationLimitV1_6( android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit halLimit)1707             halToFrameworkChipConcurrencyCombinationLimitV1_6(
1708             android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit halLimit) {
1709         List<Integer> frameworkTypes = new ArrayList<>();
1710         for (int halType : halLimit.types) {
1711             frameworkTypes.add(halToFrameworkIfaceConcurrencyType(halType));
1712         }
1713         return new WifiChip.ChipConcurrencyCombinationLimit(halLimit.maxIfaces, frameworkTypes);
1714     }
1715 
halToFrameworkIfaceConcurrencyType(int type)1716     private static @WifiChip.IfaceConcurrencyType int halToFrameworkIfaceConcurrencyType(int type) {
1717         switch (type) {
1718             case IfaceConcurrencyType.STA:
1719                 return WifiChip.IFACE_CONCURRENCY_TYPE_STA;
1720             case IfaceConcurrencyType.AP:
1721                 return WifiChip.IFACE_CONCURRENCY_TYPE_AP;
1722             case IfaceConcurrencyType.AP_BRIDGED:
1723                 return WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED;
1724             case IfaceConcurrencyType.P2P:
1725                 return WifiChip.IFACE_CONCURRENCY_TYPE_P2P;
1726             case IfaceConcurrencyType.NAN:
1727                 return WifiChip.IFACE_CONCURRENCY_TYPE_NAN;
1728             default:
1729                 Log.e(TAG, "Invalid IfaceConcurrencyType received: " + type);
1730                 return -1;
1731         }
1732     }
1733 
halToFrameworkIfaceType(int type)1734     private static @WifiChip.IfaceType int halToFrameworkIfaceType(int type) {
1735         switch (type) {
1736             case IfaceType.STA:
1737                 return WifiChip.IFACE_TYPE_STA;
1738             case IfaceType.AP:
1739                 return WifiChip.IFACE_TYPE_AP;
1740             case IfaceType.P2P:
1741                 return WifiChip.IFACE_TYPE_P2P;
1742             case IfaceType.NAN:
1743                 return WifiChip.IFACE_TYPE_NAN;
1744             default:
1745                 Log.e(TAG, "Invalid IfaceType received: " + type);
1746                 return -1;
1747         }
1748     }
1749 
1750     private static final long[][] sChipFeatureCapabilityTranslation = {
1751             {WifiManager.WIFI_FEATURE_TX_POWER_LIMIT,
1752                     android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT
1753             },
1754             {WifiManager.WIFI_FEATURE_D2D_RTT,
1755                     android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
1756             },
1757             {WifiManager.WIFI_FEATURE_D2AP_RTT,
1758                     android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
1759             }
1760     };
1761 
1762     /**
1763      * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for
1764      * additional capabilities introduced in V1.5
1765      */
1766     private static final long[][] sChipFeatureCapabilityTranslation15 = {
1767             {WifiManager.WIFI_FEATURE_INFRA_60G,
1768                     android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG
1769             }
1770     };
1771 
1772     /**
1773      * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for
1774      * additional capabilities introduced in V1.3
1775      */
1776     private static final long[][] sChipFeatureCapabilityTranslation13 = {
1777             {WifiManager.WIFI_FEATURE_LOW_LATENCY,
1778                     android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
1779             },
1780             {WifiManager.WIFI_FEATURE_P2P_RAND_MAC,
1781                     android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.P2P_RAND_MAC
1782             }
1783 
1784     };
1785 
1786     /**
1787      * Feature bit mask translation for Chip V1.1
1788      *
1789      * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
1790      * @return bitmask defined by WifiManager.WIFI_FEATURE_*
1791      */
1792     @VisibleForTesting
wifiFeatureMaskFromChipCapabilities(int capabilities)1793     int wifiFeatureMaskFromChipCapabilities(int capabilities) {
1794         int features = 0;
1795         for (int i = 0; i < sChipFeatureCapabilityTranslation.length; i++) {
1796             if ((capabilities & sChipFeatureCapabilityTranslation[i][1]) != 0) {
1797                 features |= sChipFeatureCapabilityTranslation[i][0];
1798             }
1799         }
1800         return features;
1801     }
1802 
1803     /**
1804      * Feature bit mask translation for Chip V1.5
1805      *
1806      * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
1807      * @return bitmask defined by WifiManager.WIFI_FEATURE_*
1808      */
1809     @VisibleForTesting
wifiFeatureMaskFromChipCapabilities_1_5(int capabilities)1810     long wifiFeatureMaskFromChipCapabilities_1_5(int capabilities) {
1811         // First collect features from previous versions
1812         long features = wifiFeatureMaskFromChipCapabilities_1_3(capabilities);
1813 
1814         // Next collect features for V1_5 version
1815         for (int i = 0; i < sChipFeatureCapabilityTranslation15.length; i++) {
1816             if ((capabilities & sChipFeatureCapabilityTranslation15[i][1]) != 0) {
1817                 features |= sChipFeatureCapabilityTranslation15[i][0];
1818             }
1819         }
1820         return features;
1821     }
1822 
1823     /**
1824      * Feature bit mask translation for Chip V1.3
1825      *
1826      * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
1827      * @return bitmask defined by WifiManager.WIFI_FEATURE_*
1828      */
1829     @VisibleForTesting
wifiFeatureMaskFromChipCapabilities_1_3(int capabilities)1830     long wifiFeatureMaskFromChipCapabilities_1_3(int capabilities) {
1831         // First collect features from previous versions
1832         long features = wifiFeatureMaskFromChipCapabilities(capabilities);
1833 
1834         // Next collect features for V1_3 version
1835         for (int i = 0; i < sChipFeatureCapabilityTranslation13.length; i++) {
1836             if ((capabilities & sChipFeatureCapabilityTranslation13[i][1]) != 0) {
1837                 features |= sChipFeatureCapabilityTranslation13[i][0];
1838             }
1839         }
1840         return features;
1841     }
1842 
1843     /**
1844      * Translates from Hal version of wake reason stats to the framework version of same
1845      *
1846      * @param h - Hal version of wake reason stats
1847      * @return framework version of same
1848      */
halToFrameworkWakeReasons( WifiDebugHostWakeReasonStats h)1849     private static WlanWakeReasonAndCounts halToFrameworkWakeReasons(
1850             WifiDebugHostWakeReasonStats h) {
1851         if (h == null) return null;
1852         WlanWakeReasonAndCounts ans = new WlanWakeReasonAndCounts();
1853         ans.totalCmdEventWake = h.totalCmdEventWakeCnt;
1854         ans.totalDriverFwLocalWake = h.totalDriverFwLocalWakeCnt;
1855         ans.totalRxDataWake = h.totalRxPacketWakeCnt;
1856         ans.rxUnicast = h.rxPktWakeDetails.rxUnicastCnt;
1857         ans.rxMulticast = h.rxPktWakeDetails.rxMulticastCnt;
1858         ans.rxBroadcast = h.rxPktWakeDetails.rxBroadcastCnt;
1859         ans.icmp = h.rxIcmpPkWakeDetails.icmpPkt;
1860         ans.icmp6 = h.rxIcmpPkWakeDetails.icmp6Pkt;
1861         ans.icmp6Ra = h.rxIcmpPkWakeDetails.icmp6Ra;
1862         ans.icmp6Na = h.rxIcmpPkWakeDetails.icmp6Na;
1863         ans.icmp6Ns = h.rxIcmpPkWakeDetails.icmp6Ns;
1864         ans.ipv4RxMulticast = h.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt;
1865         ans.ipv6Multicast = h.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt;
1866         ans.otherRxMulticast = h.rxMulticastPkWakeDetails.otherRxMulticastAddrCnt;
1867         ans.cmdEventWakeCntArray = intsFromArrayList(h.cmdEventWakeCntPerType);
1868         ans.driverFWLocalWakeCntArray = intsFromArrayList(h.driverFwLocalWakeCntPerType);
1869         return ans;
1870     }
1871 
1872     /**
1873      * Creates array of RingBufferStatus from the Hal version
1874      */
makeRingBufferStatusArray( ArrayList<WifiDebugRingBufferStatus> ringBuffers)1875     private static WifiNative.RingBufferStatus[] makeRingBufferStatusArray(
1876             ArrayList<WifiDebugRingBufferStatus> ringBuffers) {
1877         WifiNative.RingBufferStatus[] ans = new WifiNative.RingBufferStatus[ringBuffers.size()];
1878         int i = 0;
1879         for (WifiDebugRingBufferStatus b : ringBuffers) {
1880             ans[i++] = halToFrameworkRingBufferStatus(b);
1881         }
1882         return ans;
1883     }
1884 
1885     /**
1886      * Creates RingBufferStatus from the Hal version
1887      */
halToFrameworkRingBufferStatus( WifiDebugRingBufferStatus h)1888     private static WifiNative.RingBufferStatus halToFrameworkRingBufferStatus(
1889             WifiDebugRingBufferStatus h) {
1890         WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus();
1891         ans.name = h.ringName;
1892         ans.flag = frameworkRingBufferFlagsFromHal(h.flags);
1893         ans.ringBufferId = h.ringId;
1894         ans.ringBufferByteSize = h.sizeInBytes;
1895         ans.verboseLevel = h.verboseLevel;
1896         // Remaining fields are unavailable
1897         //  writtenBytes;
1898         //  readBytes;
1899         //  writtenRecords;
1900         return ans;
1901     }
1902 
1903     /**
1904      * Translates a hal wifiDebugRingBufferFlag to the WifiNative version
1905      */
frameworkRingBufferFlagsFromHal(int wifiDebugRingBufferFlag)1906     private static int frameworkRingBufferFlagsFromHal(int wifiDebugRingBufferFlag) {
1907         BitMask checkoff = new BitMask(wifiDebugRingBufferFlag);
1908         int flags = 0;
1909         if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) {
1910             flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES;
1911         }
1912         if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) {
1913             flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES;
1914         }
1915         if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) {
1916             flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES;
1917         }
1918         if (checkoff.value != 0) {
1919             throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value);
1920         }
1921         return flags;
1922     }
1923 
halToFrameworkRadioCombinations( List<WifiRadioCombination> halCombos)1924     private static List<WifiChip.WifiRadioCombination> halToFrameworkRadioCombinations(
1925             List<WifiRadioCombination> halCombos) {
1926         List<WifiChip.WifiRadioCombination> frameworkCombos = new ArrayList<>();
1927         for (WifiRadioCombination combo : halCombos) {
1928             frameworkCombos.add(halToFrameworkRadioCombination(combo));
1929         }
1930         return frameworkCombos;
1931     }
1932 
halToFrameworkRadioCombination( WifiRadioCombination halCombo)1933     private static WifiChip.WifiRadioCombination halToFrameworkRadioCombination(
1934             WifiRadioCombination halCombo) {
1935         List<WifiChip.WifiRadioConfiguration> frameworkConfigs = new ArrayList<>();
1936         for (WifiRadioConfiguration config : halCombo.radioConfigurations) {
1937             frameworkConfigs.add(halToFrameworkRadioConfiguration(config));
1938         }
1939         return new WifiChip.WifiRadioCombination(frameworkConfigs);
1940     }
1941 
halToFrameworkRadioConfiguration( WifiRadioConfiguration halConfig)1942     private static WifiChip.WifiRadioConfiguration halToFrameworkRadioConfiguration(
1943             WifiRadioConfiguration halConfig) {
1944         return new WifiChip.WifiRadioConfiguration(halToFrameworkWifiBand(halConfig.bandInfo),
1945                 halToFrameworkAntennaMode(halConfig.antennaMode));
1946     }
1947 
1948     /**
1949      * Makes the Hal flavor of WifiScanner's band indication
1950      *
1951      * Note: This method is only used by background scan which does not
1952      *       support 6GHz, hence band combinations including 6GHz are considered invalid
1953      *
1954      * @param frameworkBand one of WifiScanner.WIFI_BAND_*
1955      * @return A WifiBand value
1956      * @throws IllegalArgumentException if frameworkBand is not recognized
1957      */
frameworkToHalWifiBand(int frameworkBand)1958     private static int frameworkToHalWifiBand(int frameworkBand) {
1959         switch (frameworkBand) {
1960             case WifiScanner.WIFI_BAND_UNSPECIFIED:
1961                 return WifiBand.BAND_UNSPECIFIED;
1962             case WifiScanner.WIFI_BAND_24_GHZ:
1963                 return WifiBand.BAND_24GHZ;
1964             case WifiScanner.WIFI_BAND_5_GHZ:
1965                 return WifiBand.BAND_5GHZ;
1966             case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
1967                 return WifiBand.BAND_5GHZ_DFS;
1968             case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS:
1969                 return WifiBand.BAND_5GHZ_WITH_DFS;
1970             case WifiScanner.WIFI_BAND_BOTH:
1971                 return WifiBand.BAND_24GHZ_5GHZ;
1972             case WifiScanner.WIFI_BAND_BOTH_WITH_DFS:
1973                 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS;
1974             case WifiScanner.WIFI_BAND_6_GHZ:
1975                 return WifiBand.BAND_6GHZ;
1976             case WifiScanner.WIFI_BAND_24_5_6_GHZ:
1977                 return WifiBand.BAND_24GHZ_5GHZ_6GHZ;
1978             case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ:
1979                 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ;
1980             case WifiScanner.WIFI_BAND_60_GHZ:
1981                 return WifiBand.BAND_60GHZ;
1982             case WifiScanner.WIFI_BAND_24_5_6_60_GHZ:
1983                 return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ;
1984             case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ:
1985                 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ;
1986             case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS:
1987             default:
1988                 throw new IllegalArgumentException("bad band " + frameworkBand);
1989         }
1990     }
1991 
bitmapContains(int bitmap, int expectedBit)1992     private static boolean bitmapContains(int bitmap, int expectedBit) {
1993         return (bitmap & expectedBit) != 0;
1994     }
1995 
halToFrameworkWifiBand(int halBand)1996     private static int halToFrameworkWifiBand(int halBand) {
1997         int frameworkBand = 0;
1998         if (bitmapContains(halBand, WifiBand.BAND_24GHZ)) {
1999             frameworkBand |= WifiScanner.WIFI_BAND_24_GHZ;
2000         }
2001         if (bitmapContains(halBand, WifiBand.BAND_5GHZ)) {
2002             frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ;
2003         }
2004         if (bitmapContains(halBand, WifiBand.BAND_5GHZ_DFS)) {
2005             frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY;
2006         }
2007         if (bitmapContains(halBand, WifiBand.BAND_6GHZ)) {
2008             frameworkBand |= WifiScanner.WIFI_BAND_6_GHZ;
2009         }
2010         if (bitmapContains(halBand, WifiBand.BAND_60GHZ)) {
2011             frameworkBand |= WifiScanner.WIFI_BAND_60_GHZ;
2012         }
2013         return frameworkBand;
2014     }
2015 
halToFrameworkAntennaMode(int mode)2016     private static @WifiChip.WifiAntennaMode int halToFrameworkAntennaMode(int mode) {
2017         switch (mode) {
2018             case WifiAntennaMode.WIFI_ANTENNA_MODE_UNSPECIFIED:
2019                 return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED;
2020             case WifiAntennaMode.WIFI_ANTENNA_MODE_1X1:
2021                 return WifiChip.WIFI_ANTENNA_MODE_1X1;
2022             case WifiAntennaMode.WIFI_ANTENNA_MODE_2X2:
2023                 return WifiChip.WIFI_ANTENNA_MODE_2X2;
2024             case WifiAntennaMode.WIFI_ANTENNA_MODE_3X3:
2025                 return WifiChip.WIFI_ANTENNA_MODE_3X3;
2026             case WifiAntennaMode.WIFI_ANTENNA_MODE_4X4:
2027                 return WifiChip.WIFI_ANTENNA_MODE_4X4;
2028             default:
2029                 Log.e(TAG, "Invalid WifiAntennaMode: " + mode);
2030                 return -1;
2031         }
2032     }
2033 
2034     /**
2035      * Convert framework's operational mode to HAL's operational mode.
2036      */
frameworkToHalIfaceMode(@ifiAvailableChannel.OpMode int mode)2037     private int frameworkToHalIfaceMode(@WifiAvailableChannel.OpMode int mode) {
2038         int halMode = 0;
2039         if ((mode & WifiAvailableChannel.OP_MODE_STA) != 0) {
2040             halMode |= WifiIfaceMode.IFACE_MODE_STA;
2041         }
2042         if ((mode & WifiAvailableChannel.OP_MODE_SAP) != 0) {
2043             halMode |= WifiIfaceMode.IFACE_MODE_SOFTAP;
2044         }
2045         if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI) != 0) {
2046             halMode |= WifiIfaceMode.IFACE_MODE_P2P_CLIENT;
2047         }
2048         if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO) != 0) {
2049             halMode |= WifiIfaceMode.IFACE_MODE_P2P_GO;
2050         }
2051         if ((mode & WifiAvailableChannel.OP_MODE_WIFI_AWARE) != 0) {
2052             halMode |= WifiIfaceMode.IFACE_MODE_NAN;
2053         }
2054         if ((mode & WifiAvailableChannel.OP_MODE_TDLS) != 0) {
2055             halMode |= WifiIfaceMode.IFACE_MODE_TDLS;
2056         }
2057         return halMode;
2058     }
2059 
2060     /**
2061      * Convert framework's WifiAvailableChannel.FILTER_* to HAL's UsableChannelFilter.
2062      */
frameworkToHalUsableFilter(@ifiAvailableChannel.Filter int filter)2063     private int frameworkToHalUsableFilter(@WifiAvailableChannel.Filter int filter) {
2064         int halFilter = 0;  // O implies no additional filter other than regulatory (default)
2065 
2066         if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
2067             halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter.CONCURRENCY;
2068         }
2069         if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
2070             halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter
2071                     .CELLULAR_COEXISTENCE;
2072         }
2073 
2074         return halFilter;
2075     }
2076 
2077     /**
2078      * Convert framework's WifiAvailableChannel.FILTER_* to HAL's UsableChannelFilter 1.6.
2079      */
frameworkToHalUsableFilter_1_6(@ifiAvailableChannel.Filter int filter)2080     private int frameworkToHalUsableFilter_1_6(@WifiAvailableChannel.Filter int filter) {
2081         int halFilter = 0;  // O implies no additional filter other than regulatory (default)
2082 
2083         if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
2084             halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter.CONCURRENCY;
2085         }
2086         if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
2087             halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter
2088                     .CELLULAR_COEXISTENCE;
2089         }
2090         if ((filter & WifiAvailableChannel.FILTER_NAN_INSTANT_MODE) != 0) {
2091             halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter.NAN_INSTANT_MODE;
2092         }
2093 
2094         return halFilter;
2095     }
2096 
2097     /**
2098      * Convert from HAL's operational mode to framework's operational mode.
2099      */
halToFrameworkIfaceMode(int halMode)2100     private @WifiAvailableChannel.OpMode int halToFrameworkIfaceMode(int halMode) {
2101         int mode = 0;
2102         if ((halMode & WifiIfaceMode.IFACE_MODE_STA) != 0) {
2103             mode |= WifiAvailableChannel.OP_MODE_STA;
2104         }
2105         if ((halMode & WifiIfaceMode.IFACE_MODE_SOFTAP) != 0) {
2106             mode |= WifiAvailableChannel.OP_MODE_SAP;
2107         }
2108         if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_CLIENT) != 0) {
2109             mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI;
2110         }
2111         if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_GO) != 0) {
2112             mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO;
2113         }
2114         if ((halMode & WifiIfaceMode.IFACE_MODE_NAN) != 0) {
2115             mode |= WifiAvailableChannel.OP_MODE_WIFI_AWARE;
2116         }
2117         if ((halMode & WifiIfaceMode.IFACE_MODE_TDLS) != 0) {
2118             mode |= WifiAvailableChannel.OP_MODE_TDLS;
2119         }
2120         return mode;
2121     }
2122 
2123     @NonNull
2124     private ArrayList<android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel>
frameworkCoexUnsafeChannelsToHidl( @onNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels)2125             frameworkCoexUnsafeChannelsToHidl(
2126             @NonNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels) {
2127         final ArrayList<android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel> hidlList =
2128                 new ArrayList<>();
2129         if (!SdkLevel.isAtLeastS()) {
2130             return hidlList;
2131         }
2132         for (android.net.wifi.CoexUnsafeChannel frameworkUnsafeChannel : frameworkUnsafeChannels) {
2133             final android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel hidlUnsafeChannel =
2134                     new android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel();
2135             switch (frameworkUnsafeChannel.getBand()) {
2136                 case (WifiScanner.WIFI_BAND_24_GHZ):
2137                     hidlUnsafeChannel.band = WifiBand.BAND_24GHZ;
2138                     break;
2139                 case (WifiScanner.WIFI_BAND_5_GHZ):
2140                     hidlUnsafeChannel.band = WifiBand.BAND_5GHZ;
2141                     break;
2142                 case (WifiScanner.WIFI_BAND_6_GHZ):
2143                     hidlUnsafeChannel.band = WifiBand.BAND_6GHZ;
2144                     break;
2145                 case (WifiScanner.WIFI_BAND_60_GHZ):
2146                     hidlUnsafeChannel.band = WifiBand.BAND_60GHZ;
2147                     break;
2148                 default:
2149                     Log.e(TAG, "Tried to set unsafe channel with unknown band: "
2150                             + frameworkUnsafeChannel.getBand());
2151                     continue;
2152             }
2153             hidlUnsafeChannel.channel = frameworkUnsafeChannel.getChannel();
2154             final int powerCapDbm = frameworkUnsafeChannel.getPowerCapDbm();
2155             if (powerCapDbm != POWER_CAP_NONE) {
2156                 hidlUnsafeChannel.powerCapDbm = powerCapDbm;
2157             } else {
2158                 hidlUnsafeChannel.powerCapDbm =
2159                         android.hardware.wifi.V1_5.IWifiChip.PowerCapConstant.NO_POWER_CAP;
2160             }
2161             hidlList.add(hidlUnsafeChannel);
2162         }
2163         return hidlList;
2164     }
2165 
frameworkCoexRestrictionsToHidl(@ifiManager.CoexRestriction int restrictions)2166     private int frameworkCoexRestrictionsToHidl(@WifiManager.CoexRestriction int restrictions) {
2167         int hidlRestrictions = 0;
2168         if (!SdkLevel.isAtLeastS()) {
2169             return hidlRestrictions;
2170         }
2171         if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) {
2172             hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.WIFI_DIRECT;
2173         }
2174         if ((restrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) {
2175             hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.SOFTAP;
2176         }
2177         if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) {
2178             hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.WIFI_AWARE;
2179         }
2180         return hidlRestrictions;
2181     }
2182 
frameworkMultiStaUseCaseToHidl(@ifiNative.MultiStaUseCase int useCase)2183     private byte frameworkMultiStaUseCaseToHidl(@WifiNative.MultiStaUseCase int useCase)
2184             throws IllegalArgumentException {
2185         switch (useCase) {
2186             case WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY:
2187                 return android.hardware.wifi.V1_5.IWifiChip
2188                         .MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY;
2189             case WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED:
2190                 return android.hardware.wifi.V1_5.IWifiChip
2191                         .MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED;
2192             default:
2193                 throw new IllegalArgumentException("Invalid use case " + useCase);
2194         }
2195     }
2196 
2197     /**
2198      * This method checks if we need to backoff wifi Tx power due to SAR requirements.
2199      * It handles the case when the device is running the V1_1 version of WifiChip HAL
2200      * In that HAL version, it is required to perform wifi Tx power backoff only if
2201      * a voice call is ongoing.
2202      */
sarPowerBackoffRequired_1_1(SarInfo sarInfo)2203     private static boolean sarPowerBackoffRequired_1_1(SarInfo sarInfo) {
2204         /* As long as no voice call is active (in case voice call is supported),
2205          * no backoff is needed
2206          */
2207         if (sarInfo.sarVoiceCallSupported) {
2208             return (sarInfo.isVoiceCall || sarInfo.isEarPieceActive);
2209         } else {
2210             return false;
2211         }
2212     }
2213 
2214     /**
2215      * This method maps the information inside the SarInfo instance into a SAR scenario
2216      * when device is running the V1_1 version of WifiChip HAL.
2217      * In this HAL version, only one scenario is defined which is for VOICE_CALL (if voice call is
2218      * supported).
2219      * Otherwise, an exception is thrown.
2220      */
frameworkToHalTxPowerScenario_1_1(SarInfo sarInfo)2221     private static int frameworkToHalTxPowerScenario_1_1(SarInfo sarInfo) {
2222         if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
2223             return android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL;
2224         } else {
2225             throw new IllegalArgumentException("bad scenario: voice call not active/supported");
2226         }
2227     }
2228 
2229     /**
2230      * This method checks if we need to backoff wifi Tx power due to SAR requirements.
2231      * It handles the case when the device is running the V1_2 version of WifiChip HAL
2232      */
sarPowerBackoffRequired_1_2(SarInfo sarInfo)2233     private static boolean sarPowerBackoffRequired_1_2(SarInfo sarInfo) {
2234         if (sarInfo.sarSapSupported && sarInfo.isWifiSapEnabled) {
2235             return true;
2236         }
2237         if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
2238             return true;
2239         }
2240         return false;
2241     }
2242 
2243     /**
2244      * This method maps the information inside the SarInfo instance into a SAR scenario
2245      * when device is running the V1_2 version of WifiChip HAL.
2246      * If SAR SoftAP input is supported,
2247      * we make these assumptions:
2248      *   - All voice calls are treated as if device is near the head.
2249      *   - SoftAP scenario is treated as if device is near the body.
2250      * In case SoftAP is not supported, then we should revert to the V1_1 HAL
2251      * behavior, and the only valid scenario would be when a voice call is ongoing.
2252      */
frameworkToHalTxPowerScenario_1_2(SarInfo sarInfo)2253     private static int frameworkToHalTxPowerScenario_1_2(SarInfo sarInfo) {
2254         if (sarInfo.sarSapSupported && sarInfo.sarVoiceCallSupported) {
2255             if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
2256                 return android.hardware.wifi.V1_2.IWifiChip
2257                         .TxPowerScenario.ON_HEAD_CELL_ON;
2258             } else if (sarInfo.isWifiSapEnabled) {
2259                 return android.hardware.wifi.V1_2.IWifiChip
2260                         .TxPowerScenario.ON_BODY_CELL_ON;
2261             } else {
2262                 throw new IllegalArgumentException("bad scenario: no voice call/softAP active");
2263             }
2264         } else if (sarInfo.sarVoiceCallSupported) {
2265             /* SAR SoftAP input not supported, act like V1_1 */
2266             if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
2267                 return android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL;
2268             } else {
2269                 throw new IllegalArgumentException("bad scenario: voice call not active");
2270             }
2271         } else {
2272             throw new IllegalArgumentException("Invalid case: voice call not supported");
2273         }
2274     }
2275 
getWifiChipV1_1Mockable()2276     protected android.hardware.wifi.V1_1.IWifiChip getWifiChipV1_1Mockable() {
2277         return android.hardware.wifi.V1_1.IWifiChip.castFrom(mWifiChip);
2278     }
2279 
getWifiChipV1_2Mockable()2280     protected android.hardware.wifi.V1_2.IWifiChip getWifiChipV1_2Mockable() {
2281         return android.hardware.wifi.V1_2.IWifiChip.castFrom(mWifiChip);
2282     }
2283 
getWifiChipV1_3Mockable()2284     protected android.hardware.wifi.V1_3.IWifiChip getWifiChipV1_3Mockable() {
2285         return android.hardware.wifi.V1_3.IWifiChip.castFrom(mWifiChip);
2286     }
2287 
getWifiChipV1_4Mockable()2288     protected android.hardware.wifi.V1_4.IWifiChip getWifiChipV1_4Mockable() {
2289         return android.hardware.wifi.V1_4.IWifiChip.castFrom(mWifiChip);
2290     }
2291 
getWifiChipV1_5Mockable()2292     protected android.hardware.wifi.V1_5.IWifiChip getWifiChipV1_5Mockable() {
2293         return android.hardware.wifi.V1_5.IWifiChip.castFrom(mWifiChip);
2294     }
2295 
getWifiChipV1_6Mockable()2296     protected android.hardware.wifi.V1_6.IWifiChip getWifiChipV1_6Mockable() {
2297         return android.hardware.wifi.V1_6.IWifiChip.castFrom(mWifiChip);
2298     }
2299 
intsFromArrayList(ArrayList<Integer> a)2300     private static int[] intsFromArrayList(ArrayList<Integer> a) {
2301         if (a == null) return null;
2302         int[] b = new int[a.size()];
2303         int i = 0;
2304         for (Integer e : a) b[i++] = e;
2305         return b;
2306     }
2307 
isOk(WifiStatus status, String methodStr)2308     private boolean isOk(WifiStatus status, String methodStr) {
2309         if (status.code == WifiStatusCode.SUCCESS) return true;
2310         Log.e(TAG, methodStr + " failed with status: " + status);
2311         return false;
2312     }
2313 
handleRemoteException(RemoteException e, String methodStr)2314     private void handleRemoteException(RemoteException e, String methodStr) {
2315         Log.e(TAG, methodStr + " failed with remote exception: " + e);
2316         mWifiChip = null;
2317     }
2318 
validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier)2319     private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
2320         if (mWifiChip == null) {
2321             Log.e(TAG, "Cannot call " + methodStr + " because mWifiChip is null");
2322             return defaultVal;
2323         }
2324         return supplier.get();
2325     }
2326 }
2327