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.hardware.wifi.IWifiApIface; 25 import android.hardware.wifi.IWifiChip.ChannelCategoryMask; 26 import android.hardware.wifi.IWifiChip.CoexRestriction; 27 import android.hardware.wifi.IWifiChip.FeatureSetMask; 28 import android.hardware.wifi.IWifiChip.LatencyMode; 29 import android.hardware.wifi.IWifiChip.MultiStaUseCase; 30 import android.hardware.wifi.IWifiChip.TxPowerScenario; 31 import android.hardware.wifi.IWifiChip.UsableChannelFilter; 32 import android.hardware.wifi.IWifiChipEventCallback; 33 import android.hardware.wifi.IWifiNanIface; 34 import android.hardware.wifi.IWifiP2pIface; 35 import android.hardware.wifi.IWifiRttController; 36 import android.hardware.wifi.IWifiStaIface; 37 import android.hardware.wifi.IfaceConcurrencyType; 38 import android.hardware.wifi.IfaceType; 39 import android.hardware.wifi.WifiAntennaMode; 40 import android.hardware.wifi.WifiBand; 41 import android.hardware.wifi.WifiChipCapabilities; 42 import android.hardware.wifi.WifiDebugHostWakeReasonStats; 43 import android.hardware.wifi.WifiDebugRingBufferFlags; 44 import android.hardware.wifi.WifiDebugRingBufferStatus; 45 import android.hardware.wifi.WifiIfaceMode; 46 import android.hardware.wifi.WifiRadioCombination; 47 import android.hardware.wifi.WifiRadioConfiguration; 48 import android.hardware.wifi.WifiStatusCode; 49 import android.hardware.wifi.WifiUsableChannel; 50 import android.net.wifi.CoexUnsafeChannel; 51 import android.net.wifi.WifiAvailableChannel; 52 import android.net.wifi.WifiManager; 53 import android.net.wifi.WifiScanner; 54 import android.os.RemoteException; 55 import android.os.ServiceSpecificException; 56 import android.util.Log; 57 58 import com.android.internal.annotations.VisibleForTesting; 59 import com.android.modules.utils.build.SdkLevel; 60 import com.android.server.wifi.SarInfo; 61 import com.android.server.wifi.SsidTranslator; 62 import com.android.server.wifi.WifiNative; 63 import com.android.server.wifi.WlanWakeReasonAndCounts; 64 import com.android.server.wifi.util.BitMask; 65 66 import java.util.ArrayList; 67 import java.util.Arrays; 68 import java.util.List; 69 70 /** 71 * AIDL implementation of the WifiChip interface. 72 */ 73 public class WifiChipAidlImpl implements IWifiChip { 74 private static final String TAG = "WifiChipAidlImpl"; 75 private android.hardware.wifi.IWifiChip mWifiChip; 76 private android.hardware.wifi.IWifiChipEventCallback mHalCallback; 77 private WifiChip.Callback mFrameworkCallback; 78 private final Object mLock = new Object(); 79 private Context mContext; 80 private SsidTranslator mSsidTranslator; 81 WifiChipAidlImpl(@onNull android.hardware.wifi.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)82 public WifiChipAidlImpl(@NonNull android.hardware.wifi.IWifiChip chip, 83 @NonNull Context context, @NonNull SsidTranslator ssidTranslator) { 84 mWifiChip = chip; 85 mContext = context; 86 mSsidTranslator = ssidTranslator; 87 } 88 89 /** 90 * See comments for {@link IWifiChip#configureChip(int)} 91 */ 92 @Override configureChip(int modeId)93 public boolean configureChip(int modeId) { 94 final String methodStr = "configureChip"; 95 synchronized (mLock) { 96 try { 97 if (!checkIfaceAndLogFailure(methodStr)) return false; 98 mWifiChip.configureChip(modeId); 99 return true; 100 } catch (RemoteException e) { 101 handleRemoteException(e, methodStr); 102 } catch (ServiceSpecificException e) { 103 handleServiceSpecificException(e, methodStr); 104 } 105 return false; 106 } 107 } 108 109 /** 110 * See comments for {@link IWifiChip#createApIface()} 111 */ 112 @Override 113 @Nullable createApIface()114 public WifiApIface createApIface() { 115 final String methodStr = "createApIface"; 116 synchronized (mLock) { 117 try { 118 if (!checkIfaceAndLogFailure(methodStr)) return null; 119 IWifiApIface iface = mWifiChip.createApIface(); 120 return new WifiApIface(iface); 121 } catch (RemoteException e) { 122 handleRemoteException(e, methodStr); 123 } catch (ServiceSpecificException e) { 124 handleServiceSpecificException(e, methodStr); 125 } 126 return null; 127 } 128 } 129 130 /** 131 * See comments for {@link IWifiChip#createBridgedApIface()} 132 */ 133 @Override 134 @Nullable createBridgedApIface()135 public WifiApIface createBridgedApIface() { 136 final String methodStr = "createBridgedApIface"; 137 synchronized (mLock) { 138 try { 139 if (!checkIfaceAndLogFailure(methodStr)) return null; 140 IWifiApIface iface = mWifiChip.createBridgedApIface(); 141 return new WifiApIface(iface); 142 } catch (RemoteException e) { 143 handleRemoteException(e, methodStr); 144 } catch (ServiceSpecificException e) { 145 handleServiceSpecificException(e, methodStr); 146 } 147 return null; 148 } 149 } 150 151 /** 152 * See comments for {@link IWifiChip#createNanIface()} 153 */ 154 @Override 155 @Nullable createNanIface()156 public WifiNanIface createNanIface() { 157 final String methodStr = "createNanIface"; 158 synchronized (mLock) { 159 try { 160 if (!checkIfaceAndLogFailure(methodStr)) return null; 161 IWifiNanIface iface = mWifiChip.createNanIface(); 162 return new WifiNanIface(iface); 163 } catch (RemoteException e) { 164 handleRemoteException(e, methodStr); 165 } catch (ServiceSpecificException e) { 166 handleServiceSpecificException(e, methodStr); 167 } 168 return null; 169 } 170 } 171 172 /** 173 * See comments for {@link IWifiChip#createP2pIface()} 174 */ 175 @Override 176 @Nullable createP2pIface()177 public WifiP2pIface createP2pIface() { 178 final String methodStr = "createP2pIface"; 179 synchronized (mLock) { 180 try { 181 if (!checkIfaceAndLogFailure(methodStr)) return null; 182 IWifiP2pIface iface = mWifiChip.createP2pIface(); 183 return new WifiP2pIface(iface); 184 } catch (RemoteException e) { 185 handleRemoteException(e, methodStr); 186 } catch (ServiceSpecificException e) { 187 handleServiceSpecificException(e, methodStr); 188 } 189 return null; 190 } 191 } 192 193 /** 194 * See comments for {@link IWifiChip#createRttController()} 195 */ 196 @Override 197 @Nullable createRttController()198 public WifiRttController createRttController() { 199 final String methodStr = "createRttController"; 200 synchronized (mLock) { 201 try { 202 if (!checkIfaceAndLogFailure(methodStr)) return null; 203 IWifiRttController rttController = mWifiChip.createRttController(null); 204 return new WifiRttController(rttController); 205 } catch (RemoteException e) { 206 handleRemoteException(e, methodStr); 207 } catch (ServiceSpecificException e) { 208 handleServiceSpecificException(e, methodStr); 209 } 210 return null; 211 } 212 } 213 214 /** 215 * See comments for {@link IWifiChip#createStaIface()} 216 */ 217 @Override 218 @Nullable createStaIface()219 public WifiStaIface createStaIface() { 220 final String methodStr = "createStaIface"; 221 synchronized (mLock) { 222 try { 223 if (!checkIfaceAndLogFailure(methodStr)) return null; 224 IWifiStaIface iface = mWifiChip.createStaIface(); 225 return new WifiStaIface(iface, mContext, mSsidTranslator); 226 } catch (RemoteException e) { 227 handleRemoteException(e, methodStr); 228 } catch (ServiceSpecificException e) { 229 handleServiceSpecificException(e, methodStr); 230 } 231 return null; 232 } 233 } 234 235 /** 236 * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)} 237 */ 238 @Override enableDebugErrorAlerts(boolean enable)239 public boolean enableDebugErrorAlerts(boolean enable) { 240 final String methodStr = "enableDebugErrorAlerts"; 241 synchronized (mLock) { 242 try { 243 if (!checkIfaceAndLogFailure(methodStr)) return false; 244 mWifiChip.enableDebugErrorAlerts(enable); 245 return true; 246 } catch (RemoteException e) { 247 handleRemoteException(e, methodStr); 248 } catch (ServiceSpecificException e) { 249 handleServiceSpecificException(e, methodStr); 250 } 251 return false; 252 } 253 } 254 255 /** 256 * See comments for {@link IWifiChip#flushRingBufferToFile()} 257 */ 258 @Override flushRingBufferToFile()259 public boolean flushRingBufferToFile() { 260 final String methodStr = "flushRingBufferToFile"; 261 synchronized (mLock) { 262 try { 263 if (!checkIfaceAndLogFailure(methodStr)) return false; 264 mWifiChip.flushRingBufferToFile(); 265 return true; 266 } catch (RemoteException e) { 267 handleRemoteException(e, methodStr); 268 } catch (ServiceSpecificException e) { 269 handleServiceSpecificException(e, methodStr); 270 } 271 return false; 272 } 273 } 274 275 /** 276 * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)} 277 */ 278 @Override forceDumpToDebugRingBuffer(String ringName)279 public boolean forceDumpToDebugRingBuffer(String ringName) { 280 final String methodStr = "forceDumpToDebugRingBuffer"; 281 synchronized (mLock) { 282 try { 283 if (!checkIfaceAndLogFailure(methodStr)) return false; 284 mWifiChip.forceDumpToDebugRingBuffer(ringName); 285 return true; 286 } catch (RemoteException e) { 287 handleRemoteException(e, methodStr); 288 } catch (ServiceSpecificException e) { 289 handleServiceSpecificException(e, methodStr); 290 } 291 return false; 292 } 293 } 294 295 /** 296 * See comments for {@link IWifiChip#getApIface(String)} 297 */ 298 @Override 299 @Nullable getApIface(String ifaceName)300 public WifiApIface getApIface(String ifaceName) { 301 final String methodStr = "getApIface"; 302 synchronized (mLock) { 303 try { 304 if (!checkIfaceAndLogFailure(methodStr)) return null; 305 IWifiApIface iface = mWifiChip.getApIface(ifaceName); 306 return new WifiApIface(iface); 307 } catch (RemoteException e) { 308 handleRemoteException(e, methodStr); 309 } catch (ServiceSpecificException e) { 310 handleServiceSpecificException(e, methodStr); 311 } 312 return null; 313 } 314 } 315 316 /** 317 * See comments for {@link IWifiChip#getApIfaceNames()} 318 */ 319 @Override 320 @Nullable getApIfaceNames()321 public List<String> getApIfaceNames() { 322 final String methodStr = "getApIfaceNames"; 323 synchronized (mLock) { 324 try { 325 if (!checkIfaceAndLogFailure(methodStr)) return null; 326 String[] ifaceNames = mWifiChip.getApIfaceNames(); 327 return Arrays.asList(ifaceNames); 328 } catch (RemoteException e) { 329 handleRemoteException(e, methodStr); 330 } catch (ServiceSpecificException e) { 331 handleServiceSpecificException(e, methodStr); 332 } 333 return null; 334 } 335 } 336 337 /** 338 * See comments for {@link IWifiChip#getAvailableModes()} 339 */ 340 @Override 341 @Nullable getAvailableModes()342 public List<WifiChip.ChipMode> getAvailableModes() { 343 final String methodStr = "getAvailableModes"; 344 synchronized (mLock) { 345 try { 346 if (!checkIfaceAndLogFailure(methodStr)) return null; 347 android.hardware.wifi.IWifiChip.ChipMode[] halModes = mWifiChip.getAvailableModes(); 348 return halToFrameworkChipModeList(halModes); 349 } catch (RemoteException e) { 350 handleRemoteException(e, methodStr); 351 } catch (ServiceSpecificException e) { 352 handleServiceSpecificException(e, methodStr); 353 } 354 return null; 355 } 356 } 357 358 /** 359 * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()} 360 */ 361 @Override getCapabilitiesBeforeIfacesExist()362 public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() { 363 final String methodStr = "getCapabilitiesBeforeIfacesExist"; 364 return getCapabilitiesInternal(methodStr); 365 } 366 367 /** 368 * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()} 369 */ 370 @Override getCapabilitiesAfterIfacesExist()371 public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() { 372 final String methodStr = "getCapabilitiesAfterIfacesExist"; 373 return getCapabilitiesInternal(methodStr); 374 } 375 getCapabilitiesInternal(String methodStr)376 private WifiChip.Response<Long> getCapabilitiesInternal(String methodStr) { 377 // getCapabilities uses the same logic in AIDL, regardless of whether the call 378 // happens before or after any interfaces have been created. 379 WifiChip.Response<Long> featuresResp = new WifiChip.Response<>(0L); 380 synchronized (mLock) { 381 try { 382 if (!checkIfaceAndLogFailure(methodStr)) return featuresResp; 383 long halFeatureSet = mWifiChip.getFeatureSet(); 384 featuresResp.setValue(halToFrameworkChipFeatureSet(halFeatureSet)); 385 featuresResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS); 386 } catch (RemoteException e) { 387 handleRemoteException(e, methodStr); 388 featuresResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION); 389 } catch (ServiceSpecificException e) { 390 handleServiceSpecificException(e, methodStr); 391 // TODO: convert to framework status code once WifiHalAidlImpl exists 392 featuresResp.setStatusCode(e.errorCode); 393 } 394 return featuresResp; 395 } 396 } 397 398 /** 399 * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()} 400 */ 401 @Override 402 @Nullable getDebugHostWakeReasonStats()403 public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() { 404 final String methodStr = "getDebugHostWakeReasonStats"; 405 synchronized (mLock) { 406 try { 407 if (!checkIfaceAndLogFailure(methodStr)) return null; 408 WifiDebugHostWakeReasonStats stats = mWifiChip.getDebugHostWakeReasonStats(); 409 return halToFrameworkWakeReasons(stats); 410 } catch (RemoteException e) { 411 handleRemoteException(e, methodStr); 412 } catch (ServiceSpecificException e) { 413 handleServiceSpecificException(e, methodStr); 414 } 415 return null; 416 } 417 } 418 419 /** 420 * See comments for {@link IWifiChip#getDebugRingBuffersStatus()} 421 */ 422 @Override 423 @Nullable getDebugRingBuffersStatus()424 public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() { 425 final String methodStr = "getDebugRingBuffersStatus"; 426 synchronized (mLock) { 427 try { 428 if (!checkIfaceAndLogFailure(methodStr)) return null; 429 WifiDebugRingBufferStatus[] stats = mWifiChip.getDebugRingBuffersStatus(); 430 return halToFrameworkRingBufferStatusList(stats); 431 } catch (RemoteException e) { 432 handleRemoteException(e, methodStr); 433 } catch (ServiceSpecificException e) { 434 handleServiceSpecificException(e, methodStr); 435 } catch (IllegalArgumentException e) { 436 handleIllegalArgumentException(e, methodStr); 437 } 438 return null; 439 } 440 } 441 442 /** 443 * See comments for {@link IWifiChip#getId()} 444 */ 445 @Override getId()446 public int getId() { 447 final String methodStr = "getId"; 448 synchronized (mLock) { 449 try { 450 if (!checkIfaceAndLogFailure(methodStr)) return -1; 451 return mWifiChip.getId(); 452 } catch (RemoteException e) { 453 handleRemoteException(e, methodStr); 454 } catch (ServiceSpecificException e) { 455 handleServiceSpecificException(e, methodStr); 456 } 457 return -1; 458 } 459 } 460 461 /** 462 * See comments for {@link IWifiChip#getMode()} 463 */ 464 @Override getMode()465 public WifiChip.Response<Integer> getMode() { 466 final String methodStr = "getMode"; 467 WifiChip.Response<Integer> modeResp = new WifiChip.Response<>(0); 468 synchronized (mLock) { 469 try { 470 if (!checkIfaceAndLogFailure(methodStr)) return modeResp; 471 int mode = mWifiChip.getMode(); 472 modeResp.setValue(mode); 473 modeResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS); 474 } catch (RemoteException e) { 475 handleRemoteException(e, methodStr); 476 modeResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION); 477 } catch (ServiceSpecificException e) { 478 handleServiceSpecificException(e, methodStr); 479 // TODO: convert to framework status code once WifiHalAidlImpl exists 480 modeResp.setStatusCode(e.errorCode); 481 } 482 return modeResp; 483 } 484 } 485 486 /** 487 * See comments for {@link IWifiChip#getNanIface(String)} 488 */ 489 @Override 490 @Nullable getNanIface(String ifaceName)491 public WifiNanIface getNanIface(String ifaceName) { 492 final String methodStr = "getNanIface"; 493 synchronized (mLock) { 494 try { 495 if (!checkIfaceAndLogFailure(methodStr)) return null; 496 IWifiNanIface iface = mWifiChip.getNanIface(ifaceName); 497 return new WifiNanIface(iface); 498 } catch (RemoteException e) { 499 handleRemoteException(e, methodStr); 500 } catch (ServiceSpecificException e) { 501 handleServiceSpecificException(e, methodStr); 502 } 503 return null; 504 } 505 } 506 507 /** 508 * See comments for {@link IWifiChip#getNanIfaceNames()} 509 */ 510 @Override 511 @Nullable getNanIfaceNames()512 public List<String> getNanIfaceNames() { 513 final String methodStr = "getNanIfaceNames"; 514 synchronized (mLock) { 515 try { 516 if (!checkIfaceAndLogFailure(methodStr)) return null; 517 String[] ifaceNames = mWifiChip.getNanIfaceNames(); 518 return Arrays.asList(ifaceNames); 519 } catch (RemoteException e) { 520 handleRemoteException(e, methodStr); 521 } catch (ServiceSpecificException e) { 522 handleServiceSpecificException(e, methodStr); 523 } 524 return null; 525 } 526 } 527 528 /** 529 * See comments for {@link IWifiChip#getP2pIface(String)} 530 */ 531 @Override 532 @Nullable getP2pIface(String ifaceName)533 public WifiP2pIface getP2pIface(String ifaceName) { 534 final String methodStr = "getP2pIface"; 535 synchronized (mLock) { 536 try { 537 if (!checkIfaceAndLogFailure(methodStr)) return null; 538 IWifiP2pIface iface = mWifiChip.getP2pIface(ifaceName); 539 return new WifiP2pIface(iface); 540 } catch (RemoteException e) { 541 handleRemoteException(e, methodStr); 542 } catch (ServiceSpecificException e) { 543 handleServiceSpecificException(e, methodStr); 544 } 545 return null; 546 } 547 } 548 549 /** 550 * See comments for {@link IWifiChip#getP2pIfaceNames()} 551 */ 552 @Override 553 @Nullable getP2pIfaceNames()554 public List<String> getP2pIfaceNames() { 555 final String methodStr = "getP2pIfaceNames"; 556 synchronized (mLock) { 557 try { 558 if (!checkIfaceAndLogFailure(methodStr)) return null; 559 String[] ifaceNames = mWifiChip.getP2pIfaceNames(); 560 return Arrays.asList(ifaceNames); 561 } catch (RemoteException e) { 562 handleRemoteException(e, methodStr); 563 } catch (ServiceSpecificException e) { 564 handleServiceSpecificException(e, methodStr); 565 } 566 return null; 567 } 568 } 569 570 /** 571 * See comments for {@link IWifiChip#getStaIface(String)} 572 */ 573 @Override 574 @Nullable getStaIface(String ifaceName)575 public WifiStaIface getStaIface(String ifaceName) { 576 final String methodStr = "getStaIface"; 577 synchronized (mLock) { 578 try { 579 if (!checkIfaceAndLogFailure(methodStr)) return null; 580 IWifiStaIface iface = mWifiChip.getStaIface(ifaceName); 581 return new WifiStaIface(iface, mContext, mSsidTranslator); 582 } catch (RemoteException e) { 583 handleRemoteException(e, methodStr); 584 } catch (ServiceSpecificException e) { 585 handleServiceSpecificException(e, methodStr); 586 } 587 return null; 588 } 589 } 590 591 /** 592 * See comments for {@link IWifiChip#getStaIfaceNames()} 593 */ 594 @Override 595 @Nullable getStaIfaceNames()596 public List<String> getStaIfaceNames() { 597 final String methodStr = "getStaIfaceNames"; 598 synchronized (mLock) { 599 try { 600 if (!checkIfaceAndLogFailure(methodStr)) return null; 601 String[] ifaceNames = mWifiChip.getStaIfaceNames(); 602 return Arrays.asList(ifaceNames); 603 } catch (RemoteException e) { 604 handleRemoteException(e, methodStr); 605 } catch (ServiceSpecificException e) { 606 handleServiceSpecificException(e, methodStr); 607 } 608 return null; 609 } 610 } 611 612 /** 613 * See comments for {@link IWifiChip#getSupportedRadioCombinations()} 614 */ 615 @Override 616 @Nullable getSupportedRadioCombinations()617 public List<WifiChip.WifiRadioCombination> getSupportedRadioCombinations() { 618 final String methodStr = "getSupportedRadioCombinations"; 619 synchronized (mLock) { 620 try { 621 if (!checkIfaceAndLogFailure(methodStr)) return null; 622 WifiRadioCombination[] halCombos = mWifiChip.getSupportedRadioCombinations(); 623 return halToFrameworkRadioCombinations(halCombos); 624 } catch (RemoteException e) { 625 handleRemoteException(e, methodStr); 626 } catch (ServiceSpecificException e) { 627 handleServiceSpecificException(e, methodStr); 628 } 629 return null; 630 } 631 } 632 633 /** 634 * See comments for {@link IWifiChip#getWifiChipCapabilities()} 635 */ getWifiChipCapabilities()636 public WifiChip.WifiChipCapabilities getWifiChipCapabilities() { 637 final String methodStr = "getWifiChipCapabilities"; 638 synchronized (mLock) { 639 try { 640 if (!checkIfaceAndLogFailure(methodStr)) return null; 641 WifiChipCapabilities halCapab = mWifiChip.getWifiChipCapabilities(); 642 return halToFrameworkWifiChipCapabilities(halCapab); 643 } catch (RemoteException e) { 644 handleRemoteException(e, methodStr); 645 } catch (ServiceSpecificException e) { 646 handleServiceSpecificException(e, methodStr); 647 } 648 return null; 649 } 650 } 651 652 /** 653 * See comments for {@link IWifiChip#getUsableChannels(int, int, int)} 654 */ 655 @Override 656 @Nullable getUsableChannels(@ifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter)657 public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band, 658 @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) { 659 final String methodStr = "getUsableChannels"; 660 synchronized (mLock) { 661 try { 662 if (!checkIfaceAndLogFailure(methodStr)) return null; 663 WifiUsableChannel[] halChannels = mWifiChip.getUsableChannels( 664 frameworkToHalWifiBand(band), 665 frameworkToHalIfaceMode(mode), 666 frameworkToHalUsableFilter(filter)); 667 List<WifiAvailableChannel> frameworkChannels = new ArrayList<>(); 668 for (WifiUsableChannel ch : halChannels) { 669 frameworkChannels.add(new WifiAvailableChannel( 670 ch.channel, halToFrameworkIfaceMode(ch.ifaceModeMask))); 671 } 672 return frameworkChannels; 673 } catch (RemoteException e) { 674 handleRemoteException(e, methodStr); 675 } catch (ServiceSpecificException e) { 676 handleServiceSpecificException(e, methodStr); 677 } catch (IllegalArgumentException e) { 678 handleIllegalArgumentException(e, methodStr); 679 } 680 return null; 681 } 682 } 683 684 /** 685 * See comments for {@link IWifiChip#registerCallback(WifiChip.Callback)} 686 */ 687 @Override registerCallback(WifiChip.Callback callback)688 public boolean registerCallback(WifiChip.Callback callback) { 689 final String methodStr = "registerCallback"; 690 synchronized (mLock) { 691 if (!checkIfaceAndLogFailure(methodStr)) return false; 692 if (mFrameworkCallback != null) { 693 Log.e(TAG, "Framework callback is already registered"); 694 return false; 695 } else if (callback == null) { 696 Log.e(TAG, "Cannot register a null callback"); 697 return false; 698 } 699 700 try { 701 mHalCallback = new ChipEventCallback(); 702 mWifiChip.registerEventCallback(mHalCallback); 703 mFrameworkCallback = callback; 704 return true; 705 } catch (RemoteException e) { 706 handleRemoteException(e, methodStr); 707 } catch (ServiceSpecificException e) { 708 handleServiceSpecificException(e, methodStr); 709 } 710 return false; 711 } 712 } 713 714 /** 715 * See comments for {@link IWifiChip#removeApIface(String)} 716 */ 717 @Override removeApIface(String ifaceName)718 public boolean removeApIface(String ifaceName) { 719 final String methodStr = "removeApIface"; 720 synchronized (mLock) { 721 try { 722 if (!checkIfaceAndLogFailure(methodStr)) return false; 723 mWifiChip.removeApIface(ifaceName); 724 return true; 725 } catch (RemoteException e) { 726 handleRemoteException(e, methodStr); 727 } catch (ServiceSpecificException e) { 728 handleServiceSpecificException(e, methodStr); 729 } 730 return false; 731 } 732 } 733 734 /** 735 * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)} 736 */ 737 @Override removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName)738 public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) { 739 final String methodStr = "removeIfaceInstanceFromBridgedApIface"; 740 synchronized (mLock) { 741 try { 742 if (!checkIfaceAndLogFailure(methodStr)) return false; 743 mWifiChip.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName); 744 return true; 745 } catch (RemoteException e) { 746 handleRemoteException(e, methodStr); 747 } catch (ServiceSpecificException e) { 748 handleServiceSpecificException(e, methodStr); 749 } 750 return false; 751 } 752 } 753 754 /** 755 * See comments for {@link IWifiChip#removeNanIface(String)} 756 */ 757 @Override removeNanIface(String ifaceName)758 public boolean removeNanIface(String ifaceName) { 759 final String methodStr = "removeNanIface"; 760 synchronized (mLock) { 761 try { 762 if (!checkIfaceAndLogFailure(methodStr)) return false; 763 mWifiChip.removeNanIface(ifaceName); 764 return true; 765 } catch (RemoteException e) { 766 handleRemoteException(e, methodStr); 767 } catch (ServiceSpecificException e) { 768 handleServiceSpecificException(e, methodStr); 769 } 770 return false; 771 } 772 } 773 774 /** 775 * See comments for {@link IWifiChip#removeP2pIface(String)} 776 */ 777 @Override removeP2pIface(String ifaceName)778 public boolean removeP2pIface(String ifaceName) { 779 final String methodStr = "removeP2pIface"; 780 synchronized (mLock) { 781 try { 782 if (!checkIfaceAndLogFailure(methodStr)) return false; 783 mWifiChip.removeP2pIface(ifaceName); 784 return true; 785 } catch (RemoteException e) { 786 handleRemoteException(e, methodStr); 787 } catch (ServiceSpecificException e) { 788 handleServiceSpecificException(e, methodStr); 789 } 790 return false; 791 } 792 } 793 794 /** 795 * See comments for {@link IWifiChip#removeStaIface(String)} 796 */ 797 @Override removeStaIface(String ifaceName)798 public boolean removeStaIface(String ifaceName) { 799 final String methodStr = "removeStaIface"; 800 synchronized (mLock) { 801 try { 802 if (!checkIfaceAndLogFailure(methodStr)) return false; 803 mWifiChip.removeStaIface(ifaceName); 804 return true; 805 } catch (RemoteException e) { 806 handleRemoteException(e, methodStr); 807 } catch (ServiceSpecificException e) { 808 handleServiceSpecificException(e, methodStr); 809 } 810 return false; 811 } 812 } 813 814 /** 815 * See comments for {@link IWifiChip#requestChipDebugInfo()} 816 */ 817 @Override 818 @Nullable requestChipDebugInfo()819 public WifiChip.ChipDebugInfo requestChipDebugInfo() { 820 final String methodStr = "requestChipDebugInfo"; 821 synchronized (mLock) { 822 try { 823 if (!checkIfaceAndLogFailure(methodStr)) return null; 824 android.hardware.wifi.IWifiChip.ChipDebugInfo info = 825 mWifiChip.requestChipDebugInfo(); 826 return new WifiChip.ChipDebugInfo(info.driverDescription, info.firmwareDescription); 827 } catch (RemoteException e) { 828 handleRemoteException(e, methodStr); 829 } catch (ServiceSpecificException e) { 830 handleServiceSpecificException(e, methodStr); 831 } 832 return null; 833 } 834 } 835 836 /** 837 * See comments for {@link IWifiChip#requestDriverDebugDump()} 838 */ 839 @Override 840 @Nullable requestDriverDebugDump()841 public byte[] requestDriverDebugDump() { 842 final String methodStr = "requestDriverDebugDump"; 843 synchronized (mLock) { 844 try { 845 if (!checkIfaceAndLogFailure(methodStr)) return null; 846 return mWifiChip.requestDriverDebugDump(); 847 } catch (RemoteException e) { 848 handleRemoteException(e, methodStr); 849 } catch (ServiceSpecificException e) { 850 handleServiceSpecificException(e, methodStr); 851 } 852 return null; 853 } 854 } 855 856 /** 857 * See comments for {@link IWifiChip#requestFirmwareDebugDump()} 858 */ 859 @Override 860 @Nullable requestFirmwareDebugDump()861 public byte[] requestFirmwareDebugDump() { 862 final String methodStr = "requestFirmwareDebugDump"; 863 synchronized (mLock) { 864 try { 865 if (!checkIfaceAndLogFailure(methodStr)) return null; 866 return mWifiChip.requestFirmwareDebugDump(); 867 } catch (RemoteException e) { 868 handleRemoteException(e, methodStr); 869 } catch (ServiceSpecificException e) { 870 handleServiceSpecificException(e, methodStr); 871 } 872 return null; 873 } 874 } 875 876 /** 877 * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)} 878 */ 879 @Override selectTxPowerScenario(SarInfo sarInfo)880 public boolean selectTxPowerScenario(SarInfo sarInfo) { 881 final String methodStr = "selectTxPowerScenario"; 882 synchronized (mLock) { 883 try { 884 if (!checkIfaceAndLogFailure(methodStr)) return false; 885 if (sarPowerBackoffRequired(sarInfo)) { 886 // Power backoff is needed, so calculate and set the required scenario. 887 int halScenario = frameworkToHalTxPowerScenario(sarInfo); 888 if (sarInfo.setSarScenarioNeeded(halScenario)) { 889 Log.d(TAG, "Attempting to set SAR scenario to " + halScenario); 890 mWifiChip.selectTxPowerScenario(halScenario); 891 } 892 // Reaching here means that setting SAR scenario would be redundant, 893 // do nothing and return with success. 894 return true; 895 } 896 897 // We don't need to perform power backoff, so attempt to reset the SAR scenario. 898 if (sarInfo.resetSarScenarioNeeded()) { 899 Log.d(TAG, "Attempting to reset the SAR scenario"); 900 mWifiChip.resetTxPowerScenario(); 901 } 902 903 // If no if-statement was executed, then setting/resetting the SAR scenario would 904 // have been redundant. Do nothing and return with success. 905 return true; 906 } catch (RemoteException e) { 907 handleRemoteException(e, methodStr); 908 } catch (ServiceSpecificException e) { 909 handleServiceSpecificException(e, methodStr); 910 } catch (IllegalArgumentException e) { 911 handleIllegalArgumentException(e, methodStr); 912 } 913 return false; 914 } 915 } 916 917 /** 918 * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)} 919 */ 920 @Override setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions)921 public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) { 922 final String methodStr = "setCoexUnsafeChannels"; 923 synchronized (mLock) { 924 try { 925 if (!checkIfaceAndLogFailure(methodStr)) return false; 926 android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] halChannels = 927 frameworkToHalCoexUnsafeChannels(unsafeChannels); 928 int halRestrictions = frameworkToHalCoexRestrictions(restrictions); 929 mWifiChip.setCoexUnsafeChannels(halChannels, halRestrictions); 930 return true; 931 } catch (RemoteException e) { 932 handleRemoteException(e, methodStr); 933 } catch (ServiceSpecificException e) { 934 handleServiceSpecificException(e, methodStr); 935 } 936 return false; 937 } 938 } 939 940 /** 941 * See comments for {@link IWifiChip#setCountryCode(byte[])} 942 */ 943 @Override setCountryCode(byte[] code)944 public boolean setCountryCode(byte[] code) { 945 final String methodStr = "setCountryCode"; 946 synchronized (mLock) { 947 try { 948 if (!checkIfaceAndLogFailure(methodStr)) return false; 949 mWifiChip.setCountryCode(code); 950 return true; 951 } catch (RemoteException e) { 952 handleRemoteException(e, methodStr); 953 } catch (ServiceSpecificException e) { 954 handleServiceSpecificException(e, methodStr); 955 } 956 return false; 957 } 958 } 959 960 /** 961 * See comments for {@link IWifiChip#setLowLatencyMode(boolean)} 962 */ 963 @Override setLowLatencyMode(boolean enable)964 public boolean setLowLatencyMode(boolean enable) { 965 final String methodStr = "setLowLatencyMode"; 966 synchronized (mLock) { 967 try { 968 if (!checkIfaceAndLogFailure(methodStr)) return false; 969 int mode = enable ? LatencyMode.LOW : LatencyMode.NORMAL; 970 mWifiChip.setLatencyMode(mode); 971 return true; 972 } catch (RemoteException e) { 973 handleRemoteException(e, methodStr); 974 } catch (ServiceSpecificException e) { 975 handleServiceSpecificException(e, methodStr); 976 } 977 return false; 978 } 979 } 980 981 /** 982 * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)} 983 */ 984 @Override setMultiStaPrimaryConnection(String ifaceName)985 public boolean setMultiStaPrimaryConnection(String ifaceName) { 986 final String methodStr = "setMultiStaPrimaryConnection"; 987 synchronized (mLock) { 988 try { 989 if (!checkIfaceAndLogFailure(methodStr)) return false; 990 mWifiChip.setMultiStaPrimaryConnection(ifaceName); 991 return true; 992 } catch (RemoteException e) { 993 handleRemoteException(e, methodStr); 994 } catch (ServiceSpecificException e) { 995 handleServiceSpecificException(e, methodStr); 996 } 997 return false; 998 } 999 } 1000 1001 /** 1002 * See comments for {@link IWifiChip#setMultiStaUseCase(int)} 1003 */ 1004 @Override setMultiStaUseCase(@ifiNative.MultiStaUseCase int useCase)1005 public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) { 1006 final String methodStr = "setMultiStaUseCase"; 1007 synchronized (mLock) { 1008 try { 1009 if (!checkIfaceAndLogFailure(methodStr)) return false; 1010 mWifiChip.setMultiStaUseCase(frameworkToHalMultiStaUseCase(useCase)); 1011 return true; 1012 } catch (RemoteException e) { 1013 handleRemoteException(e, methodStr); 1014 } catch (ServiceSpecificException e) { 1015 handleServiceSpecificException(e, methodStr); 1016 } catch (IllegalArgumentException e) { 1017 handleIllegalArgumentException(e, methodStr); 1018 } 1019 return false; 1020 } 1021 } 1022 1023 /** 1024 * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)} 1025 */ 1026 @Override startLoggingToDebugRingBuffer(String ringName, int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes)1027 public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel, 1028 int maxIntervalInSec, int minDataSizeInBytes) { 1029 final String methodStr = "startLoggingToDebugRingBuffer"; 1030 synchronized (mLock) { 1031 try { 1032 if (!checkIfaceAndLogFailure(methodStr)) return false; 1033 mWifiChip.startLoggingToDebugRingBuffer( 1034 ringName, verboseLevel, maxIntervalInSec, minDataSizeInBytes); 1035 return true; 1036 } catch (RemoteException e) { 1037 handleRemoteException(e, methodStr); 1038 } catch (ServiceSpecificException e) { 1039 handleServiceSpecificException(e, methodStr); 1040 } 1041 return false; 1042 } 1043 } 1044 1045 /** 1046 * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()} 1047 */ 1048 @Override stopLoggingToDebugRingBuffer()1049 public boolean stopLoggingToDebugRingBuffer() { 1050 final String methodStr = "stopLoggingToDebugRingBuffer"; 1051 synchronized (mLock) { 1052 try { 1053 if (!checkIfaceAndLogFailure(methodStr)) return false; 1054 mWifiChip.stopLoggingToDebugRingBuffer(); 1055 return true; 1056 } catch (RemoteException e) { 1057 handleRemoteException(e, methodStr); 1058 } catch (ServiceSpecificException e) { 1059 handleServiceSpecificException(e, methodStr); 1060 } 1061 return false; 1062 } 1063 } 1064 1065 /** 1066 * See comments for {@link IWifiChip#triggerSubsystemRestart()} 1067 */ 1068 @Override triggerSubsystemRestart()1069 public boolean triggerSubsystemRestart() { 1070 final String methodStr = "triggerSubsystemRestart"; 1071 synchronized (mLock) { 1072 try { 1073 if (!checkIfaceAndLogFailure(methodStr)) return false; 1074 mWifiChip.triggerSubsystemRestart(); 1075 return true; 1076 } catch (RemoteException e) { 1077 handleRemoteException(e, methodStr); 1078 } catch (ServiceSpecificException e) { 1079 handleServiceSpecificException(e, methodStr); 1080 } 1081 return false; 1082 } 1083 } 1084 1085 /** 1086 * See comments for {@link IWifiChip#enableStaChannelForPeerNetwork(boolean, boolean)} 1087 */ 1088 @Override enableStaChannelForPeerNetwork(boolean enableIndoorChannel, boolean enableDfsChannel)1089 public boolean enableStaChannelForPeerNetwork(boolean enableIndoorChannel, 1090 boolean enableDfsChannel) { 1091 final String methodStr = "enableStaChannelForPeerNetwork"; 1092 synchronized (mLock) { 1093 try { 1094 if (!checkIfaceAndLogFailure(methodStr)) return false; 1095 int halChannelCategoryEnableFlag = 0; 1096 if (enableIndoorChannel) { 1097 halChannelCategoryEnableFlag |= ChannelCategoryMask.INDOOR_CHANNEL; 1098 } 1099 if (enableDfsChannel) { 1100 halChannelCategoryEnableFlag |= ChannelCategoryMask.DFS_CHANNEL; 1101 } 1102 mWifiChip.enableStaChannelForPeerNetwork(halChannelCategoryEnableFlag); 1103 return true; 1104 } catch (RemoteException e) { 1105 handleRemoteException(e, methodStr); 1106 } catch (ServiceSpecificException e) { 1107 handleServiceSpecificException(e, methodStr); 1108 } 1109 return false; 1110 } 1111 } 1112 1113 private class ChipEventCallback extends IWifiChipEventCallback.Stub { 1114 @Override onChipReconfigured(int modeId)1115 public void onChipReconfigured(int modeId) throws RemoteException { 1116 if (mFrameworkCallback == null) return; 1117 mFrameworkCallback.onChipReconfigured(modeId); 1118 } 1119 1120 @Override onChipReconfigureFailure(int statusCode)1121 public void onChipReconfigureFailure(int statusCode) { 1122 if (mFrameworkCallback == null) return; 1123 // TODO: convert to framework status code once WifiHalAidlImpl exists 1124 mFrameworkCallback.onChipReconfigureFailure(statusCode); 1125 } 1126 1127 @Override onIfaceAdded(int type, String name)1128 public void onIfaceAdded(int type, String name) { 1129 if (mFrameworkCallback == null) return; 1130 mFrameworkCallback.onIfaceAdded(halToFrameworkIfaceType(type), name); 1131 } 1132 1133 @Override onIfaceRemoved(int type, String name)1134 public void onIfaceRemoved(int type, String name) { 1135 if (mFrameworkCallback == null) return; 1136 mFrameworkCallback.onIfaceRemoved(halToFrameworkIfaceType(type), name); 1137 } 1138 1139 @Override onDebugRingBufferDataAvailable(WifiDebugRingBufferStatus status, byte[] data)1140 public void onDebugRingBufferDataAvailable(WifiDebugRingBufferStatus status, byte[] data) { 1141 if (mFrameworkCallback == null) return; 1142 try { 1143 mFrameworkCallback.onDebugRingBufferDataAvailable( 1144 halToFrameworkRingBufferStatus(status), data); 1145 } catch (IllegalArgumentException e) { 1146 handleIllegalArgumentException(e, "onDebugRingBufferDataAvailable"); 1147 } 1148 } 1149 1150 @Override onDebugErrorAlert(int errorCode, byte[] debugData)1151 public void onDebugErrorAlert(int errorCode, byte[] debugData) { 1152 if (mFrameworkCallback == null) return; 1153 mFrameworkCallback.onDebugErrorAlert(errorCode, debugData); 1154 } 1155 1156 @Override onRadioModeChange(RadioModeInfo[] radioModeInfoList)1157 public void onRadioModeChange(RadioModeInfo[] radioModeInfoList) { 1158 if (mFrameworkCallback == null) return; 1159 List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>(); 1160 for (RadioModeInfo radioInfo : radioModeInfoList) { 1161 List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>(); 1162 for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) { 1163 frameworkIfaceInfos.add( 1164 new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel)); 1165 } 1166 frameworkRadioModeInfos.add( 1167 new WifiChip.RadioModeInfo( 1168 radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos)); 1169 } 1170 mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos); 1171 } 1172 1173 @Override getInterfaceHash()1174 public String getInterfaceHash() { 1175 return IWifiChipEventCallback.HASH; 1176 } 1177 1178 @Override getInterfaceVersion()1179 public int getInterfaceVersion() { 1180 return IWifiChipEventCallback.VERSION; 1181 } 1182 } 1183 1184 1185 // Utilities 1186 halToFrameworkIfaceConcurrencyType(int type)1187 private static @WifiChip.IfaceConcurrencyType int halToFrameworkIfaceConcurrencyType(int type) { 1188 switch (type) { 1189 case IfaceConcurrencyType.STA: 1190 return WifiChip.IFACE_CONCURRENCY_TYPE_STA; 1191 case IfaceConcurrencyType.AP: 1192 return WifiChip.IFACE_CONCURRENCY_TYPE_AP; 1193 case IfaceConcurrencyType.AP_BRIDGED: 1194 return WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED; 1195 case IfaceConcurrencyType.P2P: 1196 return WifiChip.IFACE_CONCURRENCY_TYPE_P2P; 1197 case IfaceConcurrencyType.NAN_IFACE: 1198 return WifiChip.IFACE_CONCURRENCY_TYPE_NAN; 1199 default: 1200 Log.e(TAG, "Invalid IfaceConcurrencyType received: " + type); 1201 return -1; 1202 } 1203 } 1204 halToFrameworkIfaceType(int type)1205 private static @WifiChip.IfaceType int halToFrameworkIfaceType(int type) { 1206 switch (type) { 1207 case IfaceType.STA: 1208 return WifiChip.IFACE_TYPE_STA; 1209 case IfaceType.AP: 1210 return WifiChip.IFACE_TYPE_AP; 1211 case IfaceType.P2P: 1212 return WifiChip.IFACE_TYPE_P2P; 1213 case IfaceType.NAN_IFACE: 1214 return WifiChip.IFACE_TYPE_NAN; 1215 default: 1216 Log.e(TAG, "Invalid IfaceType received: " + type); 1217 return -1; 1218 } 1219 } 1220 halToFrameworkRingBufferStatusList( WifiDebugRingBufferStatus[] ringBuffers)1221 private static @Nullable List<WifiNative.RingBufferStatus> halToFrameworkRingBufferStatusList( 1222 WifiDebugRingBufferStatus[] ringBuffers) throws IllegalArgumentException { 1223 if (ringBuffers == null) return null; 1224 List<WifiNative.RingBufferStatus> ans = new ArrayList<>(); 1225 for (WifiDebugRingBufferStatus b : ringBuffers) { 1226 ans.add(halToFrameworkRingBufferStatus(b)); 1227 } 1228 return ans; 1229 } 1230 halToFrameworkRingBufferStatus( WifiDebugRingBufferStatus h)1231 private static WifiNative.RingBufferStatus halToFrameworkRingBufferStatus( 1232 WifiDebugRingBufferStatus h) throws IllegalArgumentException { 1233 WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus(); 1234 ans.name = h.ringName; 1235 ans.flag = halToFrameworkRingBufferFlags(h.flags); 1236 ans.ringBufferId = h.ringId; 1237 ans.ringBufferByteSize = h.sizeInBytes; 1238 ans.verboseLevel = h.verboseLevel; 1239 // Remaining fields are unavailable 1240 // writtenBytes; 1241 // readBytes; 1242 // writtenRecords; 1243 return ans; 1244 } 1245 halToFrameworkRingBufferFlags(int wifiDebugRingBufferFlag)1246 private static int halToFrameworkRingBufferFlags(int wifiDebugRingBufferFlag) 1247 throws IllegalArgumentException { 1248 BitMask checkoff = new BitMask(wifiDebugRingBufferFlag); 1249 int flags = 0; 1250 if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) { 1251 flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES; 1252 } 1253 if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) { 1254 flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES; 1255 } 1256 if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) { 1257 flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES; 1258 } 1259 if (checkoff.value != 0) { 1260 throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value); 1261 } 1262 return flags; 1263 } 1264 halToFrameworkWakeReasons( WifiDebugHostWakeReasonStats h)1265 private static WlanWakeReasonAndCounts halToFrameworkWakeReasons( 1266 WifiDebugHostWakeReasonStats h) { 1267 if (h == null) return null; 1268 WlanWakeReasonAndCounts ans = new WlanWakeReasonAndCounts(); 1269 ans.totalCmdEventWake = h.totalCmdEventWakeCnt; 1270 ans.totalDriverFwLocalWake = h.totalDriverFwLocalWakeCnt; 1271 ans.totalRxDataWake = h.totalRxPacketWakeCnt; 1272 ans.rxUnicast = h.rxPktWakeDetails.rxUnicastCnt; 1273 ans.rxMulticast = h.rxPktWakeDetails.rxMulticastCnt; 1274 ans.rxBroadcast = h.rxPktWakeDetails.rxBroadcastCnt; 1275 ans.icmp = h.rxIcmpPkWakeDetails.icmpPkt; 1276 ans.icmp6 = h.rxIcmpPkWakeDetails.icmp6Pkt; 1277 ans.icmp6Ra = h.rxIcmpPkWakeDetails.icmp6Ra; 1278 ans.icmp6Na = h.rxIcmpPkWakeDetails.icmp6Na; 1279 ans.icmp6Ns = h.rxIcmpPkWakeDetails.icmp6Ns; 1280 ans.ipv4RxMulticast = h.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt; 1281 ans.ipv6Multicast = h.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt; 1282 ans.otherRxMulticast = h.rxMulticastPkWakeDetails.otherRxMulticastAddrCnt; 1283 ans.cmdEventWakeCntArray = h.cmdEventWakeCntPerType; 1284 ans.driverFWLocalWakeCntArray = h.driverFwLocalWakeCntPerType; 1285 return ans; 1286 } 1287 frameworkToHalMultiStaUseCase(@ifiNative.MultiStaUseCase int useCase)1288 private static byte frameworkToHalMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) 1289 throws IllegalArgumentException { 1290 switch (useCase) { 1291 case WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY: 1292 return MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY; 1293 case WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED: 1294 return MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED; 1295 default: 1296 throw new IllegalArgumentException("Invalid use case " + useCase); 1297 } 1298 } 1299 1300 private static @NonNull android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] frameworkToHalCoexUnsafeChannels( @onNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels)1301 frameworkToHalCoexUnsafeChannels( 1302 @NonNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels) { 1303 final ArrayList<android.hardware.wifi.IWifiChip.CoexUnsafeChannel> halList = 1304 new ArrayList<>(); 1305 if (!SdkLevel.isAtLeastS()) { 1306 return new android.hardware.wifi.IWifiChip.CoexUnsafeChannel[0]; 1307 } 1308 for (android.net.wifi.CoexUnsafeChannel frameworkUnsafeChannel : frameworkUnsafeChannels) { 1309 final android.hardware.wifi.IWifiChip.CoexUnsafeChannel halUnsafeChannel = 1310 new android.hardware.wifi.IWifiChip.CoexUnsafeChannel(); 1311 switch (frameworkUnsafeChannel.getBand()) { 1312 case (WifiScanner.WIFI_BAND_24_GHZ): 1313 halUnsafeChannel.band = WifiBand.BAND_24GHZ; 1314 break; 1315 case (WifiScanner.WIFI_BAND_5_GHZ): 1316 halUnsafeChannel.band = WifiBand.BAND_5GHZ; 1317 break; 1318 case (WifiScanner.WIFI_BAND_6_GHZ): 1319 halUnsafeChannel.band = WifiBand.BAND_6GHZ; 1320 break; 1321 case (WifiScanner.WIFI_BAND_60_GHZ): 1322 halUnsafeChannel.band = WifiBand.BAND_60GHZ; 1323 break; 1324 default: 1325 Log.e(TAG, "Tried to set unsafe channel with unknown band: " 1326 + frameworkUnsafeChannel.getBand()); 1327 continue; 1328 } 1329 halUnsafeChannel.channel = frameworkUnsafeChannel.getChannel(); 1330 final int powerCapDbm = frameworkUnsafeChannel.getPowerCapDbm(); 1331 if (powerCapDbm != POWER_CAP_NONE) { 1332 halUnsafeChannel.powerCapDbm = powerCapDbm; 1333 } else { 1334 halUnsafeChannel.powerCapDbm = 1335 android.hardware.wifi.IWifiChip.NO_POWER_CAP_CONSTANT; 1336 } 1337 halList.add(halUnsafeChannel); 1338 } 1339 1340 android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] halArray = 1341 new android.hardware.wifi.IWifiChip.CoexUnsafeChannel[halList.size()]; 1342 for (int i = 0; i < halList.size(); i++) { 1343 halArray[i] = halList.get(i); 1344 } 1345 return halArray; 1346 } 1347 frameworkToHalCoexRestrictions( @ifiManager.CoexRestriction int restrictions)1348 private static int frameworkToHalCoexRestrictions( 1349 @WifiManager.CoexRestriction int restrictions) { 1350 int halRestrictions = 0; 1351 if (!SdkLevel.isAtLeastS()) { 1352 return halRestrictions; 1353 } 1354 if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) { 1355 halRestrictions |= CoexRestriction.WIFI_DIRECT; 1356 } 1357 if ((restrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) { 1358 halRestrictions |= CoexRestriction.SOFTAP; 1359 } 1360 if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) { 1361 halRestrictions |= CoexRestriction.WIFI_AWARE; 1362 } 1363 return halRestrictions; 1364 } 1365 1366 /** 1367 * Check if we need to backoff wifi Tx power due to SAR requirements. 1368 */ sarPowerBackoffRequired(SarInfo sarInfo)1369 private static boolean sarPowerBackoffRequired(SarInfo sarInfo) { 1370 if (sarInfo.sarSapSupported && sarInfo.isWifiSapEnabled) { 1371 return true; 1372 } 1373 if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) { 1374 return true; 1375 } 1376 return false; 1377 } 1378 1379 /** 1380 * Maps the information in the SarInfo instance to a TxPowerScenario. 1381 * If SAR SoftAP input is supported, we make these assumptions: 1382 * - All voice calls are treated as if device is near the head. 1383 * - SoftAP scenario is treated as if device is near the body. 1384 * If SoftAP is not supported, the only valid scenario is when a voice call is ongoing. 1385 */ frameworkToHalTxPowerScenario(SarInfo sarInfo)1386 private static int frameworkToHalTxPowerScenario(SarInfo sarInfo) 1387 throws IllegalArgumentException { 1388 if (sarInfo.sarSapSupported && sarInfo.sarVoiceCallSupported) { 1389 if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) { 1390 return TxPowerScenario.ON_HEAD_CELL_ON; 1391 } else if (sarInfo.isWifiSapEnabled) { 1392 return TxPowerScenario.ON_BODY_CELL_ON; 1393 } else { 1394 throw new IllegalArgumentException("bad scenario: no voice call/softAP active"); 1395 } 1396 } else if (sarInfo.sarVoiceCallSupported) { 1397 if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) { 1398 return TxPowerScenario.VOICE_CALL; 1399 } else { 1400 throw new IllegalArgumentException("bad scenario: voice call not active"); 1401 } 1402 } else { 1403 throw new IllegalArgumentException("Invalid case: voice call not supported"); 1404 } 1405 } 1406 frameworkToHalWifiBand(int frameworkBand)1407 private static int frameworkToHalWifiBand(int frameworkBand) throws IllegalArgumentException { 1408 switch (frameworkBand) { 1409 case WifiScanner.WIFI_BAND_UNSPECIFIED: 1410 return WifiBand.BAND_UNSPECIFIED; 1411 case WifiScanner.WIFI_BAND_24_GHZ: 1412 return WifiBand.BAND_24GHZ; 1413 case WifiScanner.WIFI_BAND_5_GHZ: 1414 return WifiBand.BAND_5GHZ; 1415 case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: 1416 return WifiBand.BAND_5GHZ_DFS; 1417 case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS: 1418 return WifiBand.BAND_5GHZ_WITH_DFS; 1419 case WifiScanner.WIFI_BAND_BOTH: 1420 return WifiBand.BAND_24GHZ_5GHZ; 1421 case WifiScanner.WIFI_BAND_BOTH_WITH_DFS: 1422 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS; 1423 case WifiScanner.WIFI_BAND_6_GHZ: 1424 return WifiBand.BAND_6GHZ; 1425 case WifiScanner.WIFI_BAND_24_5_6_GHZ: 1426 return WifiBand.BAND_24GHZ_5GHZ_6GHZ; 1427 case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ: 1428 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ; 1429 case WifiScanner.WIFI_BAND_60_GHZ: 1430 return WifiBand.BAND_60GHZ; 1431 case WifiScanner.WIFI_BAND_24_5_6_60_GHZ: 1432 return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ; 1433 case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ: 1434 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ; 1435 case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS: 1436 default: 1437 throw new IllegalArgumentException("bad band " + frameworkBand); 1438 } 1439 } 1440 frameworkToHalIfaceMode(@ifiAvailableChannel.OpMode int mode)1441 private static int frameworkToHalIfaceMode(@WifiAvailableChannel.OpMode int mode) { 1442 int halMode = 0; 1443 if ((mode & WifiAvailableChannel.OP_MODE_STA) != 0) { 1444 halMode |= WifiIfaceMode.IFACE_MODE_STA; 1445 } 1446 if ((mode & WifiAvailableChannel.OP_MODE_SAP) != 0) { 1447 halMode |= WifiIfaceMode.IFACE_MODE_SOFTAP; 1448 } 1449 if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI) != 0) { 1450 halMode |= WifiIfaceMode.IFACE_MODE_P2P_CLIENT; 1451 } 1452 if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO) != 0) { 1453 halMode |= WifiIfaceMode.IFACE_MODE_P2P_GO; 1454 } 1455 if ((mode & WifiAvailableChannel.OP_MODE_WIFI_AWARE) != 0) { 1456 halMode |= WifiIfaceMode.IFACE_MODE_NAN; 1457 } 1458 if ((mode & WifiAvailableChannel.OP_MODE_TDLS) != 0) { 1459 halMode |= WifiIfaceMode.IFACE_MODE_TDLS; 1460 } 1461 return halMode; 1462 } 1463 halToFrameworkIfaceMode(int halMode)1464 private static @WifiAvailableChannel.OpMode int halToFrameworkIfaceMode(int halMode) { 1465 int mode = 0; 1466 if ((halMode & WifiIfaceMode.IFACE_MODE_STA) != 0) { 1467 mode |= WifiAvailableChannel.OP_MODE_STA; 1468 } 1469 if ((halMode & WifiIfaceMode.IFACE_MODE_SOFTAP) != 0) { 1470 mode |= WifiAvailableChannel.OP_MODE_SAP; 1471 } 1472 if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_CLIENT) != 0) { 1473 mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI; 1474 } 1475 if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_GO) != 0) { 1476 mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO; 1477 } 1478 if ((halMode & WifiIfaceMode.IFACE_MODE_NAN) != 0) { 1479 mode |= WifiAvailableChannel.OP_MODE_WIFI_AWARE; 1480 } 1481 if ((halMode & WifiIfaceMode.IFACE_MODE_TDLS) != 0) { 1482 mode |= WifiAvailableChannel.OP_MODE_TDLS; 1483 } 1484 return mode; 1485 } 1486 frameworkToHalUsableFilter(@ifiAvailableChannel.Filter int filter)1487 private static int frameworkToHalUsableFilter(@WifiAvailableChannel.Filter int filter) { 1488 int halFilter = 0; // O implies no additional filter other than regulatory (default) 1489 if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) { 1490 halFilter |= UsableChannelFilter.CONCURRENCY; 1491 } 1492 if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) { 1493 halFilter |= UsableChannelFilter.CELLULAR_COEXISTENCE; 1494 } 1495 if ((filter & WifiAvailableChannel.FILTER_NAN_INSTANT_MODE) != 0) { 1496 halFilter |= UsableChannelFilter.NAN_INSTANT_MODE; 1497 } 1498 1499 return halFilter; 1500 } 1501 bitmapContains(long bitmap, long expectedBit)1502 private static boolean bitmapContains(long bitmap, long expectedBit) { 1503 return (bitmap & expectedBit) != 0; 1504 } 1505 1506 @VisibleForTesting halToFrameworkChipFeatureSet(long halFeatureSet)1507 protected static long halToFrameworkChipFeatureSet(long halFeatureSet) { 1508 long features = 0; 1509 if (bitmapContains(halFeatureSet, FeatureSetMask.SET_TX_POWER_LIMIT)) { 1510 features |= WifiManager.WIFI_FEATURE_TX_POWER_LIMIT; 1511 } 1512 if (bitmapContains(halFeatureSet, FeatureSetMask.D2D_RTT)) { 1513 features |= WifiManager.WIFI_FEATURE_D2D_RTT; 1514 } 1515 if (bitmapContains(halFeatureSet, FeatureSetMask.D2AP_RTT)) { 1516 features |= WifiManager.WIFI_FEATURE_D2AP_RTT; 1517 } 1518 if (bitmapContains(halFeatureSet, FeatureSetMask.SET_LATENCY_MODE)) { 1519 features |= WifiManager.WIFI_FEATURE_LOW_LATENCY; 1520 } 1521 if (bitmapContains(halFeatureSet, FeatureSetMask.P2P_RAND_MAC)) { 1522 features |= WifiManager.WIFI_FEATURE_P2P_RAND_MAC; 1523 } 1524 if (bitmapContains(halFeatureSet, FeatureSetMask.WIGIG)) { 1525 features |= WifiManager.WIFI_FEATURE_INFRA_60G; 1526 } 1527 if (bitmapContains(halFeatureSet, FeatureSetMask.T2LM_NEGOTIATION)) { 1528 features |= WifiManager.WIFI_FEATURE_T2LM_NEGOTIATION; 1529 } 1530 return features; 1531 } 1532 halToFrameworkWifiBand(int halBand)1533 private static int halToFrameworkWifiBand(int halBand) { 1534 int frameworkBand = 0; 1535 if (bitmapContains(halBand, WifiBand.BAND_24GHZ)) { 1536 frameworkBand |= WifiScanner.WIFI_BAND_24_GHZ; 1537 } 1538 if (bitmapContains(halBand, WifiBand.BAND_5GHZ)) { 1539 frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ; 1540 } 1541 if (bitmapContains(halBand, WifiBand.BAND_5GHZ_DFS)) { 1542 frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY; 1543 } 1544 if (bitmapContains(halBand, WifiBand.BAND_6GHZ)) { 1545 frameworkBand |= WifiScanner.WIFI_BAND_6_GHZ; 1546 } 1547 if (bitmapContains(halBand, WifiBand.BAND_60GHZ)) { 1548 frameworkBand |= WifiScanner.WIFI_BAND_60_GHZ; 1549 } 1550 return frameworkBand; 1551 } 1552 halToFrameworkAntennaMode(int mode)1553 private static @WifiChip.WifiAntennaMode int halToFrameworkAntennaMode(int mode) { 1554 switch (mode) { 1555 case WifiAntennaMode.WIFI_ANTENNA_MODE_UNSPECIFIED: 1556 return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED; 1557 case WifiAntennaMode.WIFI_ANTENNA_MODE_1X1: 1558 return WifiChip.WIFI_ANTENNA_MODE_1X1; 1559 case WifiAntennaMode.WIFI_ANTENNA_MODE_2X2: 1560 return WifiChip.WIFI_ANTENNA_MODE_2X2; 1561 case WifiAntennaMode.WIFI_ANTENNA_MODE_3X3: 1562 return WifiChip.WIFI_ANTENNA_MODE_3X3; 1563 case WifiAntennaMode.WIFI_ANTENNA_MODE_4X4: 1564 return WifiChip.WIFI_ANTENNA_MODE_4X4; 1565 default: 1566 Log.e(TAG, "Invalid WifiAntennaMode: " + mode); 1567 return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED; 1568 } 1569 } 1570 halToFrameworkChipModeList( android.hardware.wifi.IWifiChip.ChipMode[] halModes)1571 private static List<WifiChip.ChipMode> halToFrameworkChipModeList( 1572 android.hardware.wifi.IWifiChip.ChipMode[] halModes) { 1573 List<WifiChip.ChipMode> frameworkModes = new ArrayList<>(); 1574 for (android.hardware.wifi.IWifiChip.ChipMode halMode : halModes) { 1575 frameworkModes.add(halToFrameworkChipMode(halMode)); 1576 } 1577 return frameworkModes; 1578 } 1579 halToFrameworkChipMode( android.hardware.wifi.IWifiChip.ChipMode halMode)1580 private static WifiChip.ChipMode halToFrameworkChipMode( 1581 android.hardware.wifi.IWifiChip.ChipMode halMode) { 1582 List<WifiChip.ChipConcurrencyCombination> frameworkCombos = new ArrayList<>(); 1583 for (android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo : 1584 halMode.availableCombinations) { 1585 frameworkCombos.add(halToFrameworkChipConcurrencyCombination(halCombo)); 1586 } 1587 return new WifiChip.ChipMode(halMode.id, frameworkCombos); 1588 } 1589 halToFrameworkChipConcurrencyCombination( android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo)1590 private static WifiChip.ChipConcurrencyCombination halToFrameworkChipConcurrencyCombination( 1591 android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo) { 1592 List<WifiChip.ChipConcurrencyCombinationLimit> frameworkLimits = new ArrayList<>(); 1593 for (android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit : 1594 halCombo.limits) { 1595 frameworkLimits.add(halToFrameworkChipConcurrencyCombinationLimit(halLimit)); 1596 } 1597 return new WifiChip.ChipConcurrencyCombination(frameworkLimits); 1598 } 1599 1600 private static WifiChip.ChipConcurrencyCombinationLimit halToFrameworkChipConcurrencyCombinationLimit( android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit)1601 halToFrameworkChipConcurrencyCombinationLimit( 1602 android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit) { 1603 List<Integer> frameworkTypes = new ArrayList<>(); 1604 for (int halType : halLimit.types) { 1605 frameworkTypes.add(halToFrameworkIfaceConcurrencyType(halType)); 1606 } 1607 return new WifiChip.ChipConcurrencyCombinationLimit(halLimit.maxIfaces, frameworkTypes); 1608 } 1609 halToFrameworkRadioCombinations( WifiRadioCombination[] halCombos)1610 private static List<WifiChip.WifiRadioCombination> halToFrameworkRadioCombinations( 1611 WifiRadioCombination[] halCombos) { 1612 List<WifiChip.WifiRadioCombination> frameworkCombos = new ArrayList<>(); 1613 for (WifiRadioCombination combo : halCombos) { 1614 frameworkCombos.add(halToFrameworkRadioCombination(combo)); 1615 } 1616 return frameworkCombos; 1617 } 1618 halToFrameworkWifiChipCapabilities( WifiChipCapabilities halCapabilities)1619 private static WifiChip.WifiChipCapabilities halToFrameworkWifiChipCapabilities( 1620 WifiChipCapabilities halCapabilities) { 1621 return new WifiChip.WifiChipCapabilities(halCapabilities.maxMloAssociationLinkCount, 1622 halCapabilities.maxMloStrLinkCount, halCapabilities.maxConcurrentTdlsSessionCount); 1623 } 1624 halToFrameworkRadioCombination( WifiRadioCombination halCombo)1625 private static WifiChip.WifiRadioCombination halToFrameworkRadioCombination( 1626 WifiRadioCombination halCombo) { 1627 List<WifiChip.WifiRadioConfiguration> frameworkConfigs = new ArrayList<>(); 1628 for (WifiRadioConfiguration config : halCombo.radioConfigurations) { 1629 frameworkConfigs.add(halToFrameworkRadioConfiguration(config)); 1630 } 1631 return new WifiChip.WifiRadioCombination(frameworkConfigs); 1632 } 1633 halToFrameworkRadioConfiguration( WifiRadioConfiguration halConfig)1634 private static WifiChip.WifiRadioConfiguration halToFrameworkRadioConfiguration( 1635 WifiRadioConfiguration halConfig) { 1636 return new WifiChip.WifiRadioConfiguration(halToFrameworkWifiBand(halConfig.bandInfo), 1637 halToFrameworkAntennaMode(halConfig.antennaMode)); 1638 } 1639 checkIfaceAndLogFailure(String methodStr)1640 private boolean checkIfaceAndLogFailure(String methodStr) { 1641 if (mWifiChip == null) { 1642 Log.e(TAG, "Unable to call " + methodStr + " because iface is null."); 1643 return false; 1644 } 1645 return true; 1646 } 1647 handleRemoteException(RemoteException e, String methodStr)1648 private void handleRemoteException(RemoteException e, String methodStr) { 1649 mWifiChip = null; 1650 Log.e(TAG, methodStr + " failed with remote exception: " + e); 1651 } 1652 handleServiceSpecificException(ServiceSpecificException e, String methodStr)1653 private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) { 1654 Log.e(TAG, methodStr + " failed with service-specific exception: " + e); 1655 } 1656 handleIllegalArgumentException(IllegalArgumentException e, String methodStr)1657 private void handleIllegalArgumentException(IllegalArgumentException e, String methodStr) { 1658 Log.e(TAG, methodStr + " failed with illegal argument exception: " + e); 1659 } 1660 1661 /** 1662 * See comments for {@link IWifiChip#setMloMode(int)}. 1663 */ 1664 @Override setMloMode(@ifiManager.MloMode int mode)1665 public @WifiStatusCode int setMloMode(@WifiManager.MloMode int mode) { 1666 final String methodStr = "setMloMode"; 1667 @WifiStatusCode int errorCode = WifiStatusCode.ERROR_UNKNOWN; 1668 synchronized (mLock) { 1669 try { 1670 if (checkIfaceAndLogFailure(methodStr)) { 1671 mWifiChip.setMloMode(frameworkToAidlMloMode(mode)); 1672 errorCode = WifiStatusCode.SUCCESS; 1673 } 1674 } catch (RemoteException e) { 1675 handleRemoteException(e, methodStr); 1676 } catch (ServiceSpecificException e) { 1677 handleServiceSpecificException(e, methodStr); 1678 errorCode = e.errorCode; 1679 } catch (IllegalArgumentException e) { 1680 handleIllegalArgumentException(e, methodStr); 1681 errorCode = WifiStatusCode.ERROR_INVALID_ARGS; 1682 } 1683 return errorCode; 1684 } 1685 } 1686 frameworkToAidlMloMode( @ifiManager.MloMode int mode)1687 private @android.hardware.wifi.IWifiChip.ChipMloMode int frameworkToAidlMloMode( 1688 @WifiManager.MloMode int mode) { 1689 switch(mode) { 1690 case WifiManager.MLO_MODE_DEFAULT: 1691 return android.hardware.wifi.IWifiChip.ChipMloMode.DEFAULT; 1692 case WifiManager.MLO_MODE_LOW_LATENCY: 1693 return android.hardware.wifi.IWifiChip.ChipMloMode.LOW_LATENCY; 1694 case WifiManager.MLO_MODE_HIGH_THROUGHPUT: 1695 return android.hardware.wifi.IWifiChip.ChipMloMode.HIGH_THROUGHPUT; 1696 case WifiManager.MLO_MODE_LOW_POWER: 1697 return android.hardware.wifi.IWifiChip.ChipMloMode.LOW_POWER; 1698 default: 1699 throw new IllegalArgumentException("frameworkToAidlMloMode: Invalid mode: " + mode); 1700 } 1701 } 1702 } 1703