Android10 音频架构之耳麦插拔

xref: /frameworks/base/core/res/res/values/config.xml
<!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
28          icons in the status bar that are not notifications. -->
29     <string-array name="config_statusBarIcons">
30         <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item>
31         <item><xliff:g id="id">@string/status_bar_rotate</xliff:g></item>
32         <item><xliff:g id="id">@string/status_bar_headset</xliff:g></item>
33         <item><xliff:g id="id">@string/status_bar_data_saver</xliff:g></item>
34         <item><xliff:g id="id">@string/status_bar_ime</xliff:g></item>
35         <item><xliff:g id="id">@string/status_bar_sync_failing</xliff:g></item>
36         <item><xliff:g id="id">@string/status_bar_sync_active</xliff:g></item>
37         <item><xliff:g id="id">@string/status_bar_nfc</xliff:g></item>
38         <item><xliff:g id="id">@string/status_bar_tty</xliff:g></item>
39         <item><xliff:g id="id">@string/status_bar_speakerphone</xliff:g></item>
40         <item><xliff:g id="id">@string/status_bar_cdma_eri</xliff:g></item>
41         <item><xliff:g id="id">@string/status_bar_data_connection</xliff:g></item>
42         <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item>
43         <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item>
44         <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item>
45         <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item>
46         <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item>
47         <item><xliff:g id="id">@string/status_bar_vpn</xliff:g></item>
48         <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item>
49         <item><xliff:g id="id">@string/status_bar_camera</xliff:g></item>
50         <item><xliff:g id="id">@string/status_bar_microphone</xliff:g></item>
51         <item><xliff:g id="id">@string/status_bar_location</xliff:g></item>
52         <item><xliff:g id="id">@string/status_bar_mute</xliff:g></item>
53         <item><xliff:g id="id">@string/status_bar_volume</xliff:g></item>
54         <item><xliff:g id="id">@string/status_bar_zen</xliff:g></item>
55         <item><xliff:g id="id">@string/status_bar_ethernet</xliff:g></item>
56         <item><xliff:g id="id">@string/status_bar_wifi</xliff:g></item>
57         <item><xliff:g id="id">@string/status_bar_hotspot</xliff:g></item>
58         <item><xliff:g id="id">@string/status_bar_mobile</xliff:g></item>
59         <item><xliff:g id="id">@string/status_bar_airplane</xliff:g></item>
60         <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item>
61         <item><xliff:g id="id">@string/status_bar_sensors_off</xliff:g></item>
62     </string-array>
1. 确定耳机图标的位置
    通过status_bar_headsetconfig.xml里面确定耳机图标的位置。

xref: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
597      private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
598          @Override
599          public void onReceive(Context context, Intent intent) {
600              String action = intent.getAction();
601              switch (action) {
602                  case AudioManager.RINGER_MODE_CHANGED_ACTION:
603                  case AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION:
604                      updateVolumeZen();
605                      break;
606                  case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
607                      // Avoid rebroadcast because SysUI is direct boot aware.
608                      if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK,
609                              false)) {
610                          break;
611                      }
612                      updateSimState(intent);
613                      break;
614                  case TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED:
615                      updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
616                              TelecomManager.TTY_MODE_OFF));
617                      break;
618                  case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
619                  case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
620                  case Intent.ACTION_MANAGED_PROFILE_REMOVED:
621                      updateManagedProfile();
622                      break;
623                  case AudioManager.ACTION_HEADSET_PLUG:
624                      updateHeadsetPlug(intent);
625                      break;
626              }
627          }
628      };
 
563      private void updateHeadsetPlug(Intent intent) {
564          boolean connected = intent.getIntExtra("state", 0) != 0;
565          boolean hasMic = intent.getIntExtra("microphone", 0) != 0;
566          if (connected) {
567              String contentDescription = mContext.getString(hasMic
568                      ? R.string.accessibility_status_bar_headset
569                      : R.string.accessibility_status_bar_headphones);
570              mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.stat_sys_headset_mic
571                      : R.drawable.stat_sys_headset, contentDescription);
572              mIconController.setIconVisibility(mSlotHeadset, true);
573          } else {
574              mIconController.setIconVisibility(mSlotHeadset, false);
575          }
576      }
2.监听耳机插拔事件
    mIconController.setIconVisibility(mSlotHeadset, true);
    通过AudioManager.ACTION_HEADSET_PLUG监听是否插入耳机,如果监听到耳机插入则显示耳机图标。
3.调用流程
<bool name="config_useDevInputEventForAudioJack">false</bool>
config_useDevInputEventForAudioJack为false时使用uevent机制,为true时使用input子系统。
xref: /frameworks/native/services/inputflinger/InputReader.cpp    
286  void InputReader::loopOnce() {
287      int32_t oldGeneration;
288      int32_t timeoutMillis;
289      bool inputDevicesChanged = false;
290      std::vector<InputDeviceInfo> inputDevices;
291      { // acquire lock
292          AutoMutex _l(mLock);
293  
294          oldGeneration = mGeneration;
295          timeoutMillis = -1;
296  
297          uint32_t changes = mConfigurationChangesToRefresh;
298          if (changes) {
299              mConfigurationChangesToRefresh = 0;
300              timeoutMillis = 0;
301              refreshConfigurationLocked(changes);
302          } else if (mNextTimeout != LLONG_MAX) {
303              nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
304              timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
305          }
306      } // release lock
307  
308      size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
309  
310      { // acquire lock
311          AutoMutex _l(mLock);
312          mReaderIsAliveCondition.broadcast();
313  
314          if (count) {
315              processEventsLocked(mEventBuffer, count);
316          }
317  
318          if (mNextTimeout != LLONG_MAX) {
319              nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
320              if (now >= mNextTimeout) {
321  #if DEBUG_RAW_EVENTS
322                  ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
323  #endif
324                  mNextTimeout = LLONG_MAX;
325                  timeoutExpiredLocked(now);
326              }
327          }
328  
329          if (oldGeneration != mGeneration) {
330              inputDevicesChanged = true;
331              getInputDevicesLocked(inputDevices);
332          }
333      } // release lock
334  
335      // Send out a message that the describes the changed input devices.
336      if (inputDevicesChanged) {
337          mPolicy->notifyInputDevicesChanged(inputDevices);
338      }
339  
340      // Flush queued events out to the listener.
341      // This must happen outside of the lock because the listener could potentially call
342      // back into the InputReader's methods, such as getScanCodeState, or become blocked
343      // on another thread similarly waiting to acquire the InputReader lock thereby
344      // resulting in a deadlock.  This situation is actually quite plausible because the
345      // listener is actually the input dispatcher, which calls into the window manager,
346      // which occasionally calls into the input reader.
347      mQueuedListener->flush();
348  }
    如果有事件则调用processEventsLocked(mEventBuffer, count);进行处理,如果没有事件则休眠。
