Connecting to 12.103.3.241:22... Could not connect to '**.***.*.**' (port 22): Connection failed.

本文介绍了解决网络连接问题的一种方法:通过将网络连接模式从NAT模式更改为桥接模式来解决问题。对于遇到类似问题的用户来说,可以尝试不同的网络配置以找到适合自己的解决方案。

看到网上许多解答,都没解决,发现网络连接模式配置成,NAT模式了,改成桥接模式就解决了.因人而异,不同方法都多试试



讲解下面的代码: 1 /* 2 * Copyright (C) 2012 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 * Changes from Qualcomm Innovation Center are provided under the following license: 17 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 18 * SPDX-License-Identifier: BSD-3-Clause-Clear 19 */ 20 21 /** 22 * Bluetooth A2DP StateMachine. There is one instance per remote device. 23 * - "Disconnected" and "Connected" are steady states. 24 * - "Connecting" and "Disconnecting" are transient states until the 25 * connection / disconnection is completed. 26 * 27 * 28 * (Disconnected) 29 * | ^ 30 * CONNECT | | DISCONNECTED 31 * V | 32 * (Connecting)<--->(Disconnecting) 33 * | ^ 34 * CONNECTED | | DISCONNECT 35 * V | 36 * (Connected) 37 * NOTES: 38 * - If state machine is in "Connecting" state and the remote device sends 39 * DISCONNECT request, the state machine transitions to "Disconnecting" state. 40 * - Similarly, if the state machine is in "Disconnecting" state and the remote device 41 * sends CONNECT request, the state machine transitions to "Connecting" state. 42 * 43 * DISCONNECT 44 * (Connecting) ---------------> (Disconnecting) 45 * <--------------- 46 * CONNECT 47 * 48 */ 49 50 package com.android.bluetooth.a2dp; 51 52 import static android.Manifest.permission.BLUETOOTH_CONNECT; 53 54 import android.bluetooth.BluetoothA2dp; 55 import android.bluetooth.BluetoothCodecConfig; 56 import android.bluetooth.BluetoothCodecStatus; 57 import android.bluetooth.BluetoothDevice; 58 import android.bluetooth.BluetoothProfile; 59 import android.content.Intent; 60 import android.os.Looper; 61 import android.os.Message; 62 import android.util.Log; 63 64 import com.android.bluetooth.BluetoothStatsLog; 65 import com.android.bluetooth.Utils; 66 import com.android.bluetooth.btservice.ProfileService; 67 import com.android.bluetooth.apm.ApmConstIntf; 68 import com.android.bluetooth.apm.DeviceProfileMapIntf; 69 import com.android.bluetooth.apm.MediaAudioIntf; 70 71 import com.android.internal.annotations.VisibleForTesting; 72 import com.android.internal.util.State; 73 import com.android.internal.util.StateMachine; 74 75 import java.io.FileDescriptor; 76 import java.io.PrintWriter; 77 import java.io.StringWriter; 78 import java.util.List; 79 import java.util.Scanner; 80 import java.lang.reflect.Method; 81 import android.os.SystemProperties; 82 import com.android.bluetooth.btservice.AdapterService; 83 84 final class A2dpStateMachine extends StateMachine { 85 private static final boolean DBG = true; 86 private static final String TAG = "A2dpStateMachine"; 87 88 static final int CONNECT = 1; 89 static final int DISCONNECT = 2; 90 @VisibleForTesting 91 static final int STACK_EVENT = 101; 92 private static final int CONNECT_TIMEOUT = 201; 93 94 // NOTE: the value is not "final" - it is modified in the unit tests 95 @VisibleForTesting 96 static int sConnectTimeoutMs = 30000; // 30s 97 98 private Disconnected mDisconnected; 99 private Connecting mConnecting; 100 private Disconnecting mDisconnecting; 101 private Connected mConnected; 102 private int mConnectionState = BluetoothProfile.STATE_DISCONNECTED; 103 private int mLastConnectionState = -1; 104 105 private A2dpService mA2dpService; 106 private A2dpNativeInterface mA2dpNativeInterface; 107 @VisibleForTesting 108 boolean mA2dpOffloadEnabled = false; 109 private final BluetoothDevice mDevice; 110 private boolean mIsPlaying = false; 111 private BluetoothCodecStatus mCodecStatus; 112 private boolean mCodecConfigUpdated = false; 113 114 A2dpStateMachine(BluetoothDevice device, A2dpService a2dpService, 115 A2dpNativeInterface a2dpNativeInterface, Looper looper) { 116 super(TAG, looper); 117 setDbg(DBG); 118 mDevice = device; 119 mCodecConfigUpdated = false; 120 mA2dpService = a2dpService; 121 mA2dpNativeInterface = a2dpNativeInterface; 122 123 mDisconnected = new Disconnected(); 124 mConnecting = new Connecting(); 125 mDisconnecting = new Disconnecting(); 126 mConnected = new Connected(); 127 128 addState(mDisconnected); 129 addState(mConnecting); 130 addState(mDisconnecting); 131 addState(mConnected); 132 mA2dpOffloadEnabled = mA2dpService.mA2dpOffloadEnabled; 133 134 setInitialState(mDisconnected); 135 } 136 137 static A2dpStateMachine make(BluetoothDevice device, A2dpService a2dpService, 138 A2dpNativeInterface a2dpNativeInterface, Looper looper) { 139 Log.i(TAG, "make for device " + device); 140 A2dpStateMachine a2dpSm = new A2dpStateMachine(device, a2dpService, a2dpNativeInterface, 141 looper); 142 a2dpSm.start(); 143 return a2dpSm; 144 } 145 146 public void doQuit() { 147 log("doQuit for device " + mDevice); 148 if (mIsPlaying) { 149 // Stop if auido is still playing 150 log("doQuit: stopped playing " + mDevice); 151 mIsPlaying = false; 152 mA2dpService.setAvrcpAudioState(BluetoothA2dp.STATE_NOT_PLAYING, mDevice); 153 broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, 154 BluetoothA2dp.STATE_PLAYING); 155 } 156 quitNow(); 157 } 158 159 public void cleanup() { 160 log("cleanup for device " + mDevice); 161 } 162 163 @VisibleForTesting 164 class Disconnected extends State { 165 @Override 166 public void enter() { 167 Message currentMessage = getCurrentMessage(); 168 Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + (currentMessage == null ? "null" 169 : messageWhatToString(currentMessage.what))); 170 mCodecConfigUpdated = false; 171 synchronized (this) { 172 mConnectionState = BluetoothProfile.STATE_DISCONNECTED; 173 } 174 removeDeferredMessages(DISCONNECT); 175 176 if (mLastConnectionState != -1) { 177 // Don&#39;t broadcast during startup 178 if (mIsPlaying) { 179 Log.i(TAG, "Disconnected: stopped playing: " + mDevice); 180 mIsPlaying = false; 181 mA2dpService.setAvrcpAudioState(BluetoothA2dp.STATE_NOT_PLAYING, mDevice); 182 broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, 183 BluetoothA2dp.STATE_PLAYING); 184 } 185 broadcastConnectionState(mConnectionState, mLastConnectionState); 186 AdapterService adapterService = AdapterService.getAdapterService(); 187 if (adapterService.isVendorIntfEnabled() && 188 adapterService.isTwsPlusDevice(mDevice)) { 189 mA2dpService.updateTwsChannelMode(BluetoothA2dp.STATE_NOT_PLAYING, mDevice); 190 } 191 } 192 } 193 194 @Override 195 public void exit() { 196 Message currentMessage = getCurrentMessage(); 197 log("Exit Disconnected(" + mDevice + "): " + (currentMessage == null ? "null" 198 : messageWhatToString(currentMessage.what))); 199 mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED; 200 } 201 202 @Override 203 public boolean processMessage(Message message) { 204 log("Disconnected process message(" + mDevice + "): " 205 + messageWhatToString(message.what)); 206 207 switch (message.what) { 208 case CONNECT: 209 Log.i(TAG, "Connecting to " + mDevice); 210 if (!mA2dpNativeInterface.connectA2dp(mDevice)) { 211 Log.e(TAG, "Disconnected: error connecting to " + mDevice); 212 break; 213 } 214 if (mA2dpService.okToConnect(mDevice, true)) { 215 transitionTo(mConnecting); 216 } else { 217 // Reject the request and stay in Disconnected state 218 Log.w(TAG, "Outgoing A2DP Connecting request rejected: " + mDevice); 219 } 220 break; 221 case DISCONNECT: 222 Log.w(TAG, "Disconnected: DISCONNECT ignored: " + mDevice); 223 break; 224 case STACK_EVENT: 225 A2dpStackEvent event = (A2dpStackEvent) message.obj; 226 log("Disconnected: stack event: " + event); 227 if (!mDevice.equals(event.device)) { 228 Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event); 229 } 230 switch (event.type) { 231 case A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: 232 processConnectionEvent(event.valueInt); 233 break; 234 case A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED: 235 processCodecConfigEvent(event.codecStatus); 236 break; 237 default: 238 Log.e(TAG, "Disconnected: ignoring stack event: " + event); 239 break; 240 } 241 break; 242 default: 243 return NOT_HANDLED; 244 } 245 return HANDLED; 246 } 247 248 // in Disconnected state 249 private void processConnectionEvent(int event) { 250 switch (event) { 251 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTED: 252 Log.w(TAG, "Ignore A2DP DISCONNECTED event: " + mDevice); 253 break; 254 case A2dpStackEvent.CONNECTION_STATE_CONNECTING: 255 if (mA2dpService.okToConnect(mDevice, false)) { 256 Log.i(TAG, "Incoming A2DP Connecting request accepted: " + mDevice); 257 transitionTo(mConnecting); 258 if (mA2dpService.isQtiLeAudioEnabled()) { 259 MediaAudioIntf mMediaAudio = MediaAudioIntf.get(); 260 mMediaAudio.autoConnect(mDevice); 261 } 262 } else { 263 // Reject the connection and stay in Disconnected state itself 264 Log.w(TAG, "Incoming A2DP Connecting request rejected: " + mDevice); 265 mA2dpNativeInterface.disconnectA2dp(mDevice); 266 } 267 break; 268 case A2dpStackEvent.CONNECTION_STATE_CONNECTED: 269 Log.w(TAG, "A2DP Connected from Disconnected state: " + mDevice); 270 if (mA2dpService.okToConnect(mDevice, false)) { 271 Log.i(TAG, "Incoming A2DP Connected request accepted: " + mDevice); 272 transitionTo(mConnected); 273 if (mA2dpService.isQtiLeAudioEnabled()) { 274 MediaAudioIntf mMediaAudio = MediaAudioIntf.get(); 275 mMediaAudio.autoConnect(mDevice); 276 } 277 } else { 278 // Reject the connection and stay in Disconnected state itself 279 Log.w(TAG, "Incoming A2DP Connected request rejected: " + mDevice); 280 mA2dpNativeInterface.disconnectA2dp(mDevice); 281 } 282 break; 283 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTING: 284 Log.w(TAG, "Ignore A2DP DISCONNECTING event: " + mDevice); 285 break; 286 default: 287 Log.e(TAG, "Incorrect event: " + event + " device: " + mDevice); 288 break; 289 } 290 } 291 } 292 293 @VisibleForTesting 294 class Connecting extends State { 295 @Override 296 public void enter() { 297 Message currentMessage = getCurrentMessage(); 298 Log.i(TAG, "Enter Connecting(" + mDevice + "): " + (currentMessage == null ? "null" 299 : messageWhatToString(currentMessage.what))); 300 sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); 301 synchronized (this) { 302 mConnectionState = BluetoothProfile.STATE_CONNECTING; 303 } 304 broadcastConnectionState(mConnectionState, mLastConnectionState); 305 } 306 307 @Override 308 public void exit() { 309 Message currentMessage = getCurrentMessage(); 310 log("Exit Connecting(" + mDevice + "): " + (currentMessage == null ? "null" 311 : messageWhatToString(currentMessage.what))); 312 mLastConnectionState = BluetoothProfile.STATE_CONNECTING; 313 removeMessages(CONNECT_TIMEOUT); 314 } 315 316 @Override 317 public boolean processMessage(Message message) { 318 log("Connecting process message(" + mDevice + "): " 319 + messageWhatToString(message.what)); 320 321 switch (message.what) { 322 case CONNECT: 323 deferMessage(message); 324 break; 325 case CONNECT_TIMEOUT: { 326 Log.w(TAG, "Connecting connection timeout: " + mDevice); 327 mA2dpNativeInterface.disconnectA2dp(mDevice); 328 A2dpStackEvent event = 329 new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); 330 event.device = mDevice; 331 event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; 332 sendMessage(STACK_EVENT, event); 333 break; 334 } 335 case DISCONNECT: 336 // Cancel connection 337 Log.i(TAG, "Connecting: connection canceled to " + mDevice); 338 mA2dpNativeInterface.disconnectA2dp(mDevice); 339 transitionTo(mDisconnected); 340 break; 341 case STACK_EVENT: 342 A2dpStackEvent event = (A2dpStackEvent) message.obj; 343 log("Connecting: stack event: " + event); 344 if (!mDevice.equals(event.device)) { 345 Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event); 346 } 347 switch (event.type) { 348 case A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: 349 processConnectionEvent(event.valueInt); 350 break; 351 case A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED: 352 processCodecConfigEvent(event.codecStatus); 353 break; 354 case A2dpStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED: 355 break; 356 default: 357 Log.e(TAG, "Connecting: ignoring stack event: " + event); 358 break; 359 } 360 break; 361 default: 362 return NOT_HANDLED; 363 } 364 return HANDLED; 365 } 366 367 // in Connecting state 368 private void processConnectionEvent(int event) { 369 switch (event) { 370 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTED: 371 Log.w(TAG, "Connecting device disconnected: " + mDevice); 372 transitionTo(mDisconnected); 373 break; 374 case A2dpStackEvent.CONNECTION_STATE_CONNECTED: 375 transitionTo(mConnected); 376 break; 377 case A2dpStackEvent.CONNECTION_STATE_CONNECTING: 378 // Ignored - probably an event that the outgoing connection was initiated 379 break; 380 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTING: 381 Log.w(TAG, "Connecting interrupted: device is disconnecting: " + mDevice); 382 transitionTo(mDisconnecting); 383 break; 384 default: 385 Log.e(TAG, "Incorrect event: " + event); 386 break; 387 } 388 } 389 } 390 391 @VisibleForTesting 392 class Disconnecting extends State { 393 @Override 394 public void enter() { 395 Message currentMessage = getCurrentMessage(); 396 Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " + (currentMessage == null ? "null" 397 : messageWhatToString(currentMessage.what))); 398 mCodecConfigUpdated = false; 399 sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs); 400 synchronized (this) { 401 mConnectionState = BluetoothProfile.STATE_DISCONNECTING; 402 } 403 broadcastConnectionState(mConnectionState, mLastConnectionState); 404 } 405 406 @Override 407 public void exit() { 408 Message currentMessage = getCurrentMessage(); 409 log("Exit Disconnecting(" + mDevice + "): " + (currentMessage == null ? "null" 410 : messageWhatToString(currentMessage.what))); 411 mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING; 412 removeMessages(CONNECT_TIMEOUT); 413 } 414 415 @Override 416 public boolean processMessage(Message message) { 417 log("Disconnecting process message(" + mDevice + "): " 418 + messageWhatToString(message.what)); 419 420 switch (message.what) { 421 case CONNECT: 422 deferMessage(message); 423 break; 424 case CONNECT_TIMEOUT: { 425 Log.w(TAG, "Disconnecting connection timeout: " + mDevice); 426 mA2dpNativeInterface.disconnectA2dp(mDevice); 427 A2dpStackEvent event = 428 new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); 429 event.device = mDevice; 430 event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; 431 sendMessage(STACK_EVENT, event); 432 break; 433 } 434 case DISCONNECT: 435 deferMessage(message); 436 break; 437 case STACK_EVENT: 438 A2dpStackEvent event = (A2dpStackEvent) message.obj; 439 log("Disconnecting: stack event: " + event); 440 if (!mDevice.equals(event.device)) { 441 Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event); 442 } 443 switch (event.type) { 444 case A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: 445 processConnectionEvent(event.valueInt); 446 break; 447 case A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED: 448 processCodecConfigEvent(event.codecStatus); 449 break; 450 case A2dpStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED: 451 default: 452 Log.e(TAG, "Disconnecting: ignoring stack event: " + event); 453 break; 454 } 455 break; 456 default: 457 return NOT_HANDLED; 458 } 459 return HANDLED; 460 } 461 462 // in Disconnecting state 463 private void processConnectionEvent(int event) { 464 switch (event) { 465 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTED: 466 Log.i(TAG, "Disconnected: " + mDevice); 467 transitionTo(mDisconnected); 468 break; 469 case A2dpStackEvent.CONNECTION_STATE_CONNECTED: 470 if (mA2dpService.okToConnect(mDevice, false)) { 471 Log.w(TAG, "Disconnecting interrupted: device is connected: " + mDevice); 472 transitionTo(mConnected); 473 if (mA2dpService.isQtiLeAudioEnabled()) { 474 MediaAudioIntf mMediaAudio = MediaAudioIntf.get(); 475 mMediaAudio.autoConnect(mDevice); 476 } 477 } else { 478 // Reject the connection and stay in Disconnecting state 479 Log.w(TAG, "Incoming A2DP Connected request rejected: " + mDevice); 480 mA2dpNativeInterface.disconnectA2dp(mDevice); 481 } 482 break; 483 case A2dpStackEvent.CONNECTION_STATE_CONNECTING: 484 if (mA2dpService.okToConnect(mDevice, false)) { 485 Log.i(TAG, "Disconnecting interrupted: try to reconnect: " + mDevice); 486 transitionTo(mConnecting); 487 if (mA2dpService.isQtiLeAudioEnabled()) { 488 MediaAudioIntf mMediaAudio = MediaAudioIntf.get(); 489 mMediaAudio.autoConnect(mDevice); 490 } 491 } else { 492 // Reject the connection and stay in Disconnecting state 493 Log.w(TAG, "Incoming A2DP Connecting request rejected: " + mDevice); 494 mA2dpNativeInterface.disconnectA2dp(mDevice); 495 } 496 break; 497 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTING: 498 // We are already disconnecting, do nothing 499 Log.i(TAG, " already disconnecting, do nothing "); 500 break; 501 default: 502 Log.e(TAG, "Incorrect event: " + event); 503 break; 504 } 505 } 506 } 507 508 @VisibleForTesting 509 class Connected extends State { 510 @Override 511 public void enter() { 512 Message currentMessage = getCurrentMessage(); 513 Log.i(TAG, "Enter Connected(" + mDevice + "): " + (currentMessage == null ? "null" 514 : messageWhatToString(currentMessage.what))); 515 synchronized (this) { 516 mConnectionState = BluetoothProfile.STATE_CONNECTED; 517 } 518 removeDeferredMessages(CONNECT); 519 DeviceProfileMapIntf dpm = DeviceProfileMapIntf.getDeviceProfileMapInstance(); 520 dpm.profileConnectionUpdate(mDevice, ApmConstIntf.AudioFeatures.MEDIA_AUDIO, 521 ApmConstIntf.AudioProfiles.A2DP, true); 522 // Each time a device connects, we want to re-check if it supports optional 523 // codecs (perhaps it&#39;s had a firmware update, etc.) and save that state if 524 // it differs from what we had saved before. 525 mA2dpService.updateOptionalCodecsSupport(mDevice); 526 broadcastConnectionState(mConnectionState, mLastConnectionState); 527 // Upon connected, the audio starts out as stopped 528 broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, 529 BluetoothA2dp.STATE_PLAYING); 530 } 531 532 @Override 533 public void exit() { 534 Message currentMessage = getCurrentMessage(); 535 log("Exit Connected(" + mDevice + "): " + (currentMessage == null ? "null" 536 : messageWhatToString(currentMessage.what))); 537 mLastConnectionState = BluetoothProfile.STATE_CONNECTED; 538 } 539 540 @Override 541 public boolean processMessage(Message message) { 542 log("Connected process message(" + mDevice + "): " + messageWhatToString(message.what)); 543 544 switch (message.what) { 545 case CONNECT: 546 Log.w(TAG, "Connected: CONNECT ignored: " + mDevice); 547 break; 548 case DISCONNECT: { 549 Log.i(TAG, "Disconnecting from " + mDevice); 550 if (!mA2dpNativeInterface.disconnectA2dp(mDevice)) { 551 // If error in the native stack, transition directly to Disconnected state. 552 Log.e(TAG, "Connected: error disconnecting from " + mDevice); 553 transitionTo(mDisconnected); 554 break; 555 } 556 transitionTo(mDisconnecting); 557 } 558 break; 559 case STACK_EVENT: 560 A2dpStackEvent event = (A2dpStackEvent) message.obj; 561 log("Connected: stack event: " + event); 562 if (!mDevice.equals(event.device)) { 563 Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event); 564 } 565 switch (event.type) { 566 case A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED: 567 processConnectionEvent(event.valueInt); 568 break; 569 case A2dpStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED: 570 processAudioStateEvent(event.valueInt); 571 break; 572 case A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED: 573 processCodecConfigEvent(event.codecStatus); 574 break; 575 default: 576 Log.e(TAG, "Connected: ignoring stack event: " + event); 577 break; 578 } 579 break; 580 default: 581 return NOT_HANDLED; 582 } 583 return HANDLED; 584 } 585 586 // in Connected state 587 private void processConnectionEvent(int event) { 588 switch (event) { 589 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTED: 590 Log.i(TAG, "Disconnected from " + mDevice); 591 transitionTo(mDisconnected); 592 break; 593 case A2dpStackEvent.CONNECTION_STATE_CONNECTED: 594 Log.w(TAG, "Ignore A2DP CONNECTED event: " + mDevice); 595 break; 596 case A2dpStackEvent.CONNECTION_STATE_CONNECTING: 597 Log.w(TAG, "Ignore A2DP CONNECTING event: " + mDevice); 598 break; 599 case A2dpStackEvent.CONNECTION_STATE_DISCONNECTING: 600 Log.i(TAG, "Disconnecting from " + mDevice); 601 transitionTo(mDisconnecting); 602 break; 603 default: 604 Log.e(TAG, "Connection State Device: " + mDevice + " bad event: " + event); 605 break; 606 } 607 } 608 609 // in Connected state 610 private void processAudioStateEvent(int state) { 611 Log.i(TAG, "Connected: processAudioStateEvent: state: " + state + "mIsPlaying: " + mIsPlaying); 612 switch (state) { 613 case A2dpStackEvent.AUDIO_STATE_STARTED: 614 synchronized (this) { 615 if (!mIsPlaying) { 616 Log.i(TAG, "Connected: started playing: " + mDevice); 617 mIsPlaying = true; 618 mA2dpService.setAvrcpAudioState(BluetoothA2dp.STATE_PLAYING, mDevice); 619 broadcastAudioState(BluetoothA2dp.STATE_PLAYING, 620 BluetoothA2dp.STATE_NOT_PLAYING); 621 Log.i(TAG,"state:AUDIO_STATE_STARTED"); 622 } 623 AdapterService adapterService = AdapterService.getAdapterService(); 624 if (adapterService.isVendorIntfEnabled() && 625 adapterService.isTwsPlusDevice(mDevice)) { 626 mA2dpService.updateTwsChannelMode(BluetoothA2dp.STATE_PLAYING, mDevice); 627 } 628 } 629 break; 630 case A2dpStackEvent.AUDIO_STATE_REMOTE_SUSPEND: 631 case A2dpStackEvent.AUDIO_STATE_STOPPED: 632 synchronized (this) { 633 if (mIsPlaying) { 634 Log.i(TAG, "Connected: stopped playing: " + mDevice); 635 mIsPlaying = false; 636 mA2dpService.setAvrcpAudioState(BluetoothA2dp.STATE_NOT_PLAYING, mDevice); 637 broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, 638 BluetoothA2dp.STATE_PLAYING); 639 mA2dpService.setGamingMode(mDevice, false); 640 } 641 } 642 break; 643 default: 644 Log.e(TAG, "Audio State Device: " + mDevice + " bad state: " + state); 645 break; 646 } 647 } 648 } 649 650 int getConnectionState() { 651 return mConnectionState; 652 } 653 654 BluetoothDevice getDevice() { 655 return mDevice; 656 } 657 658 boolean isConnected() { 659 synchronized (this) { 660 return (mConnectionState == BluetoothProfile.STATE_CONNECTED); 661 } 662 } 663 664 boolean isPlaying() { 665 synchronized (this) { 666 return mIsPlaying; 667 } 668 } 669 670 BluetoothCodecStatus getCodecStatus() { 671 synchronized (this) { 672 return mCodecStatus; 673 } 674 } 675 676 // NOTE: This event is processed in any state 677 @VisibleForTesting 678 void processCodecConfigEvent(BluetoothCodecStatus newCodecStatus) { 679 BluetoothCodecConfig prevCodecConfig = null; 680 BluetoothCodecStatus prevCodecStatus = mCodecStatus; 681 682 int new_codec_type = newCodecStatus.getCodecConfig().getCodecType(); 683 684 // Split A2dp will be enabled by default 685 boolean isSplitA2dpEnabled = true; 686 AdapterService adapterService = AdapterService.getAdapterService(); 687 Object objStreamAudioService = null; 688 689 if (adapterService != null){ 690 isSplitA2dpEnabled = adapterService.isSplitA2dpEnabled(); 691 Log.v(TAG,"isSplitA2dpEnabled: " + isSplitA2dpEnabled); 692 } else { 693 Log.e(TAG,"adapterService is null"); 694 } 695 696 Log.w(TAG,"processCodecConfigEvent: new_codec_type = " + new_codec_type); 697 698 if (isSplitA2dpEnabled) { 699 if (new_codec_type == BluetoothCodecConfig.SOURCE_QVA_CODEC_TYPE_MAX) { 700 if (adapterService.isVendorIntfEnabled() && 701 adapterService.isTwsPlusDevice(mDevice)) { 702 Log.d(TAG,"TWSP device streaming,not calling reconfig"); 703 mCodecStatus = newCodecStatus; 704 return; 705 } 706 mA2dpService.broadcastReconfigureA2dp(); 707 Log.w(TAG,"Split A2dp enabled rcfg send to Audio for codec max"); 708 return; 709 } 710 } 711 synchronized (this) { 712 if (mCodecStatus != null) { 713 prevCodecConfig = mCodecStatus.getCodecConfig(); 714 } 715 mCodecStatus = newCodecStatus; 716 } 717 if (DBG) { 718 Log.d(TAG, "A2DP Codec Config: " + prevCodecConfig + "->" 719 + newCodecStatus.getCodecConfig()); 720 for (BluetoothCodecConfig codecConfig : 721 newCodecStatus.getCodecsLocalCapabilities()) { 722 Log.d(TAG, "A2DP Codec Local Capability: " + codecConfig); 723 } 724 for (BluetoothCodecConfig codecConfig : 725 newCodecStatus.getCodecsSelectableCapabilities()) { 726 Log.d(TAG, "A2DP Codec Selectable Capability: " + codecConfig); 727 } 728 } 729 730 if (isConnected() && !sameSelectableCodec(prevCodecStatus, mCodecStatus)) { 731 // Remote selectable codec could be changed if codec config changed 732 // in connected state, we need to re-check optional codec status 733 // for this codec change event. 734 mA2dpService.updateOptionalCodecsSupport(mDevice); 735 } 736 Log.d(TAG, " mA2dpOffloadEnabled: " + mA2dpOffloadEnabled); 737 if (mA2dpOffloadEnabled) { 738 boolean update = false; 739 BluetoothCodecConfig newCodecConfig = mCodecStatus.getCodecConfig(); 740 if ((prevCodecConfig != null) 741 && (prevCodecConfig.getCodecType() != newCodecConfig.getCodecType())) { 742 Log.d(TAG, " previous codec is different from new codec "); 743 update = true; 744 } else if (!newCodecConfig.sameAudioFeedingParameters(prevCodecConfig)) { 745 Log.d(TAG, " codec config parameters mismatched from previous config "); 746 update = true; 747 } else if ((newCodecConfig.getCodecType() 748 == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) 749 && (prevCodecConfig != null) 750 && (prevCodecConfig.getCodecSpecific1() 751 != newCodecConfig.getCodecSpecific1())) { 752 Log.d(TAG, "LDAC: codec config parameters mismatched from previous config "); 753 update = true; 754 } else if (prevCodecStatus != null && 755 newCodecStatus.getCodecsSelectableCapabilities().size() != 756 prevCodecStatus.getCodecsSelectableCapabilities().size()){ 757 Log.d(TAG, " codec selectable caps mismatched from previous config "); 758 update = true; 759 } else if (!mCodecConfigUpdated) { 760 Log.d(TAG, " mCodecConfigUpdated is false, codecConfigUpdated is required"); 761 update = true; 762 } 763 764 if ((newCodecConfig.getCodecType() 765 == BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE)) { 766 Log.d(TAG, "processCodecConfigEvent, APTX ADAPTIVE: reset Low Latency mode "); 767 try { 768 Class streamAudioService = Class.forName("com.android.bluetooth.apm.StreamAudioService"); 769 Method method = streamAudioService.getDeclaredMethod("getStreamAudioService"); 770 objStreamAudioService = method.invoke(null); 771 if (objStreamAudioService != null) { 772 Log.d(TAG, " processCodecConfigEvent, objStreamAudioService not null:"); 773 } else { 774 Log.d(TAG, " processCodecConfigEvent, objStreamAudioService is null:"); 775 } 776 } catch (Exception ex) { 777 Log.w(TAG, ex); 778 } 779 try { 780 Class streamAudioService = 781 Class.forName("com.android.bluetooth.apm.StreamAudioService"); 782 Method method = streamAudioService.getDeclaredMethod("resetLowLatencyMode"); 783 if (objStreamAudioService != null) { 784 Log.d(TAG, " processCodecConfigEvent, invoke resetLowLatencyMode "); 785 method.invoke(objStreamAudioService); 786 } 787 } catch (Exception ex) { 788 Log.w(TAG, ex); 789 } 790 } 791 Log.d(TAG, " update: " + update); 792 if (update) { 793 mA2dpService.codecConfigUpdated(mDevice, mCodecStatus, false); 794 mCodecConfigUpdated = true; 795 } 796 return; 797 } 798 799 Log.d(TAG, " isSplitA2dpEnabled: " + isSplitA2dpEnabled); 800 if (!isSplitA2dpEnabled) { 801 boolean isUpdateRequired = false; 802 if ((prevCodecConfig != null) && (prevCodecConfig.getCodecType() != new_codec_type)) { 803 Log.d(TAG, "previous codec is differs from new codec"); 804 isUpdateRequired = true; 805 } else if (!newCodecStatus.getCodecConfig().sameAudioFeedingParameters(prevCodecConfig)) { 806 Log.d(TAG, "codec config parameters mismatched with previous config: "); 807 isUpdateRequired = true; 808 } else if ((newCodecStatus.getCodecConfig().getCodecType() 809 == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) 810 && (prevCodecConfig != null) 811 && (prevCodecConfig.getCodecSpecific1() 812 != newCodecStatus.getCodecConfig().getCodecSpecific1())) { 813 Log.d(TAG, "LDAC: codec config parameters mismatched with previous config: "); 814 isUpdateRequired = true; 815 } else if(!mCodecConfigUpdated) { 816 Log.d(TAG, " mCodecConfigUpdated is false, codecConfigUpdated is required "); 817 isUpdateRequired = true; 818 } 819 Log.d(TAG, "isUpdateRequired: " + isUpdateRequired); 820 //update MM only when previous and current codec config has been changed 821 // OR reconnection has happened 822 if (isUpdateRequired) { 823 mA2dpService.codecConfigUpdated(mDevice, mCodecStatus, false); 824 mCodecConfigUpdated = true; 825 } 826 } 827 } 828 829 // This method does not check for error conditon (newState == prevState) 830 private void broadcastConnectionState(int newState, int prevState) { 831 log("Connection state " + mDevice + ": " + profileStateToString(prevState) 832 + "->" + profileStateToString(newState)); 833 834 if(mA2dpService.isQtiLeAudioEnabled() || ApmConstIntf.getAospLeaEnabled()) { 835 mA2dpService.updateConnState(mDevice, newState); 836 } 837 838 if (!mA2dpService.isQtiLeAudioEnabled()) { 839 Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); 840 intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 841 intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 842 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); 843 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 844 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 845 mA2dpService.sendBroadcast(intent, BLUETOOTH_CONNECT, 846 Utils.getTempAllowlistBroadcastOptions()); 847 } 848 } 849 850 private void broadcastAudioState(int newState, int prevState) { 851 log("A2DP Playing state : device: " + mDevice + " State:" + audioStateToString(prevState) 852 + "->" + audioStateToString(newState)); 853 854 mA2dpService.updateStreamState(mDevice, newState); 855 856 if(mA2dpService.isQtiLeAudioEnabled()) { 857 return; 858 } 859 860 BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED, newState); 861 Intent intent = new Intent(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); 862 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); 863 intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 864 intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 865 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 866 mA2dpService.sendBroadcast(intent, BLUETOOTH_CONNECT, 867 Utils.getTempAllowlistBroadcastOptions()); 868 } 869 870 @Override 871 protected String getLogRecString(Message msg) { 872 StringBuilder builder = new StringBuilder(); 873 builder.append(messageWhatToString(msg.what)); 874 builder.append(": "); 875 builder.append("arg1=") 876 .append(msg.arg1) 877 .append(", arg2=") 878 .append(msg.arg2) 879 .append(", obj=") 880 .append(msg.obj); 881 return builder.toString(); 882 } 883 884 private static boolean sameSelectableCodec(BluetoothCodecStatus prevCodecStatus, 885 BluetoothCodecStatus newCodecStatus) { 886 if (prevCodecStatus == null || newCodecStatus == null) { 887 return false; 888 } 889 List<BluetoothCodecConfig> c1 = prevCodecStatus.getCodecsSelectableCapabilities(); 890 List<BluetoothCodecConfig> c2 = newCodecStatus.getCodecsSelectableCapabilities(); 891 if (c1 == null) { 892 return (c2 == null); 893 } 894 if (c2 == null) { 895 return false; 896 } 897 if (c1.size() != c2.size()) { 898 return false; 899 } 900 return c1.containsAll(c2); 901 } 902 903 private static String messageWhatToString(int what) { 904 switch (what) { 905 case CONNECT: 906 return "CONNECT"; 907 case DISCONNECT: 908 return "DISCONNECT"; 909 case STACK_EVENT: 910 return "STACK_EVENT"; 911 case CONNECT_TIMEOUT: 912 return "CONNECT_TIMEOUT"; 913 default: 914 break; 915 } 916 return Integer.toString(what); 917 } 918 919 private static String profileStateToString(int state) { 920 switch (state) { 921 case BluetoothProfile.STATE_DISCONNECTED: 922 return "DISCONNECTED"; 923 case BluetoothProfile.STATE_CONNECTING: 924 return "CONNECTING"; 925 case BluetoothProfile.STATE_CONNECTED: 926 return "CONNECTED"; 927 case BluetoothProfile.STATE_DISCONNECTING: 928 return "DISCONNECTING"; 929 default: 930 break; 931 } 932 return Integer.toString(state); 933 } 934 935 private static String audioStateToString(int state) { 936 switch (state) { 937 case BluetoothA2dp.STATE_PLAYING: 938 return "PLAYING"; 939 case BluetoothA2dp.STATE_NOT_PLAYING: 940 return "NOT_PLAYING"; 941 default: 942 break; 943 } 944 return Integer.toString(state); 945 } 946 947 public void dump(StringBuilder sb) { 948 ProfileService.println(sb, "mDevice: " + mDevice); 949 ProfileService.println(sb, " StateMachine: " + this.toString()); 950 ProfileService.println(sb, " mIsPlaying: " + mIsPlaying); 951 synchronized (this) { 952 if (mCodecStatus != null) { 953 ProfileService.println(sb, " mCodecConfig: " + mCodecStatus.getCodecConfig()); 954 } 955 } 956 // Dump the state machine logs 957 StringWriter stringWriter = new StringWriter(); 958 PrintWriter printWriter = new PrintWriter(stringWriter); 959 super.dump(new FileDescriptor(), printWriter, new String[]{}); 960 printWriter.flush(); 961 stringWriter.flush(); 962 ProfileService.println(sb, " StateMachineLog:"); 963 Scanner scanner = new Scanner(stringWriter.toString()); 964 while (scanner.hasNextLine()) { 965 String line = scanner.nextLine(); 966 ProfileService.println(sb, " " + line); 967 } 968 scanner.close(); 969 } 970 971 @Override 972 protected void log(String msg) { 973 if (DBG) { 974 super.log(msg); 975 } 976 } 977 }
08-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值