1e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk/* 2e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Copyright 2017 The Android Open Source Project 3e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 4e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * you may not use this file except in compliance with the License. 6e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * You may obtain a copy of the License at 7e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 8e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 9e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * 10e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * Unless required by applicable law or agreed to in writing, software 11e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * See the License for the specific language governing permissions and 14e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk * limitations under the License. 15e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk */ 16e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 17e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#define LOG_TAG "AudioStreamLegacy" 18e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk//#define LOG_NDEBUG 0 19e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <utils/Log.h> 20e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 21e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <stdint.h> 223d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk 233d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk#include <aaudio/AAudio.h> 243d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk#include <audio_utils/primitives.h> 25e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <media/AudioTrack.h> 267328a80ffc83729cc6252c79e0851a31af59c653Phil Burk#include <media/AudioTimestamp.h> 273d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk#include <utils/String16.h> 28e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 29e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "core/AudioStream.h" 30e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "legacy/AudioStreamLegacy.h" 31e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 32e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkusing namespace android; 33e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkusing namespace aaudio; 34e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 35e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil BurkAudioStreamLegacy::AudioStreamLegacy() 362d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk : AudioStream() 372d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk , mDeviceCallback(new StreamDeviceCallback(this)) { 38e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 39e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 40e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil BurkAudioStreamLegacy::~AudioStreamLegacy() { 41e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 42e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 43e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk// Called from AudioTrack.cpp or AudioRecord.cpp 44e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkstatic void AudioStreamLegacy_callback(int event, void* userData, void *info) { 45e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk AudioStreamLegacy *streamLegacy = (AudioStreamLegacy *) userData; 46e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk streamLegacy->processCallback(event, info); 47e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 48e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 49e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkaaudio_legacy_callback_t AudioStreamLegacy::getLegacyCallback() { 50e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return AudioStreamLegacy_callback; 51e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 52e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 533d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burkaaudio_data_callback_result_t AudioStreamLegacy::callDataCallbackFrames(uint8_t *buffer, 543d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk int32_t numFrames) { 553d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk void *finalAudioData = buffer; 567328a80ffc83729cc6252c79e0851a31af59c653Phil Burk if (getDirection() == AAUDIO_DIRECTION_INPUT) { 577328a80ffc83729cc6252c79e0851a31af59c653Phil Burk // Increment before because we already got the data from the device. 587328a80ffc83729cc6252c79e0851a31af59c653Phil Burk incrementFramesRead(numFrames); 593d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk finalAudioData = (void *) maybeConvertDeviceData(buffer, numFrames); 607328a80ffc83729cc6252c79e0851a31af59c653Phil Burk } 617328a80ffc83729cc6252c79e0851a31af59c653Phil Burk 62e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Call using the AAudio callback interface. 633d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk aaudio_data_callback_result_t callbackResult = maybeCallDataCallback(finalAudioData, numFrames); 647328a80ffc83729cc6252c79e0851a31af59c653Phil Burk 657328a80ffc83729cc6252c79e0851a31af59c653Phil Burk if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE 667328a80ffc83729cc6252c79e0851a31af59c653Phil Burk && getDirection() == AAUDIO_DIRECTION_OUTPUT) { 677328a80ffc83729cc6252c79e0851a31af59c653Phil Burk // Increment after because we are going to write the data to the device. 687328a80ffc83729cc6252c79e0851a31af59c653Phil Burk incrementFramesWritten(numFrames); 697328a80ffc83729cc6252c79e0851a31af59c653Phil Burk } 707328a80ffc83729cc6252c79e0851a31af59c653Phil Burk return callbackResult; 717328a80ffc83729cc6252c79e0851a31af59c653Phil Burk} 727328a80ffc83729cc6252c79e0851a31af59c653Phil Burk 737328a80ffc83729cc6252c79e0851a31af59c653Phil Burk// Implement FixedBlockProcessor 747328a80ffc83729cc6252c79e0851a31af59c653Phil Burkint32_t AudioStreamLegacy::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) { 753d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk int32_t numFrames = numBytes / getBytesPerDeviceFrame(); 76134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return (int32_t) callDataCallbackFrames(buffer, numFrames); 77e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 78e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 79e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkvoid AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) { 80e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk aaudio_data_callback_result_t callbackResult; 813d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk // This illegal size can be used to tell AudioFlinger to stop calling us. 82134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // This takes advantage of AudioFlinger killing the stream. 833d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk // TODO add to API in AudioRecord and AudioTrack 84134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk const size_t SIZE_STOP_CALLBACKS = SIZE_MAX; 85fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent 86e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk switch (opcode) { 87e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: { 88134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk (void) checkForDisconnectRequest(true); 892d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk 902d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // Note that this code assumes an AudioTrack::Buffer is the same as 912d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // AudioRecord::Buffer 922d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // TODO define our own AudioBuffer and pass it from the subclasses. 932d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info); 949e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) { 959e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk ALOGW("processCallbackCommon() data, stream disconnected"); 969e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk audioBuffer->size = SIZE_STOP_CALLBACKS; 979e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk } else if (!mCallbackEnabled.load()) { 989e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk ALOGW("processCallbackCommon() stopping because callback disabled"); 99134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk audioBuffer->size = SIZE_STOP_CALLBACKS; 1002d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk } else { 1012d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk if (audioBuffer->frameCount == 0) { 1029e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk ALOGW("processCallbackCommon() data, frameCount is zero"); 1032d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk return; 1042d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk } 105fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent 106fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent // If the caller specified an exact size then use a block size adapter. 107fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent if (mBlockAdapter != nullptr) { 1083d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk int32_t byteCount = audioBuffer->frameCount * getBytesPerDeviceFrame(); 109fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent callbackResult = mBlockAdapter->processVariableBlock( 110fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent (uint8_t *) audioBuffer->raw, byteCount); 111fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent } else { 112fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent // Call using the AAudio callback interface. 1137328a80ffc83729cc6252c79e0851a31af59c653Phil Burk callbackResult = callDataCallbackFrames((uint8_t *)audioBuffer->raw, 1147328a80ffc83729cc6252c79e0851a31af59c653Phil Burk audioBuffer->frameCount); 115fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent } 116fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) { 1173d786cb59f5acd5484fa4fb968ba2de9dcf283adPhil Burk audioBuffer->size = audioBuffer->frameCount * getBytesPerDeviceFrame(); 118134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } else { // STOP or invalid result 1199e9a95b347ce2a86ced8b3b12603e05d1411b708Phil Burk ALOGW("%s() callback requested stop, fake an error", __func__); 120134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk audioBuffer->size = SIZE_STOP_CALLBACKS; 121134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // Disable the callback just in case AudioFlinger keeps trying to call us. 122134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk mCallbackEnabled.store(false); 123fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent } 1240befec600314a79c0d142c3edd99f7d1c75e1afePhil Burk 1252d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk if (updateStateMachine() != AAUDIO_OK) { 1262d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk forceDisconnect(); 1272d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk mCallbackEnabled.store(false); 1280befec600314a79c0d142c3edd99f7d1c75e1afePhil Burk } 129e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 130e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 1312d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk break; 132e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 1330befec600314a79c0d142c3edd99f7d1c75e1afePhil Burk // Stream got rerouted so we disconnect. 1342d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: 135fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent ALOGD("processCallbackCommon() stream disconnected"); 1362d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk forceDisconnect(); 137e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mCallbackEnabled.store(false); 138e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk break; 139e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 140e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk default: 141e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk break; 142e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 143e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 1445204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk 145134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_result_t AudioStreamLegacy::checkForDisconnectRequest(bool errorCallbackEnabled) { 1462d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk if (mRequestDisconnect.isRequested()) { 1472d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk ALOGD("checkForDisconnectRequest() mRequestDisconnect acknowledged"); 148134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk forceDisconnect(errorCallbackEnabled); 1492d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk mRequestDisconnect.acknowledge(); 1502d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk mCallbackEnabled.store(false); 151134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_ERROR_DISCONNECTED; 152134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } else { 153134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_OK; 1542d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk } 1552d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk} 1562d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk 157134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkvoid AudioStreamLegacy::forceDisconnect(bool errorCallbackEnabled) { 1582d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk if (getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { 1592d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk setState(AAUDIO_STREAM_STATE_DISCONNECTED); 160134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (errorCallbackEnabled) { 161134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk maybeCallErrorCallback(AAUDIO_ERROR_DISCONNECTED); 1622d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk } 1632d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk } 1642d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk} 1652d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk 1665204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burkaaudio_result_t AudioStreamLegacy::getBestTimestamp(clockid_t clockId, 1675204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk int64_t *framePosition, 1685204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk int64_t *timeNanoseconds, 1695204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk ExtendedTimestamp *extendedTimestamp) { 1705204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk int timebase; 1715204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk switch (clockId) { 1725204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk case CLOCK_BOOTTIME: 1735204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk timebase = ExtendedTimestamp::TIMEBASE_BOOTTIME; 1745204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk break; 1755204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk case CLOCK_MONOTONIC: 1765204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk timebase = ExtendedTimestamp::TIMEBASE_MONOTONIC; 1775204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk break; 1785204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk default: 1795204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk ALOGE("getTimestamp() - Unrecognized clock type %d", (int) clockId); 18017fff38dd9d467bc5fb6cd5b9a6b183951c7750dPhil Burk return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 1815204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk break; 1825204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk } 1837328a80ffc83729cc6252c79e0851a31af59c653Phil Burk ExtendedTimestamp::Location location = ExtendedTimestamp::Location::LOCATION_INVALID; 1847328a80ffc83729cc6252c79e0851a31af59c653Phil Burk int64_t localPosition; 1857328a80ffc83729cc6252c79e0851a31af59c653Phil Burk status_t status = extendedTimestamp->getBestTimestamp(&localPosition, timeNanoseconds, 1867328a80ffc83729cc6252c79e0851a31af59c653Phil Burk timebase, &location); 187c0959648b4a3d73212cd16c1f03289eadcbacae0Phil Burk if (status == OK) { 188c0959648b4a3d73212cd16c1f03289eadcbacae0Phil Burk // use MonotonicCounter to prevent retrograde motion. 189c0959648b4a3d73212cd16c1f03289eadcbacae0Phil Burk mTimestampPosition.update32((int32_t) localPosition); 190c0959648b4a3d73212cd16c1f03289eadcbacae0Phil Burk *framePosition = mTimestampPosition.get(); 191c0959648b4a3d73212cd16c1f03289eadcbacae0Phil Burk } 1927328a80ffc83729cc6252c79e0851a31af59c653Phil Burk 1937328a80ffc83729cc6252c79e0851a31af59c653Phil Burk// ALOGD("getBestTimestamp() fposition: server = %6lld, kernel = %6lld, location = %d", 1947328a80ffc83729cc6252c79e0851a31af59c653Phil Burk// (long long) extendedTimestamp->mPosition[ExtendedTimestamp::Location::LOCATION_SERVER], 1957328a80ffc83729cc6252c79e0851a31af59c653Phil Burk// (long long) extendedTimestamp->mPosition[ExtendedTimestamp::Location::LOCATION_KERNEL], 1967328a80ffc83729cc6252c79e0851a31af59c653Phil Burk// (int)location); 197c0959648b4a3d73212cd16c1f03289eadcbacae0Phil Burk return AAudioConvert_androidToAAudioResult(status); 1985204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk} 199fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent 200fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurentvoid AudioStreamLegacy::onAudioDeviceUpdate(audio_port_handle_t deviceId) 201fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent{ 202fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent ALOGD("onAudioDeviceUpdate() deviceId %d", (int)deviceId); 203fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent if (getDeviceId() != AAUDIO_UNSPECIFIED && getDeviceId() != deviceId && 204fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent getState() != AAUDIO_STREAM_STATE_DISCONNECTED) { 2052d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // Note that isDataCallbackActive() is affected by state so call it before DISCONNECTING. 2062d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // If we have a data callback and the stream is active, then ask the data callback 2072d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // to DISCONNECT and call the error callback. 2082d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk if (isDataCallbackActive()) { 2092d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk ALOGD("onAudioDeviceUpdate() request DISCONNECT in data callback due to device change"); 2102d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // If the stream is stopped before the data callback has a chance to handle the 2112d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // request then the requestStop() and requestPause() methods will handle it after 2122d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk // the callback has stopped. 2132d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk mRequestDisconnect.request(); 2142d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk } else { 2152d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk ALOGD("onAudioDeviceUpdate() DISCONNECT the stream now"); 2162d5ba532cc80b3408b9eb5d47d3144bf93ece8cdPhil Burk forceDisconnect(); 217fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent } 218fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent } 219fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent setDeviceId(deviceId); 220fb00fc77f59ed5ebec4d38bac666e6521b6c1de0Eric Laurent} 221