xref: /frameworks/native/services/inputflinger/InputReader.cpp
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
351      for (const RawEvent* rawEvent = rawEvents; count;) {
352          int32_t type = rawEvent->type;
353          size_t batchSize = 1;
354          if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
355              int32_t deviceId = rawEvent->deviceId;
356              while (batchSize < count) {
357                  if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
358                          || rawEvent[batchSize].deviceId != deviceId) {
359                      break;
360                  }
361                  batchSize += 1;
362              }
363  #if DEBUG_RAW_EVENTS
364              ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
365  #endif
366              processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
367          } else {
368              switch (rawEvent->type) {
369              case EventHubInterface::DEVICE_ADDED:
370                  addDeviceLocked(rawEvent->when, rawEvent->deviceId);
371                  break;
372              case EventHubInterface::DEVICE_REMOVED:
373                  removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
374                  break;
375              case EventHubInterface::FINISHED_DEVICE_SCAN:
376                  handleConfigurationChangedLocked(rawEvent->when);
377                  break;
378              default:
379                  ALOG_ASSERT(false); // can't happen
380                  break;
381              }
382          }
383          count -= batchSize;
384          rawEvent += batchSize;
385      }
386  }
xref: /frameworks/native/services/inputflinger/InputReader.cpp
522  void InputReader::processEventsForDeviceLocked(int32_t deviceId,
523          const RawEvent* rawEvents, size_t count) {
524      ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
525      if (deviceIndex < 0) {
526          ALOGW("Discarding event for unknown deviceId %d.", deviceId);
527          return;
528      }
529  
530      InputDevice* device = mDevices.valueAt(deviceIndex);
531      if (device->isIgnored()) {
532          //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
533          return;
534      }
535  
536      device->process(rawEvents, count);
537  }
538  
539  void InputReader::timeoutExpiredLocked(nsecs_t when) {
540      for (size_t i = 0; i < mDevices.size(); i++) {
541          InputDevice* device = mDevices.valueAt(i);
542          if (!device->isIgnored()) {
543              device->timeoutExpired(when);
544          }
545      }
546  }
​​​​​​​xref: /frameworks/native/services/inputflinger/InputReader.cpp
1132  void InputDevice::process(const RawEvent* rawEvents, size_t count) {
1133      // Process all of the events in order for each mapper.
1134      // We cannot simply ask each mapper to process them in bulk because mappers may
1135      // have side-effects that must be interleaved.  For example, joystick movement events and
1136      // gamepad button presses are handled by different mappers but they should be dispatched
1137      // in the order received.
1138      for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
1139  #if DEBUG_RAW_EVENTS
1140          ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
1141                  rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
1142                  rawEvent->when);
1143  #endif
1144  
1145          if (mDropUntilNextSync) {
1146              if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
1147                  mDropUntilNextSync = false;
1148  #if DEBUG_RAW_EVENTS
1149                  ALOGD("Recovered from input event buffer overrun.");
1150  #endif
1151              } else {
1152  #if DEBUG_RAW_EVENTS
1153                  ALOGD("Dropped input event while waiting for next input sync.");
1154  #endif
1155              }
1156          } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
1157              ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
1158              mDropUntilNextSync = true;
1159              reset(rawEvent->when);
1160          } else {
1161              for (InputMapper* mapper : mMappers) {
1162                  mapper->process(rawEvent);
1163              }
1164          }
1165          --count;
1166      }
1167  }
    mapper->process(rawEvent);最终调用到InputMapper的process函数。InputMapper是指SwitchInputMapper
xref: /frameworks/native/services/inputflinger/InputReader.cpp
2029  void SwitchInputMapper::process(const RawEvent* rawEvent) {
2030      switch (rawEvent->type) {
2031      case EV_SW:
2032          processSwitch(rawEvent->code, rawEvent->value);
2033          break;
2034  
2035      case EV_SYN:
2036          if (rawEvent->code == SYN_REPORT) {
2037              sync(rawEvent->when);
2038          }
2039      }
2040  }
2041  
2042  void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
2043      if (switchCode >= 0 && switchCode < 32) {
2044          if (switchValue) {
2045              mSwitchValues |= 1 << switchCode;
2046          } else {
2047              mSwitchValues &= ~(1 << switchCode);
2048          }
2049          mUpdatedSwitchMask |= 1 << switchCode;
2050      }
2051  }
异步事件处理
mSwitchValues |= 1 << switchCode;按下则记录switchCode值。
mSwitchValues &= ~(1 << switchCode);松开则清除switchCode值。
mUpdatedSwitchMask |= 1 << switchCode;将switchCode记录在mUpdatedSwitchMask里面。
xref: /frameworks/native/services/inputflinger/InputReader.cpp
2053  void SwitchInputMapper::sync(nsecs_t when) {
2054      if (mUpdatedSwitchMask) {
2055          uint32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask;
2056          NotifySwitchArgs args(mContext->getNextSequenceNum(), when, 0, updatedSwitchValues,
2057                  mUpdatedSwitchMask);
2058          getListener()->notifySwitch(&args);
2059  
2060          mUpdatedSwitchMask = 0;
2061      }
2062  }
同步事件处理
getListener()->notifySwitch(&args);最终调用InputDispatcher::notifySwitch
xref: /frameworks/native/services/inputflinger/InputDispatcher.cpp
2809  void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2810  #if DEBUG_INBOUND_EVENT_DETAILS
2811      ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
2812              "switchMask=0x%08x",
2813              args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
2814  #endif
2815  
2816      uint32_t policyFlags = args->policyFlags;
2817      policyFlags |= POLICY_FLAG_TRUSTED;
2818      mPolicy->notifySwitch(args->eventTime,
2819              args->switchValues, args->switchMask, policyFlags);
2820  }
    调用mPolicy->notifySwitch,最终调用NativeInputManager::notifySwitch
xref: /frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
692  void NativeInputManager::notifySwitch(nsecs_t when,
693          uint32_t switchValues, uint32_t switchMask, uint32_t /* policyFlags */) {
694  #if DEBUG_INPUT_DISPATCHER_POLICY
695      ALOGD("notifySwitch - when=%lld, switchValues=0x%08x, switchMask=0x%08x, policyFlags=0x%x",
696              when, switchValues, switchMask, policyFlags);
697  #endif
698      ATRACE_CALL();
699  
700      JNIEnv* env = jniEnv();
701  
702      env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySwitch,
703              when, switchValues, switchMask);
704      checkAndClearExceptionFromCallback(env, "notifySwitch");
705  }
    env->CallVoidMethod调用java中的同名函数
xref: /frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
1753      private void notifySwitch(long whenNanos, int switchValues, int switchMask) {
1754          if (DEBUG) {
1755              Slog.d(TAG, "notifySwitch: values=" + Integer.toHexString(switchValues)
1756                      + ", mask=" + Integer.toHexString(switchMask));
1757          }
1758  
1759          if ((switchMask & SW_LID_BIT) != 0) {
1760              final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0);
1761              mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
1762          }
1763  
1764          if ((switchMask & SW_CAMERA_LENS_COVER_BIT) != 0) {
1765              final boolean lensCovered = ((switchValues & SW_CAMERA_LENS_COVER_BIT) != 0);
1766              mWindowManagerCallbacks.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered);
1767          }
1768  
1769          if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) {
1770              mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
1771                      switchMask);
1772          }
1773  
1774          if ((switchMask & SW_TABLET_MODE_BIT) != 0) {
1775              SomeArgs args = SomeArgs.obtain();
1776              args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
1777              args.argi2 = (int) (whenNanos >> 32);
1778              args.arg1 = Boolean.valueOf((switchValues & SW_TABLET_MODE_BIT) != 0);
1779              mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,
1780                      args).sendToTarget();
1781          }
1782      }
    调用mWiredAccessoryCallbacks.notifyWiredAccessoryChanged。mUseDevInputEventForAudioJack来源于config.xml配置。
xref: /frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.java
137      @Override
138      public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask) {
139          if (LOG) {
140              Slog.v(TAG, "notifyWiredAccessoryChanged: when=" + whenNanos
141                      + " bits=" + switchCodeToString(switchValues, switchMask)
142                      + " mask=" + Integer.toHexString(switchMask));
143          }
144  
145          synchronized (mLock) {
146              int headset;
147              mSwitchValues = (mSwitchValues & ~switchMask) | switchValues;
148              switch (mSwitchValues &
149                      (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT)) {
150                  case 0:
151                      headset = 0;
152                      break;
153  
154                  case SW_HEADPHONE_INSERT_BIT:
155                      headset = BIT_HEADSET_NO_MIC;
156                      break;
157  
158                  case SW_LINEOUT_INSERT_BIT:
159                      headset = BIT_LINEOUT;
160                      break;
161  
162                  case SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT:
163                      headset = BIT_HEADSET;
164                      break;
165  
166                  case SW_MICROPHONE_INSERT_BIT:
167                      headset = BIT_HEADSET;
168                      break;
169  
170                  default:
171                      headset = 0;
172                      break;
173              }
174  
175              updateLocked(NAME_H2W,
176                      (mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) | headset);
177          }
178      }
    最终调用到WiredAccessoryManager类里面的notifyWiredAccessoryChanged方法。根据驱动程序的上传mSwitchValues值来确定headset。
