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