xref: /frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.java​​​​​​​
199      private void updateLocked(String newName, int newState) {
200          // Retain only relevant bits
201          int headsetState = newState & SUPPORTED_HEADSETS;
202          int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
203          int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
204          int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT);
205          boolean h2wStateChange = true;
206          boolean usbStateChange = true;
207          if (LOG) {
208              Slog.v(TAG, "newName=" + newName
209                      + " newState=" + newState
210                      + " headsetState=" + headsetState
211                      + " prev headsetState=" + mHeadsetState);
212          }
213  
214          if (mHeadsetState == headsetState) {
215              Log.e(TAG, "No state change.");
216              return;
217          }
218  
219          // reject all suspect transitions: only accept state changes from:
220          // - a: 0 headset to 1 headset
221          // - b: 1 headset to 0 headset
222          if (h2w_headset == (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) {
223              Log.e(TAG, "Invalid combination, unsetting h2w flag");
224              h2wStateChange = false;
225          }
226          // - c: 0 usb headset to 1 usb headset
227          // - d: 1 usb headset to 0 usb headset
228          if (usb_headset_anlg == BIT_USB_HEADSET_ANLG && usb_headset_dgtl == BIT_USB_HEADSET_DGTL) {
229              Log.e(TAG, "Invalid combination, unsetting usb flag");
230              usbStateChange = false;
231          }
232          if (!h2wStateChange && !usbStateChange) {
233              Log.e(TAG, "invalid transition, returning ...");
234              return;
235          }
236  
237          mWakeLock.acquire();
238  
239          Log.i(TAG, "MSG_NEW_DEVICE_STATE");
240          Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
241                  mHeadsetState, "");
242          mHandler.sendMessage(msg);
243  
244          mHeadsetState = headsetState;
245      }
246  
247      private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
248          @Override
249          public void handleMessage(Message msg) {
250              switch (msg.what) {
251                  case MSG_NEW_DEVICE_STATE:
252                      setDevicesState(msg.arg1, msg.arg2, (String) msg.obj);
253                      mWakeLock.release();
254                      break;
255                  case MSG_SYSTEM_READY:
256                      onSystemReady();
257                      mWakeLock.release();
258                      break;
259              }
260          }
261      };
262  
263      private void setDevicesState(
264              int headsetState, int prevHeadsetState, String headsetName) {
265          synchronized (mLock) {
266              int allHeadsets = SUPPORTED_HEADSETS;
267              for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
268                  if ((curHeadset & allHeadsets) != 0) {
269                      setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
270                      allHeadsets &= ~curHeadset;
271                  }
272              }
273          }
274      }
275  
276      private void setDeviceStateLocked(int headset,
277              int headsetState, int prevHeadsetState, String headsetName) {
278          if ((headsetState & headset) != (prevHeadsetState & headset)) {
279              int outDevice = 0;
280              int inDevice = 0;
281              int state;
282  
283              if ((headsetState & headset) != 0) {
284                  state = 1;
285              } else {
286                  state = 0;
287              }
288  
289              if (headset == BIT_HEADSET) {
290                  outDevice = AudioManager.DEVICE_OUT_WIRED_HEADSET;
291                  inDevice = AudioManager.DEVICE_IN_WIRED_HEADSET;
292              } else if (headset == BIT_HEADSET_NO_MIC) {
293                  outDevice = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
294              } else if (headset == BIT_LINEOUT) {
295                  outDevice = AudioManager.DEVICE_OUT_LINE;
296              } else if (headset == BIT_USB_HEADSET_ANLG) {
297                  outDevice = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
298              } else if (headset == BIT_USB_HEADSET_DGTL) {
299                  outDevice = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
300              } else if (headset == BIT_HDMI_AUDIO) {
301                  outDevice = AudioManager.DEVICE_OUT_HDMI;
302              } else {
303                  Slog.e(TAG, "setDeviceState() invalid headset type: " + headset);
304                  return;
305              }
306  
307              if (LOG) {
308                  Slog.v(TAG, "headsetName: " + headsetName +
309                          (state == 1 ? " connected" : " disconnected"));
310              }
311  
312              if (outDevice != 0) {
313                  mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);
314              }
315              if (inDevice != 0) {
316                  mAudioManager.setWiredDeviceConnectionState(inDevice, state, "", headsetName);
317              }
318          }
319      }
    通过mAudioManager.setWiredDeviceConnectionState设置到mAudioManager
xref: /frameworks/base/media/java/android/media/AudioManager.java
4189      @UnsupportedAppUsage
4190      public void setWiredDeviceConnectionState(int type, int state, String address, String name) {
4191          final IAudioService service = getService();
4192          try {
4193              service.setWiredDeviceConnectionState(type, state, address, name,
4194                      mApplicationContext.getOpPackageName());
4195          } catch (RemoteException e) {
4196              throw e.rethrowFromSystemServer();
4197          }
4198      }
xref: /frameworks/base/services/core/java/com/android/server/audio/AudioService.java
4368      public void setWiredDeviceConnectionState(int type,
4369              @ConnectionState int state, String address, String name,
4370              String caller) {
4371          if (state != CONNECTION_STATE_CONNECTED
4372                  && state != CONNECTION_STATE_DISCONNECTED) {
4373              throw new IllegalArgumentException("Invalid state " + state);
4374          }
4375          mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
4376      }
xref: /frameworks/base/services/core/java/com/android/server/audio/AudioDeviceInventory.java
803      private void sendDeviceConnectionIntent(int device, int state, String address,
804                                              String deviceName) {
805          if (AudioService.DEBUG_DEVICES) {
806              Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device)
807                      + " state:0x" + Integer.toHexString(state) + " address:" + address
808                      + " name:" + deviceName + ");");
809          }
810          Intent intent = new Intent();
811  
812          switch(device) {
813              case AudioSystem.DEVICE_OUT_WIRED_HEADSET:
814                  intent.setAction(Intent.ACTION_HEADSET_PLUG);
815                  intent.putExtra("microphone", 1);
816                  break;
817              case AudioSystem.DEVICE_OUT_WIRED_HEADPHONE:
818              case AudioSystem.DEVICE_OUT_LINE:
819                  intent.setAction(Intent.ACTION_HEADSET_PLUG);
820                  intent.putExtra("microphone", 0);
821                  break;
822              case AudioSystem.DEVICE_OUT_USB_HEADSET:
823                  intent.setAction(Intent.ACTION_HEADSET_PLUG);
824                  intent.putExtra("microphone",
825                          AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_IN_USB_HEADSET, "")
826                                  == AudioSystem.DEVICE_STATE_AVAILABLE ? 1 : 0);
827                  break;
828              case AudioSystem.DEVICE_IN_USB_HEADSET:
829                  if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_USB_HEADSET, "")
830                          == AudioSystem.DEVICE_STATE_AVAILABLE) {
831                      intent.setAction(Intent.ACTION_HEADSET_PLUG);
832                      intent.putExtra("microphone", 1);
833                  } else {
834                      // do not send ACTION_HEADSET_PLUG when only the input side is seen as changing
835                      return;
836                  }
837                  break;
838              case AudioSystem.DEVICE_OUT_HDMI:
839              case AudioSystem.DEVICE_OUT_HDMI_ARC:
840                  configureHdmiPlugIntent(intent, state);
841                  break;
842          }
843  
844          if (intent.getAction() == null) {
845              return;
846          }
847  
848          intent.putExtra(CONNECT_INTENT_KEY_STATE, state);
849          intent.putExtra(CONNECT_INTENT_KEY_ADDRESS, address);
850          intent.putExtra(CONNECT_INTENT_KEY_PORT_NAME, deviceName);
851  
852          intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
853  
854          final long ident = Binder.clearCallingIdentity();
855          try {
856              ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_CURRENT);
857          } finally {
858              Binder.restoreCallingIdentity(ident);
859          }
860      }
    最终会调用到ActivityManager.broadcastStickyIntent把消息都广播发送出去。
4.声音通道的切换
xref: /frameworks/base/services/core/java/com/android/server/audio/AudioDeviceInventory.java
357      /*package*/ void onSetWiredDeviceConnectionState(
358                              AudioDeviceInventory.WiredDeviceConnectionState wdcs) {
359          AudioService.sDeviceLogger.log(new AudioServiceEvents.WiredDevConnectEvent(wdcs));
360  
361          synchronized (mConnectedDevices) {
362              if ((wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED)
363                      && ((wdcs.mType & DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG) != 0)) {
364                  mDeviceBroker.setBluetoothA2dpOnInt(true,
365                          "onSetWiredDeviceConnectionState state DISCONNECTED");
366              }
367  
368              if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED,
369                      wdcs.mType, wdcs.mAddress, wdcs.mName)) {
370                  // change of connection state failed, bailout
371                  return;
372              }
373              if (wdcs.mState != AudioService.CONNECTION_STATE_DISCONNECTED) {
374                  if ((wdcs.mType & DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG) != 0) {
375                      mDeviceBroker.setBluetoothA2dpOnInt(false,
376                              "onSetWiredDeviceConnectionState state not DISCONNECTED");
377                  }
378                  mDeviceBroker.checkMusicActive(wdcs.mType, wdcs.mCaller);
379              }
380              if (wdcs.mType == AudioSystem.DEVICE_OUT_HDMI) {
381                  mDeviceBroker.checkVolumeCecOnHdmiConnection(wdcs.mState, wdcs.mCaller);
382              }
383              sendDeviceConnectionIntent(wdcs.mType, wdcs.mState, wdcs.mAddress, wdcs.mName);
384              updateAudioRoutes(wdcs.mType, wdcs.mState);
385          }
386      }
    音频通道的处理在handleDeviceConnection方法里面,
xref: /frameworks/base/services/core/java/com/android/server/audio/AudioDeviceInventory.java
417      /*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
418              String deviceName) {
419          if (AudioService.DEBUG_DEVICES) {
420              Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:"
421                      + Integer.toHexString(device) + " address:" + address
422                      + " name:" + deviceName + ")");
423          }
424          synchronized (mConnectedDevices) {
425              final String deviceKey = DeviceInfo.makeDeviceListKey(device, address);
426              if (AudioService.DEBUG_DEVICES) {
427                  Slog.i(TAG, "deviceKey:" + deviceKey);
428              }
429              DeviceInfo di = mConnectedDevices.get(deviceKey);
430              boolean isConnected = di != null;
431              if (AudioService.DEBUG_DEVICES) {
432                  Slog.i(TAG, "deviceInfo:" + di + " is(already)Connected:" + isConnected);
433              }
434              if (connect && !isConnected) {
435                  final int res = AudioSystem.setDeviceConnectionState(device,
436                          AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
437                          AudioSystem.AUDIO_FORMAT_DEFAULT);
438                  if (res != AudioSystem.AUDIO_STATUS_OK) {
439                      Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device)
440                              + " due to command error " + res);
441                      return false;
442                  }
443                  mConnectedDevices.put(deviceKey, new DeviceInfo(
444                          device, deviceName, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
445                  mDeviceBroker.postAccessoryPlugMediaUnmute(device);
446                  return true;
447              } else if (!connect && isConnected) {
448                  AudioSystem.setDeviceConnectionState(device,
449                          AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName,
450                          AudioSystem.AUDIO_FORMAT_DEFAULT);
451                  // always remove even if disconnection failed
452                  mConnectedDevices.remove(deviceKey);
453                  return true;
454              }
455              Log.w(TAG, "handleDeviceConnection() failed, deviceKey=" + deviceKey
456                      + ", deviceSpec=" + di + ", connect=" + connect);
457          }
458          return false;
459      }
​​​​​​​xref: /frameworks/av/media/libaudioclient/AudioSystem.cpp
786  status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
787                                                 audio_policy_dev_state_t state,
788                                                 const char *device_address,
789                                                 const char *device_name,
790                                                 audio_format_t encodedFormat)
791  {
792      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
793      const char *address = "";
794      const char *name = "";
795  
796      if (aps == 0) return PERMISSION_DENIED;
797  
798      if (device_address != NULL) {
799          address = device_address;
800      }
801      if (device_name != NULL) {
802          name = device_name;
803      }
804      return aps->setDeviceConnectionState(device, state, address, name, encodedFormat);
805  }
xref: /frameworks/base/core/jni/android_media_AudioSystem.cpp
492  static jint
493  android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
494                                                     jint codec)
495  {
496      const char *c_address = env->GetStringUTFChars(device_address, NULL);
497      const char *c_name = env->GetStringUTFChars(device_name, NULL);
498      int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
499                                            static_cast <audio_policy_dev_state_t>(state),
500                                            c_address, c_name,
501                                            static_cast <audio_format_t>(codec)));
502      env->ReleaseStringUTFChars(device_address, c_address);
503      env->ReleaseStringUTFChars(device_name, c_name);
504      return (jint) status;
505  }
xref: /frameworks/av/media/libaudioclient/AudioSystem.cpp
786  status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
787                                                 audio_policy_dev_state_t state,
788                                                 const char *device_address,
789                                                 const char *device_name,
790                                                 audio_format_t encodedFormat)
791  {
792      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
793      const char *address = "";
794      const char *name = "";
795  
796      if (aps == 0) return PERMISSION_DENIED;
797  
798      if (device_address != NULL) {
799          address = device_address;
800      }
801      if (device_name != NULL) {
802          name = device_name;
803      }
804      return aps->setDeviceConnectionState(device, state, address, name, encodedFormat);
805  }
xref: /frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
31  status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
32                                                    audio_policy_dev_state_t state,
33                                                    const char *device_address,
34                                                    const char *device_name,
35                                                    audio_format_t encodedFormat)
36  {
37      if (mAudioPolicyManager == NULL) {
38          return NO_INIT;
39      }
40      if (!settingsAllowed()) {
41          return PERMISSION_DENIED;
42      }
43      if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
44              state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
45          return BAD_VALUE;
46      }
47  
48      ALOGV("setDeviceConnectionState()");
49      Mutex::Autolock _l(mLock);
50      AutoCallerClear acc;
51      return mAudioPolicyManager->setDeviceConnectionState(device, state,
52                                                           device_address, device_name, encodedFormat);
53  }
xref: /frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
83  status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
84                                                        audio_policy_dev_state_t state,
85                                                        const char *device_address,
86                                                        const char *device_name,
87                                                        audio_format_t encodedFormat)
88  {
89      status_t status = setDeviceConnectionStateInt(device, state, device_address,
90                                                    device_name, encodedFormat);
91      nextAudioPortGeneration();
92      return status;
93  }
 
105  status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
106                                                           audio_policy_dev_state_t state,
107                                                           const char *device_address,
108                                                           const char *device_name,
109                                                           audio_format_t encodedFormat)
110  {
111      ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s format 0x%X",
112              deviceType, state, device_address, device_name, encodedFormat);
113  
114      // connect/disconnect only 1 device at a time
115      if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
116  
117      sp<DeviceDescriptor> device =
118              mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
119                                             state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
120      if (device == 0) {
121          return INVALID_OPERATION;
122      }
123  
124      // handle output devices
125      if (audio_is_output_device(deviceType)) {
126          SortedVector <audio_io_handle_t> outputs;
127  
128          ssize_t index = mAvailableOutputDevices.indexOf(device);
129  
130          // save a copy of the opened output descriptors before any output is opened or closed
131          // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
132          mPreviousOutputs = mOutputs;
133          switch (state)
134          {
135          // handle output device connection
136          case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
137              if (index >= 0) {
138                  ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
139                  return INVALID_OPERATION;
140              }
141              ALOGV("%s() connecting device %s format %x",
142                      __func__, device->toString().c_str(), encodedFormat);
143  
144              // register new device as available
145              if (mAvailableOutputDevices.add(device) < 0) {
146                  return NO_MEMORY;
147              }
148  
149              // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
150              // parameters on newly connected devices (instead of opening the outputs...)
151              broadcastDeviceConnectionState(device, state);
152  
153              if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
154                  mAvailableOutputDevices.remove(device);
155  
156                  mHwModules.cleanUpForDevice(device);
157  
158                  broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
159                  return INVALID_OPERATION;
160              }
161  
162              // outputs should never be empty here
163              ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
164                      "checkOutputsForDevice() returned no outputs but status OK");
165              ALOGV("%s() checkOutputsForDevice() returned %zu outputs", __func__, outputs.size());
166  
167              } break;
168          // handle output device disconnection
169          case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
170              if (index < 0) {
171                  ALOGW("%s() device not connected: %s", __func__, device->toString().c_str());
172                  return INVALID_OPERATION;
173              }
174  
175              ALOGV("%s() disconnecting output device %s", __func__, device->toString().c_str());
176  
177              // Send Disconnect to HALs
178              broadcastDeviceConnectionState(device, state);
179  
180              // remove device from available output devices
181              mAvailableOutputDevices.remove(device);
182  
183              mOutputs.clearSessionRoutesForDevice(device);
184  
185              checkOutputsForDevice(device, state, outputs);
186  
187              // Reset active device codec
188              device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
189  
190              } break;
191  
192          default:
193              ALOGE("%s() invalid state: %x", __func__, state);
194              return BAD_VALUE;
195          }
196  
197          // Propagate device availability to Engine
198          setEngineDeviceConnectionState(device, state);
199  
200          // No need to evaluate playback routing when connecting a remote submix
201          // output device used by a dynamic policy of type recorder as no
202          // playback use case is affected.
203          bool doCheckForDeviceAndOutputChanges = true;
204          if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
205                  && strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) {
206              for (audio_io_handle_t output : outputs) {
207                  sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
208                  sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
209                  if (policyMix != nullptr
210                          && policyMix->mMixType == MIX_TYPE_RECORDERS
211                          && strncmp(device_address,
212                                     policyMix->mDeviceAddress.string(),
213                                     AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
214                      doCheckForDeviceAndOutputChanges = false;
215                      break;
216                  }
217              }
218          }
219  
220          auto checkCloseOutputs = [&]() {
221              // outputs must be closed after checkOutputForAllStrategies() is executed
222              if (!outputs.isEmpty()) {
223                  for (audio_io_handle_t output : outputs) {
224                      sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
225                      // close unused outputs after device disconnection or direct outputs that have
226                      // been opened by checkOutputsForDevice() to query dynamic parameters
227                      if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
228                              (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
229                                  (desc->mDirectOpenCount == 0))) {
230                          closeOutput(output);
231                      }
232                  }
233                  // check A2DP again after closing A2DP output to reset mA2dpSuspended if needed
234                  return true;
235              }
236              return false;
237          };
238  
239          if (doCheckForDeviceAndOutputChanges) {
240              checkForDeviceAndOutputChanges(checkCloseOutputs);
241          } else {
242              checkCloseOutputs();
243          }
244  
245          if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
246              DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
247              updateCallRouting(newDevices);
248          }
249          const DeviceVector msdOutDevices = getMsdAudioOutDevices();
250          for (size_t i = 0; i < mOutputs.size(); i++) {
251              sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
252              if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
253                  DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
254                  // do not force device change on duplicated output because if device is 0, it will
255                  // also force a device 0 for the two outputs it is duplicated to which may override
256                  // a valid device selection on those outputs.
257                  bool force = (msdOutDevices.isEmpty() || msdOutDevices != desc->devices())
258                          && !desc->isDuplicated()
259                          && (!device_distinguishes_on_address(deviceType)
260                                  // always force when disconnecting (a non-duplicated device)
261                                  || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
262                  setOutputDevices(desc, newDevices, force, 0);
263              }
264          }
265  
266          if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
267              cleanUpForDevice(device);
268          }
269  
270          mpClientInterface->onAudioPortListUpdate();
271          return NO_ERROR;
272      }  // end if is output device
273  
274      // handle input devices
275      if (audio_is_input_device(deviceType)) {
276          ssize_t index = mAvailableInputDevices.indexOf(device);
277          switch (state)
278          {
279          // handle input device connection
280          case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
281              if (index >= 0) {
282                  ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
283                  return INVALID_OPERATION;
284              }
285  
286              if (mAvailableInputDevices.add(device) < 0) {
287                  return NO_MEMORY;
288              }
289  
290              // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
291              // parameters on newly connected devices (instead of opening the inputs...)
292              broadcastDeviceConnectionState(device, state);
293  
294              if (checkInputsForDevice(device, state) != NO_ERROR) {
295                  mAvailableInputDevices.remove(device);
296  
297                  broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
298  
299                  mHwModules.cleanUpForDevice(device);
300  
301                  return INVALID_OPERATION;
302              }
303  
304          } break;
305  
306          // handle input device disconnection
307          case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
308              if (index < 0) {
309                  ALOGW("%s() device not connected: %s", __func__, device->toString().c_str());
310                  return INVALID_OPERATION;
311              }
312  
313              ALOGV("%s() disconnecting input device %s", __func__, device->toString().c_str());
314  
315              // Set Disconnect to HALs
316              broadcastDeviceConnectionState(device, state);
317  
318              mAvailableInputDevices.remove(device);
319  
320              checkInputsForDevice(device, state);
321          } break;
322  
323          default:
324              ALOGE("%s() invalid state: %x", __func__, state);
325              return BAD_VALUE;
326          }
327  
328          // Propagate device availability to Engine
329          setEngineDeviceConnectionState(device, state);
330  
331          checkCloseInputs();
332          // As the input device list can impact the output device selection, update
333          // getDeviceForStrategy() cache
334          updateDevicesAndOutputs();
335  
336          if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
337              DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
338              updateCallRouting(newDevices);
339          }
340  
341          if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
342              cleanUpForDevice(device);
343          }
344  
345          mpClientInterface->onAudioPortListUpdate();
346          return NO_ERROR;
347      } // end if is input device
348  
349      ALOGW("%s() invalid device: %s", __func__, device->toString().c_str());
350      return BAD_VALUE;
351  }
    经过一系列的调用最终走到AudioPolicyManager::setDeviceConnectionStateInt里面,checkOutputsForDevice(device, state, outputs);用于检测device是否有对应的outputs。
xref: /frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
4547  status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& device,
4548                                                     audio_policy_dev_state_t state,
4549                                                     SortedVector<audio_io_handle_t>& outputs)
4550  {
4551      audio_devices_t deviceType = device->type();
4552      const String8 &address = device->address();
4553      sp<SwAudioOutputDescriptor> desc;
4554  
4555      if (audio_device_is_digital(deviceType)) {
4556          // erase all current sample rates, formats and channel masks
4557          device->clearAudioProfiles();
4558      }
4559  
4560      if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
4561          // first list already open outputs that can be routed to this device
4562          for (size_t i = 0; i < mOutputs.size(); i++) {
4563              desc = mOutputs.valueAt(i);
4564              if (!desc->isDuplicated() && desc->supportsDevice(device)
4565                      && desc->deviceSupportsEncodedFormats(deviceType)) {
4566                  ALOGV("checkOutputsForDevice(): adding opened output %d on device %s",
4567                        mOutputs.keyAt(i), device->toString().c_str());
4568                  outputs.add(mOutputs.keyAt(i));
4569              }
4570          }
4571          // then look for output profiles that can be routed to this device
4572          SortedVector< sp<IOProfile> > profiles;
4573          for (const auto& hwModule : mHwModules) {
4574              for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
4575                  sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
4576                  if (profile->supportsDevice(device)) {
4577                      profiles.add(profile);
4578                      ALOGV("checkOutputsForDevice(): adding profile %zu from module %s",
4579                            j, hwModule->getName());
4580                  }
4581              }
4582          }
4583  
4584          ALOGV("  found %zu profiles, %zu outputs", profiles.size(), outputs.size());
4585  
4586          if (profiles.isEmpty() && outputs.isEmpty()) {
4587              ALOGW("checkOutputsForDevice(): No output available for device %04x", deviceType);
4588              return BAD_VALUE;
4589          }
4590  
4591          // open outputs for matching profiles if needed. Direct outputs are also opened to
4592          // query for dynamic parameters and will be closed later by setDeviceConnectionState()
4593          for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
4594              sp<IOProfile> profile = profiles[profile_index];
4595  
4596              // nothing to do if one output is already opened for this profile
4597              size_t j;
4598              for (j = 0; j < outputs.size(); j++) {
4599                  desc = mOutputs.valueFor(outputs.itemAt(j));
4600                  if (!desc->isDuplicated() && desc->mProfile == profile) {
4601                      // matching profile: save the sample rates, format and channel masks supported
4602                      // by the profile in our device descriptor
4603                      if (audio_device_is_digital(deviceType)) {
4604                          device->importAudioPort(profile);
4605                      }
4606                      break;
4607                  }
4608              }
4609              if (j != outputs.size()) {
4610                  continue;
4611              }
4612  
4613              if (!profile->canOpenNewIo()) {
4614                  ALOGW("Max Output number %u already opened for this profile %s",
4615                        profile->maxOpenCount, profile->getTagName().c_str());
4616                  continue;
4617              }
4618  
4619              ALOGV("opening output for device %08x with params %s profile %p name %s",
4620                    deviceType, address.string(), profile.get(), profile->getName().string());
4621              desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
4622              audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
4623              status_t status = desc->open(nullptr, DeviceVector(device),
4624                                           AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
4625  
4626              if (status == NO_ERROR) {
4627                  // Here is where the out_set_parameters() for card & device gets called
4628                  if (!address.isEmpty()) {
4629                      char *param = audio_device_address_to_parameter(deviceType, address);
4630                      mpClientInterface->setParameters(output, String8(param));
4631                      free(param);
4632                  }
4633                  updateAudioProfiles(device, output, profile->getAudioProfiles());
4634                  if (!profile->hasValidAudioProfile()) {
4635                      ALOGW("checkOutputsForDevice() missing param");
4636                      desc->close();
4637                      output = AUDIO_IO_HANDLE_NONE;
4638                  } else if (profile->hasDynamicAudioProfile()) {
4639                      desc->close();
4640                      output = AUDIO_IO_HANDLE_NONE;
4641                      audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4642                      profile->pickAudioProfile(
4643                              config.sample_rate, config.channel_mask, config.format);
4644                      config.offload_info.sample_rate = config.sample_rate;
4645                      config.offload_info.channel_mask = config.channel_mask;
4646                      config.offload_info.format = config.format;
4647  
4648                      status_t status = desc->open(&config, DeviceVector(device),
4649                                                   AUDIO_STREAM_DEFAULT,
4650                                                   AUDIO_OUTPUT_FLAG_NONE, &output);
4651                      if (status != NO_ERROR) {
4652                          output = AUDIO_IO_HANDLE_NONE;
4653                      }
4654                  }
4655  
4656                  if (output != AUDIO_IO_HANDLE_NONE) {
4657                      addOutput(output, desc);
4658                      if (device_distinguishes_on_address(deviceType) && address != "0") {
4659                          sp<AudioPolicyMix> policyMix;
4660                          if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix)
4661                                  == NO_ERROR) {
4662                              policyMix->setOutput(desc);
4663                              desc->mPolicyMix = policyMix;
4664                          } else {
4665                              ALOGW("checkOutputsForDevice() cannot find policy for address %s",
4666                                    address.string());
4667                          }
4668  
4669                      } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
4670                                      hasPrimaryOutput()) {
4671                          // no duplicated output for direct outputs and
4672                          // outputs used by dynamic policy mixes
4673                          audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
4674  
4675                          //TODO: configure audio effect output stage here
4676  
4677                          // open a duplicating output thread for the new output and the primary output
4678                          sp<SwAudioOutputDescriptor> dupOutputDesc =
4679                                  new SwAudioOutputDescriptor(NULL, mpClientInterface);
4680                          status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
4681                                                                           &duplicatedOutput);
4682                          if (status == NO_ERROR) {
4683                              // add duplicated output descriptor
4684                              addOutput(duplicatedOutput, dupOutputDesc);
4685                          } else {
4686                              ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
4687                                      mPrimaryOutput->mIoHandle, output);
4688                              desc->close();
4689                              removeOutput(output);
4690                              nextAudioPortGeneration();
4691                              output = AUDIO_IO_HANDLE_NONE;
4692                          }
4693                      }
4694                  }
4695              } else {
4696                  output = AUDIO_IO_HANDLE_NONE;
4697              }
4698              if (output == AUDIO_IO_HANDLE_NONE) {
4699                  ALOGW("checkOutputsForDevice() could not open output for device %x", deviceType);
4700                  profiles.removeAt(profile_index);
4701                  profile_index--;
4702              } else {
4703                  outputs.add(output);
4704                  // Load digital format info only for digital devices
4705                  if (audio_device_is_digital(deviceType)) {
4706                      device->importAudioPort(profile);
4707                  }
4708  
4709                  if (device_distinguishes_on_address(deviceType)) {
4710                      ALOGV("checkOutputsForDevice(): setOutputDevices %s",
4711                              device->toString().c_str());
4712                      setOutputDevices(desc, DeviceVector(device), true/*force*/, 0/*delay*/,
4713                                       NULL/*patch handle*/);
4714                  }
4715                  ALOGV("checkOutputsForDevice(): adding output %d", output);
4716              }
4717          }
4718  
4719          if (profiles.isEmpty()) {
4720              ALOGW("checkOutputsForDevice(): No output available for device %04x", deviceType);
4721              return BAD_VALUE;
4722          }
4723      } else { // Disconnect
4724          // check if one opened output is not needed any more after disconnecting one device
4725          for (size_t i = 0; i < mOutputs.size(); i++) {
4726              desc = mOutputs.valueAt(i);
4727              if (!desc->isDuplicated()) {
4728                  // exact match on device
4729                  if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)
4730                          && desc->deviceSupportsEncodedFormats(deviceType)) {
4731                      outputs.add(mOutputs.keyAt(i));
4732                  } else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) {
4733                      ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
4734                              mOutputs.keyAt(i));
4735                      outputs.add(mOutputs.keyAt(i));
4736                  }
4737              }
4738          }
4739          // Clear any profiles associated with the disconnected device.
4740          for (const auto& hwModule : mHwModules) {
4741              for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
4742                  sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
4743                  if (profile->supportsDevice(device)) {
4744                      ALOGV("checkOutputsForDevice(): "
4745                              "clearing direct output profile %zu on module %s",
4746                              j, hwModule->getName());
4747                      profile->clearAudioProfiles();
4748                  }
4749              }
4750          }
4751      }
4752      return NO_ERROR;
4753  }

​​​​​​​   desc->open打开新的output并创建播放线程playbackthread.

返回到AudioPolicyManager::setDeviceConnectionStateInt中,checkOutputsForDevice之后调用checkForDeviceAndOutputChanges方法,再调用AudioPolicyManager::checkOutputForAllStrategies,然后在调用checkOutputForAttributes方法。
xref: /frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
5030  void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr)
5031  {
5032      auto psId = mEngine->getProductStrategyForAttributes(attr);
5033  
5034      DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/);
5035      DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/);
5036      SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs);
5037      SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
5038  
5039      // also take into account external policy-related changes: add all outputs which are
5040      // associated with policies in the "before" and "after" output vectors
5041      ALOGVV("%s(): policy related outputs", __func__);
5042      for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
5043          const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
5044          if (desc != 0 && desc->mPolicyMix != NULL) {
5045              srcOutputs.add(desc->mIoHandle);
5046              ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
5047          }
5048      }
5049      for (size_t i = 0 ; i < mOutputs.size() ; i++) {
5050          const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
5051          if (desc != 0 && desc->mPolicyMix != NULL) {
5052              dstOutputs.add(desc->mIoHandle);
5053              ALOGVV(" new outputs: adding %d", desc->mIoHandle);
5054          }
5055      }
5056  
5057      if (srcOutputs != dstOutputs) {
5058          // get maximum latency of all source outputs to determine the minimum mute time guaranteeing
5059          // audio from invalidated tracks will be rendered when unmuting
5060          uint32_t maxLatency = 0;
5061          for (audio_io_handle_t srcOut : srcOutputs) {
5062              sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
5063              if (desc != 0 && maxLatency < desc->latency()) {
5064                  maxLatency = desc->latency();
5065              }
5066          }
5067          ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()),
5068                "%s: strategy %d, moving from output %s to output %s", __func__, psId,
5069                std::to_string(srcOutputs[0]).c_str(),
5070                std::to_string(dstOutputs[0]).c_str());
5071          // mute strategy while moving tracks from one output to another
5072          for (audio_io_handle_t srcOut : srcOutputs) {
5073              sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
5074              if (desc != 0 && desc->isStrategyActive(psId)) {
5075                  setStrategyMute(psId, true, desc);
5076                  setStrategyMute(psId, false, desc, maxLatency * LATENCY_MUTE_FACTOR,
5077                                  newDevices.types());
5078              }
5079              sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
5080              if (source != 0){
5081                  connectAudioSource(source);
5082              }
5083          }
5084  
5085          // Move effects associated to this stream from previous output to new output
5086          if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
5087              selectOutputForMusicEffects();
5088          }
5089          // Move tracks associated to this stream (and linked) from previous output to new output
5090          for (auto stream :  mEngine->getStreamTypesForProductStrategy(psId)) {
5091              mpClientInterface->invalidateStream(stream);
5092          }
5093      }
5094  }
    判断srcOutputs和dstOutputs是否相同,如果相同则不需要切换output,如果不相同则需要切换通道。mpClientInterface->invalidateStream使之前的output无效。
xref: /frameworks/av/media/libaudioclient/AudioTrack.cpp
2287  status_t AudioTrack::restoreTrack_l(const char *from)
2288  {
2289      ALOGW("%s(%d): dead IAudioTrack, %s, creating a new one from %s()",
2290              __func__, mPortId, isOffloadedOrDirect_l() ? "Offloaded or Direct" : "PCM", from);
2291      ++mSequence;
2292  
2293      // refresh the audio configuration cache in this process to make sure we get new
2294      // output parameters and new IAudioFlinger in createTrack_l()
2295      AudioSystem::clearAudioConfigCache();
2296  
2297      if (isOffloadedOrDirect_l() || mDoNotReconnect) {
2298          // FIXME re-creation of offloaded and direct tracks is not yet implemented;
2299          // reconsider enabling for linear PCM encodings when position can be preserved.
2300          return DEAD_OBJECT;
2301      }
2302  
2303      // Save so we can return count since creation.
2304      mUnderrunCountOffset = getUnderrunCount_l();
2305  
2306      // save the old static buffer position
2307      uint32_t staticPosition = 0;
2308      size_t bufferPosition = 0;
2309      int loopCount = 0;
2310      if (mStaticProxy != 0) {
2311          mStaticProxy->getBufferPositionAndLoopCount(&bufferPosition, &loopCount);
2312          staticPosition = mStaticProxy->getPosition().unsignedValue();
2313      }
2314  
2315      // See b/74409267. Connecting to a BT A2DP device supporting multiple codecs
2316      // causes a lot of churn on the service side, and it can reject starting
2317      // playback of a previously created track. May also apply to other cases.
2318      const int INITIAL_RETRIES = 3;
2319      int retries = INITIAL_RETRIES;
2320  retry:
2321      if (retries < INITIAL_RETRIES) {
2322          // See the comment for clearAudioConfigCache at the start of the function.
2323          AudioSystem::clearAudioConfigCache();
2324      }
2325      mFlags = mOrigFlags;
2326  
2327      // If a new IAudioTrack is successfully created, createTrack_l() will modify the
2328      // following member variables: mAudioTrack, mCblkMemory and mCblk.
2329      // It will also delete the strong references on previous IAudioTrack and IMemory.
2330      // If a new IAudioTrack cannot be created, the previous (dead) instance will be left intact.
2331      status_t result = createTrack_l();
2332  
2333      if (result == NO_ERROR) {
2334          // take the frames that will be lost by track recreation into account in saved position
2335          // For streaming tracks, this is the amount we obtained from the user/client
2336          // (not the number actually consumed at the server - those are already lost).
2337          if (mStaticProxy == 0) {
2338              mPosition = mReleased;
2339          }
2340          // Continue playback from last known position and restore loop.
2341          if (mStaticProxy != 0) {
2342              if (loopCount != 0) {
2343                  mStaticProxy->setBufferPositionAndLoop(bufferPosition,
2344                          mLoopStart, mLoopEnd, loopCount);
2345              } else {
2346                  mStaticProxy->setBufferPosition(bufferPosition);
2347                  if (bufferPosition == mFrameCount) {
2348                      ALOGD("%s(%d): restoring track at end of static buffer", __func__, mPortId);
2349                  }
2350              }
2351          }
2352          // restore volume handler
2353          mVolumeHandler->forall([this](const VolumeShaper &shaper) -> VolumeShaper::Status {
2354              sp<VolumeShaper::Operation> operationToEnd =
2355                      new VolumeShaper::Operation(shaper.mOperation);
2356              // TODO: Ideally we would restore to the exact xOffset position
2357              // as returned by getVolumeShaperState(), but we don't have that
2358              // information when restoring at the client unless we periodically poll
2359              // the server or create shared memory state.
2360              //
2361              // For now, we simply advance to the end of the VolumeShaper effect
2362              // if it has been started.
2363              if (shaper.isStarted()) {
2364                  operationToEnd->setNormalizedTime(1.f);
2365              }
2366              return mAudioTrack->applyVolumeShaper(shaper.mConfiguration, operationToEnd);
2367          });
2368  
2369          if (mState == STATE_ACTIVE) {
2370              result = mAudioTrack->start();
2371          }
2372          // server resets to zero so we offset
2373          mFramesWrittenServerOffset =
2374                  mStaticProxy.get() != nullptr ? staticPosition : mFramesWritten;
2375          mFramesWrittenAtRestore = mFramesWrittenServerOffset;
2376      }
2377      if (result != NO_ERROR) {
2378          ALOGW("%s(%d): failed status %d, retries %d", __func__, mPortId, result, retries);
2379          if (--retries > 0) {
2380              // leave time for an eventual race condition to clear before retrying
2381              usleep(500000);
2382              goto retry;
2383          }
2384          // if no retries left, set invalid bit to force restoring at next occasion
2385          // and avoid inconsistent active state on client and server sides
2386          if (mCblk != nullptr) {
2387              android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
2388          }
2389      }
2390      return result;
2391  }
xref: /frameworks/av/media/libaudioclient/AudioTrack.cpp
1393  status_t AudioTrack::createTrack_l()
1394  {
1395      status_t status;
1396      bool callbackAdded = false;
1397  
1398      const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
1399      if (audioFlinger == 0) {
1400          ALOGE("%s(%d): Could not get audioflinger",
1401                  __func__, mPortId);
1402          status = NO_INIT;
1403          goto exit;
1404      }
1405  
1406      {
1407      // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
1408      // After fast request is denied, we will request again if IAudioTrack is re-created.
1409      // Client can only express a preference for FAST.  Server will perform additional tests.
1410      if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
1411          // either of these use cases:
1412          // use case 1: shared buffer
1413          bool sharedBuffer = mSharedBuffer != 0;
1414          bool transferAllowed =
1415              // use case 2: callback transfer mode
1416              (mTransfer == TRANSFER_CALLBACK) ||
1417              // use case 3: obtain/release mode
1418              (mTransfer == TRANSFER_OBTAIN) ||
1419              // use case 4: synchronous write
1420              ((mTransfer == TRANSFER_SYNC || mTransfer == TRANSFER_SYNC_NOTIF_CALLBACK)
1421                      && mThreadCanCallJava);
1422  
1423          bool fastAllowed = sharedBuffer || transferAllowed;
1424          if (!fastAllowed) {
1425              ALOGW("%s(%d): AUDIO_OUTPUT_FLAG_FAST denied by client,"
1426                    " not shared buffer and transfer = %s",
1427                    __func__, mPortId,
1428                    convertTransferToText(mTransfer));
1429              mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_FAST);
1430          }
1431      }
1432  
1433      IAudioFlinger::CreateTrackInput input;
1434      if (mStreamType != AUDIO_STREAM_DEFAULT) {
1435          input.attr = AudioSystem::streamTypeToAttributes(mStreamType);
1436      } else {
1437          input.attr = mAttributes;
1438      }
1439      input.config = AUDIO_CONFIG_INITIALIZER;
1440      input.config.sample_rate = mSampleRate;
1441      input.config.channel_mask = mChannelMask;
1442      input.config.format = mFormat;
1443      input.config.offload_info = mOffloadInfoCopy;
1444      input.clientInfo.clientUid = mClientUid;
1445      input.clientInfo.clientPid = mClientPid;
1446      input.clientInfo.clientTid = -1;
1447      if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
1448          // It is currently meaningless to request SCHED_FIFO for a Java thread.  Even if the
1449          // application-level code follows all non-blocking design rules, the language runtime
1450          // doesn't also follow those rules, so the thread will not benefit overall.
1451          if (mAudioTrackThread != 0 && !mThreadCanCallJava) {
1452              input.clientInfo.clientTid = mAudioTrackThread->getTid();
1453          }
1454      }
1455      input.sharedBuffer = mSharedBuffer;
1456      input.notificationsPerBuffer = mNotificationsPerBufferReq;
1457      input.speed = 1.0;
1458      if (audio_has_proportional_frames(mFormat) && mSharedBuffer == 0 &&
1459              (mFlags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
1460          input.speed  = !isPurePcmData_l() || isOffloadedOrDirect_l() ? 1.0f :
1461                          max(mMaxRequiredSpeed, mPlaybackRate.mSpeed);
1462      }
1463      input.flags = mFlags;
1464      input.frameCount = mReqFrameCount;
1465      input.notificationFrameCount = mNotificationFramesReq;
1466      input.selectedDeviceId = mSelectedDeviceId;
1467      input.sessionId = mSessionId;
1468  
1469      IAudioFlinger::CreateTrackOutput output;
1470  
1471      sp<IAudioTrack> track = audioFlinger->createTrack(input,
1472                                                        output,
1473                                                        &status);
1474  
1475      if (status != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
1476          ALOGE("%s(%d): AudioFlinger could not create track, status: %d output %d",
1477                  __func__, mPortId, status, output.outputId);
1478          if (status == NO_ERROR) {
1479              status = NO_INIT;
1480          }
1481          goto exit;
1482      }
1483      ALOG_ASSERT(track != 0);
1484  
1485      mFrameCount = output.frameCount;
1486      mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
1487      mRoutedDeviceId = output.selectedDeviceId;
1488      mSessionId = output.sessionId;
1489  
1490      mSampleRate = output.sampleRate;
1491      if (mOriginalSampleRate == 0) {
1492          mOriginalSampleRate = mSampleRate;
1493      }
1494  
1495      mAfFrameCount = output.afFrameCount;
1496      mAfSampleRate = output.afSampleRate;
1497      mAfLatency = output.afLatencyMs;
1498  
1499      mLatency = mAfLatency + (1000LL * mFrameCount) / mSampleRate;
1500  
1501      // AudioFlinger now owns the reference to the I/O handle,
1502      // so we are no longer responsible for releasing it.
1503  
1504      // FIXME compare to AudioRecord
1505      sp<IMemory> iMem = track->getCblk();
1506      if (iMem == 0) {
1507          ALOGE("%s(%d): Could not get control block", __func__, mPortId);
1508          status = NO_INIT;
1509          goto exit;
1510      }
1511      void *iMemPointer = iMem->pointer();
1512      if (iMemPointer == NULL) {
1513          ALOGE("%s(%d): Could not get control block pointer", __func__, mPortId);
1514          status = NO_INIT;
1515          goto exit;
1516      }
1517      // invariant that mAudioTrack != 0 is true only after set() returns successfully
1518      if (mAudioTrack != 0) {
1519          IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this);
1520          mDeathNotifier.clear();
1521      }
1522      mAudioTrack = track;
1523      mCblkMemory = iMem;
1524      IPCThreadState::self()->flushCommands();
1525  
1526      audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
1527      mCblk = cblk;
1528  
1529      mAwaitBoost = false;
1530      if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
1531          if (output.flags & AUDIO_OUTPUT_FLAG_FAST) {
1532              ALOGI("%s(%d): AUDIO_OUTPUT_FLAG_FAST successful; frameCount %zu -> %zu",
1533                    __func__, mPortId, mReqFrameCount, mFrameCount);
1534              if (!mThreadCanCallJava) {
1535                  mAwaitBoost = true;
1536              }
1537          } else {
1538              ALOGW("%s(%d): AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %zu -> %zu",
1539                    __func__, mPortId, mReqFrameCount, mFrameCount);
1540          }
1541      }
1542      mFlags = output.flags;
1543  
1544      //mOutput != output includes the case where mOutput == AUDIO_IO_HANDLE_NONE for first creation
1545      if (mDeviceCallback != 0) {
1546          if (mOutput != AUDIO_IO_HANDLE_NONE) {
1547              AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
1548          }
1549          AudioSystem::addAudioDeviceCallback(this, output.outputId, output.portId);
1550          callbackAdded = true;
1551      }
1552  
1553      mPortId = output.portId;
1554      // We retain a copy of the I/O handle, but don't own the reference
1555      mOutput = output.outputId;
1556      mRefreshRemaining = true;
1557  
1558      // Starting address of buffers in shared memory.  If there is a shared buffer, buffers
1559      // is the value of pointer() for the shared buffer, otherwise buffers points
1560      // immediately after the control block.  This address is for the mapping within client
1561      // address space.  AudioFlinger::TrackBase::mBuffer is for the server address space.
1562      void* buffers;
1563      if (mSharedBuffer == 0) {
1564          buffers = cblk + 1;
1565      } else {
1566          buffers = mSharedBuffer->pointer();
1567          if (buffers == NULL) {
1568              ALOGE("%s(%d): Could not get buffer pointer", __func__, mPortId);
1569              status = NO_INIT;
1570              goto exit;
1571          }
1572      }
1573  
1574      mAudioTrack->attachAuxEffect(mAuxEffectId);
1575  
1576      // If IAudioTrack is re-created, don't let the requested frameCount
1577      // decrease.  This can confuse clients that cache frameCount().
1578      if (mFrameCount > mReqFrameCount) {
1579          mReqFrameCount = mFrameCount;
1580      }
1581  
1582      // reset server position to 0 as we have new cblk.
1583      mServer = 0;
1584  
1585      // update proxy
1586      if (mSharedBuffer == 0) {
1587          mStaticProxy.clear();
1588          mProxy = new AudioTrackClientProxy(cblk, buffers, mFrameCount, mFrameSize);
1589      } else {
1590          mStaticProxy = new StaticAudioTrackClientProxy(cblk, buffers, mFrameCount, mFrameSize);
1591          mProxy = mStaticProxy;
1592      }
1593  
1594      mProxy->setVolumeLR(gain_minifloat_pack(
1595              gain_from_float(mVolume[AUDIO_INTERLEAVE_LEFT]),
1596              gain_from_float(mVolume[AUDIO_INTERLEAVE_RIGHT])));
1597  
1598      mProxy->setSendLevel(mSendLevel);
1599      const uint32_t effectiveSampleRate = adjustSampleRate(mSampleRate, mPlaybackRate.mPitch);
1600      const float effectiveSpeed = adjustSpeed(mPlaybackRate.mSpeed, mPlaybackRate.mPitch);
1601      const float effectivePitch = adjustPitch(mPlaybackRate.mPitch);
1602      mProxy->setSampleRate(effectiveSampleRate);
1603  
1604      AudioPlaybackRate playbackRateTemp = mPlaybackRate;
1605      playbackRateTemp.mSpeed = effectiveSpeed;
1606      playbackRateTemp.mPitch = effectivePitch;
1607      mProxy->setPlaybackRate(playbackRateTemp);
1608      mProxy->setMinimum(mNotificationFramesAct);
1609  
1610      mDeathNotifier = new DeathNotifier(this);
1611      IInterface::asBinder(mAudioTrack)->linkToDeath(mDeathNotifier, this);
1612  
1613      }
1614  
1615  exit:
1616      if (status != NO_ERROR && callbackAdded) {
1617          // note: mOutput is always valid is callbackAdded is true
1618          AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
1619      }
1620  
1621      mStatus = status;
1622  
1623      // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
1624      return status;
1625  }
​​​​​​​    最终会通过audioFlinger->createTrack在audioFlinger中创建一个新的track跟audioTrack相对应。后面数据会传给新的track,从而在新的设备上播放出来。
  • 24
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值