Merge "Clarify ownership of returned pointer"
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 02dc516..6665c43 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1392,6 +1392,12 @@
return af->getMicrophones(microphones);
}
+status_t AudioSystem::setAudioHalPids(const std::vector<pid_t>& pids) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) return PERMISSION_DENIED;
+ return af->setAudioHalPids(pids);
+}
+
status_t AudioSystem::getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 54ec684..90783eb 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -90,10 +90,12 @@
SET_MASTER_BALANCE,
GET_MASTER_BALANCE,
SET_EFFECT_SUSPENDED,
+ SET_AUDIO_HAL_PIDS
};
#define MAX_ITEMS_PER_LIST 1024
+
class BpAudioFlinger : public BpInterface<IAudioFlinger>
{
public:
@@ -900,6 +902,20 @@
status = reply.readParcelableVector(microphones);
return status;
}
+ virtual status_t setAudioHalPids(const std::vector<pid_t>& pids)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(pids.size());
+ for (auto pid : pids) {
+ data.writeInt32(pid);
+ }
+ status_t status = remote()->transact(SET_AUDIO_HAL_PIDS, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return static_cast <status_t> (reply.readInt32());
+ }
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -955,7 +971,8 @@
case SET_MODE:
case SET_MIC_MUTE:
case SET_LOW_RAM_DEVICE:
- case SYSTEM_READY: {
+ case SYSTEM_READY:
+ case SET_AUDIO_HAL_PIDS: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@@ -1542,6 +1559,31 @@
}
return NO_ERROR;
}
+ case SET_AUDIO_HAL_PIDS: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ std::vector<pid_t> pids;
+ int32_t size;
+ status_t status = data.readInt32(&size);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+ if (size > MAX_ITEMS_PER_LIST) {
+ size = MAX_ITEMS_PER_LIST;
+ }
+ for (int32_t i = 0; i < size; i++) {
+ int32_t pid;
+ status = data.readInt32(&pid);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ pids.push_back(pid);
+ }
+ reply->writeInt32(setAudioHalPids(pids));
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 3f846f7..f29a775 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -397,6 +397,12 @@
static status_t setRttEnabled(bool enabled);
+ /**
+ * Send audio HAL server process pids to native audioserver process for use
+ * when generating audio HAL servers tombstones
+ */
+ static status_t setAudioHalPids(const std::vector<pid_t>& pids);
+
// ----------------------------------------------------------------------------
class AudioVolumeGroupCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index a6b9ba8..8e8a1f5 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -511,6 +511,8 @@
/* List available microphones and their characteristics */
virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+
+ virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;
};
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 1bfe3f9..31257d5 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -42,6 +42,13 @@
return audioDeviceOutAllScoSet;
}
+const DeviceTypeSet& getAudioDeviceOutAllUsbSet() {
+ static const DeviceTypeSet audioDeviceOutAllUsbSet = DeviceTypeSet(
+ std::begin(AUDIO_DEVICE_OUT_ALL_USB_ARRAY),
+ std::end(AUDIO_DEVICE_OUT_ALL_USB_ARRAY));
+ return audioDeviceOutAllUsbSet;
+}
+
const DeviceTypeSet& getAudioDeviceInAllSet() {
static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet(
std::begin(AUDIO_DEVICE_IN_ALL_ARRAY),
@@ -49,6 +56,13 @@
return audioDeviceInAllSet;
}
+const DeviceTypeSet& getAudioDeviceInAllUsbSet() {
+ static const DeviceTypeSet audioDeviceInAllUsbSet = DeviceTypeSet(
+ std::begin(AUDIO_DEVICE_IN_ALL_USB_ARRAY),
+ std::end(AUDIO_DEVICE_IN_ALL_USB_ARRAY));
+ return audioDeviceInAllUsbSet;
+}
+
bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) {
if (deviceTypes.empty()) {
str = "Empty device types";
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index f01ac83..ef7576e 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -25,12 +25,22 @@
namespace android {
DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type) :
- AudioPort("", AUDIO_PORT_TYPE_DEVICE,
- audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
- AUDIO_PORT_ROLE_SOURCE)
+ DeviceDescriptorBase(type, "")
{
- mDeviceTypeAddr.mType = type;
- if (audio_is_remote_submix_device(type)) {
+}
+
+DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type, const std::string& address) :
+ DeviceDescriptorBase(AudioDeviceTypeAddr(type, address))
+{
+}
+
+DeviceDescriptorBase::DeviceDescriptorBase(const AudioDeviceTypeAddr &deviceTypeAddr) :
+ AudioPort("", AUDIO_PORT_TYPE_DEVICE,
+ audio_is_output_device(deviceTypeAddr.mType) ? AUDIO_PORT_ROLE_SINK :
+ AUDIO_PORT_ROLE_SOURCE),
+ mDeviceTypeAddr(deviceTypeAddr)
+{
+ if (mDeviceTypeAddr.mAddress.empty() && audio_is_remote_submix_device(mDeviceTypeAddr.mType)) {
mDeviceTypeAddr.mAddress = "0";
}
}
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 2a3385b..72fda49 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -37,7 +37,9 @@
const DeviceTypeSet& getAudioDeviceOutAllSet();
const DeviceTypeSet& getAudioDeviceOutAllA2dpSet();
const DeviceTypeSet& getAudioDeviceOutAllScoSet();
+const DeviceTypeSet& getAudioDeviceOutAllUsbSet();
const DeviceTypeSet& getAudioDeviceInAllSet();
+const DeviceTypeSet& getAudioDeviceInAllUsbSet();
template<typename T>
static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 5641ff1..4c03667 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -35,6 +35,8 @@
public:
// Note that empty name refers by convention to a generic device.
explicit DeviceDescriptorBase(audio_devices_t type);
+ DeviceDescriptorBase(audio_devices_t type, const std::string& address);
+ explicit DeviceDescriptorBase(const AudioDeviceTypeAddr& deviceTypeAddr);
virtual ~DeviceDescriptorBase() {}
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 8669e2a..e96a68c 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -27,6 +27,7 @@
"android.hardware.audio.common-util",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
+ "libaudiofoundation",
"libaudiohal_deathhandler",
"libaudioutils",
"libbase",
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 9f8a520..f29b0f3 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -17,6 +17,7 @@
#include <string.h>
#define LOG_TAG "HalHidl"
+#include <media/AudioContainers.h>
#include <media/AudioParameter.h>
#include <utils/Log.h>
@@ -109,26 +110,22 @@
char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
memset(halAddress, 0, sizeof(halAddress));
audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
- const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
+ halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
address.address.mac[0], address.address.mac[1], address.address.mac[2],
address.address.mac[3], address.address.mac[4], address.address.mac[5]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+ } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
+ getAudioDeviceInAllUsbSet().count(halDevice) > 0) {
snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
address.address.alsa.device);
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
- } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
- (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+ halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
} else {
snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index e166900..42c16c0 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -22,6 +22,7 @@
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include <cutils/native_handle.h>
#include <hwbinder/IPCThreadState.h>
+#include <media/AudioContainers.h>
#include <utils/Log.h>
#include <common/all-versions/VersionUtils.h>
@@ -51,42 +52,32 @@
if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
return OK;
}
- const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
- if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
- if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
- || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ if (getAudioDeviceOutAllA2dpSet().count(device) > 0
+ || device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
int status = sscanf(halAddress,
"%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
&address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
&address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
return status == 6 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
- || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+ } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
int status = sscanf(halAddress,
"%hhu.%hhu.%hhu.%hhu",
&address->address.ipv4[0], &address->address.ipv4[1],
&address->address.ipv4[2], &address->address.ipv4[3]);
return status == 4 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
- || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+ } else if (getAudioDeviceOutAllUsbSet().count(device) > 0
+ || getAudioDeviceInAllUsbSet().count(device) > 0) {
int status = sscanf(halAddress,
"card=%d;device=%d",
&address->address.alsa.card, &address->address.alsa.device);
return status == 2 ? OK : BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
- || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
- if (halAddress != NULL) {
- address->busAddress = halAddress;
- return OK;
- }
- return BAD_VALUE;
- } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
- || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
- if (halAddress != NULL) {
- address->rSubmixAddress = halAddress;
- return OK;
- }
- return BAD_VALUE;
+ } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
+ address->busAddress = halAddress;
+ return OK;
+ } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+ || device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
+ address->rSubmixAddress = halAddress;
+ return OK;
}
return OK;
}
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 1335a0c..c30da3c 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -20,6 +20,7 @@
#define LOG_TAG "DevicesFactoryHalHidl"
//#define LOG_NDEBUG 0
+#include "android/hidl/manager/1.0/IServiceManager.h"
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
#include <media/audiohal/hidl/HalDeathHandler.h>
#include <utils/Log.h>
@@ -28,6 +29,8 @@
#include "DeviceHalHidl.h"
#include "DevicesFactoryHalHidl.h"
+#include <set>
+
using ::android::hardware::audio::CPP_VERSION::IDevice;
using ::android::hardware::audio::CPP_VERSION::Result;
using ::android::hardware::Return;
@@ -108,5 +111,29 @@
return BAD_VALUE;
}
+status_t DevicesFactoryHalHidl::getHalPids(std::vector<pid_t> *pids) {
+ std::set<pid_t> pidsSet;
+
+ for (const auto& factory : mDeviceFactories) {
+ using ::android::hidl::base::V1_0::DebugInfo;
+ using android::hidl::manager::V1_0::IServiceManager;
+
+ DebugInfo debugInfo;
+ auto ret = factory->getDebugInfo([&] (const auto &info) {
+ debugInfo = info;
+ });
+ if (!ret.isOk()) {
+ return INVALID_OPERATION;
+ }
+ if (debugInfo.pid == (int)IServiceManager::PidConstant::NO_PID) {
+ continue;
+ }
+ pidsSet.insert(debugInfo.pid);
+ }
+
+ *pids = {pidsSet.begin(), pidsSet.end()};
+ return NO_ERROR;
+}
+
} // namespace CPP_VERSION
} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index 8775e7b..52185c8 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -37,6 +37,9 @@
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+
+ status_t getHalPids(std::vector<pid_t> *pids) override;
+
private:
std::vector<sp<IDevicesFactory>> mDeviceFactories;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
index 0e1f1bb..a5aef1b 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -37,6 +37,14 @@
}
return mLocalFactory->openDevice(name, device);
}
+
+status_t DevicesFactoryHalHybrid::getHalPids(std::vector<pid_t> *pids) {
+ if (mHidlFactory != 0) {
+ return mHidlFactory->getHalPids(pids);
+ }
+ return INVALID_OPERATION;
+}
+
} // namespace CPP_VERSION
template <>
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
index 545bb70..2189b36 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
@@ -36,6 +36,8 @@
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+ status_t getHalPids(std::vector<pid_t> *pids) override;
+
private:
sp<DevicesFactoryHalInterface> mLocalFactory;
sp<DevicesFactoryHalInterface> mHidlFactory;
diff --git a/media/libaudiohal/impl/DevicesFactoryHalLocal.h b/media/libaudiohal/impl/DevicesFactoryHalLocal.h
index 5d108dd..2b011f4 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalLocal.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalLocal.h
@@ -33,6 +33,10 @@
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+ status_t getHalPids(std::vector<pid_t> *pids __unused) override {
+ return INVALID_OPERATION;
+ }
+
private:
friend class DevicesFactoryHalHybrid;
diff --git a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
index 14af384..e9ac1ce 100644
--- a/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DevicesFactoryHalInterface.h
@@ -20,6 +20,7 @@
#include <media/audiohal/DeviceHalInterface.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include <vector>
namespace android {
@@ -30,6 +31,8 @@
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device) = 0;
+ virtual status_t getHalPids(std::vector<pid_t> *pids) = 0;
+
static sp<DevicesFactoryHalInterface> create();
protected:
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 8a9039c..5047b19 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -51,6 +51,10 @@
"libmedia_headers",
],
+ include_dirs: [
+ // For DEBUGGER_SIGNAL
+ "system/core/debuggerd/include",
+ ],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
}
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 265a232..4a3e470 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -14,13 +14,50 @@
* limitations under the License.
*/
+#define LOG_TAG "TimeCheck"
#include <utils/Log.h>
#include <mediautils/TimeCheck.h>
#include <mediautils/EventLog.h>
+#include "debuggerd/handler.h"
namespace android {
+// Audio HAL server pids vector used to generate audio HAL processes tombstone
+// when audioserver watchdog triggers.
+// We use a lockless storage to avoid potential deadlocks in the context of watchdog
+// trigger.
+// Protection again simultaneous writes is not needed given one update takes place
+// during AudioFlinger construction and other comes necessarily later once the IAudioFlinger
+// interface is available.
+// The use of an atomic index just guaranties that current vector is fully initialized
+// when read.
+/* static */
+void TimeCheck::accessAudioHalPids(std::vector<pid_t>* pids, bool update) {
+ static constexpr int kNumAudioHalPidsVectors = 3;
+ static std::vector<pid_t> audioHalPids[kNumAudioHalPidsVectors];
+ static std::atomic<int> curAudioHalPids = 0;
+
+ if (update) {
+ audioHalPids[(curAudioHalPids + 1) % kNumAudioHalPidsVectors] = *pids;
+ curAudioHalPids++;
+ } else {
+ *pids = audioHalPids[curAudioHalPids];
+ }
+}
+
+/* static */
+void TimeCheck::setAudioHalPids(const std::vector<pid_t>& pids) {
+ accessAudioHalPids(&(const_cast<std::vector<pid_t>&>(pids)), true);
+}
+
+/* static */
+std::vector<pid_t> TimeCheck::getAudioHalPids() {
+ std::vector<pid_t> pids;
+ accessAudioHalPids(&pids, false);
+ return pids;
+}
+
/* static */
sp<TimeCheck::TimeCheckThread> TimeCheck::getTimeCheckThread()
{
@@ -82,10 +119,22 @@
if (waitTimeNs > 0) {
status = mCond.waitRelative(mMutex, waitTimeNs);
}
- }
- if (status != NO_ERROR) {
- LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
- LOG_ALWAYS_FATAL("TimeCheck timeout for %s", tag);
+ if (status != NO_ERROR) {
+ // Generate audio HAL processes tombstones and allow time to complete
+ // before forcing restart
+ std::vector<pid_t> pids = getAudioHalPids();
+ if (pids.size() != 0) {
+ for (const auto& pid : pids) {
+ ALOGI("requesting tombstone for pid: %d", pid);
+ sigqueue(pid, DEBUGGER_SIGNAL, {.sival_int = 0});
+ }
+ sleep(1);
+ } else {
+ ALOGI("No HAL process pid available, skipping tombstones");
+ }
+ LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
+ LOG_ALWAYS_FATAL("TimeCheck timeout for %s", tag);
+ }
}
return true;
}
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index 6c5f656..5ba6d7c 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -20,7 +20,7 @@
#include <utils/KeyedVector.h>
#include <utils/Thread.h>
-
+#include <vector>
namespace android {
@@ -35,6 +35,8 @@
TimeCheck(const char *tag, uint32_t timeoutMs = kDefaultTimeOutMs);
~TimeCheck();
+ static void setAudioHalPids(const std::vector<pid_t>& pids);
+ static std::vector<pid_t> getAudioHalPids();
private:
@@ -63,6 +65,7 @@
};
static sp<TimeCheckThread> getTimeCheckThread();
+ static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);
const nsecs_t mEndTimeNs;
};
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index e722995..525ac68 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -70,6 +70,7 @@
#include <media/nbaio/PipeReader.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/ServiceUtilities.h>
+#include <mediautils/TimeCheck.h>
#include <private/android_filesystem_config.h>
//#define BUFLOG_NDEBUG 0
@@ -193,6 +194,9 @@
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
mMediaLogNotifier->run("MediaLogNotifier");
+ std::vector<pid_t> halPids;
+ mDevicesFactoryHal->getHalPids(&halPids);
+ TimeCheck::setAudioHalPids(halPids);
}
void AudioFlinger::onFirstRef()
@@ -218,6 +222,11 @@
gAudioFlinger = this;
}
+status_t AudioFlinger::setAudioHalPids(const std::vector<pid_t>& pids) {
+ TimeCheck::setAudioHalPids(pids);
+ return NO_ERROR;
+}
+
AudioFlinger::~AudioFlinger()
{
while (!mRecordThreads.isEmpty()) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 29d6ec6..9e3ec92 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -281,6 +281,8 @@
virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
+
virtual status_t onTransact(
uint32_t code,
const Parcel& data,
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 13152d0..ee7a6d6 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -29,7 +29,9 @@
#include <system/audio_effects/effect_visualizer.h>
#include <audio_utils/channels.h>
#include <audio_utils/primitives.h>
+#include <media/AudioContainers.h>
#include <media/AudioEffect.h>
+#include <media/AudioDeviceTypeAddr.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <mediautils/ServiceUtilities.h>
@@ -1229,9 +1231,11 @@
}
}
-status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
+status_t AudioFlinger::EffectModule::sendSetAudioDevicesCommand(
+ const AudioDeviceTypeAddrVector &devices, uint32_t cmdCode)
{
- if (device == AUDIO_DEVICE_NONE) {
+ audio_devices_t deviceType = deviceTypesToBitMask(getAudioDeviceTypes(devices));
+ if (deviceType == AUDIO_DEVICE_NONE) {
return NO_ERROR;
}
@@ -1243,17 +1247,26 @@
if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
status_t cmdStatus;
uint32_t size = sizeof(status_t);
- uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
- EFFECT_CMD_SET_INPUT_DEVICE;
- status = mEffectInterface->command(cmd,
+ // FIXME: use audio device types and addresses when the hal interface is ready.
+ status = mEffectInterface->command(cmdCode,
sizeof(uint32_t),
- &device,
+ &deviceType,
&size,
&cmdStatus);
}
return status;
}
+status_t AudioFlinger::EffectModule::setDevices(const AudioDeviceTypeAddrVector &devices)
+{
+ return sendSetAudioDevicesCommand(devices, EFFECT_CMD_SET_DEVICE);
+}
+
+status_t AudioFlinger::EffectModule::setInputDevice(const AudioDeviceTypeAddr &device)
+{
+ return sendSetAudioDevicesCommand({device}, EFFECT_CMD_SET_INPUT_DEVICE);
+}
+
status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
{
Mutex::Autolock _l(mLock);
@@ -2288,12 +2301,21 @@
return mEffects.size();
}
-// setDevice_l() must be called with ThreadBase::mLock held
-void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
+// setDevices_l() must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setDevices_l(const AudioDeviceTypeAddrVector &devices)
{
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
- mEffects[i]->setDevice(device);
+ mEffects[i]->setDevices(devices);
+ }
+}
+
+// setInputDevice_l() must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setInputDevice_l(const AudioDeviceTypeAddr &device)
+{
+ size_t size = mEffects.size();
+ for (size_t i = 0; i < size; i++) {
+ mEffects[i]->setInputDevice(device);
}
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 220874d..dbf63c8 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -109,7 +109,8 @@
const effect_descriptor_t& desc() const { return mDescriptor; }
wp<EffectChain>& chain() { return mChain; }
- status_t setDevice(audio_devices_t device);
+ status_t setDevices(const AudioDeviceTypeAddrVector &devices);
+ status_t setInputDevice(const AudioDeviceTypeAddr &device);
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(audio_mode_t mode);
status_t setAudioSource(audio_source_t source);
@@ -158,6 +159,7 @@
status_t start_l();
status_t stop_l();
status_t remove_effect_from_hal_l();
+ status_t sendSetAudioDevicesCommand(const AudioDeviceTypeAddrVector &devices, uint32_t cmdCode);
mutable Mutex mLock; // mutex for process, commands and handles list protection
wp<ThreadBase> mThread; // parent thread
@@ -350,7 +352,8 @@
// FIXME use float to improve the dynamic range
bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false);
void resetVolume_l();
- void setDevice_l(audio_devices_t device);
+ void setDevices_l(const AudioDeviceTypeAddrVector &devices);
+ void setInputDevice_l(const AudioDeviceTypeAddr &device);
void setMode_l(audio_mode_t mode);
void setAudioSource_l(audio_source_t source);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 59ffff1..06ba8b0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1378,8 +1378,8 @@
effectCreated = true;
// FIXME: use vector of device and address when effect interface is ready.
- effect->setDevice(deviceTypesToBitMask(outDeviceTypes()));
- effect->setDevice(inDeviceType());
+ effect->setDevices(outDeviceTypeAddrs());
+ effect->setInputDevice(inDeviceTypeAddr());
effect->setMode(mAudioFlinger->getMode());
effect->setAudioSource(mAudioSource);
}
@@ -1495,8 +1495,8 @@
return status;
}
- effect->setDevice(deviceTypesToBitMask(outDeviceTypes()));
- effect->setDevice(inDeviceType());
+ effect->setDevices(outDeviceTypeAddrs());
+ effect->setInputDevice(inDeviceTypeAddr());
effect->setMode(mAudioFlinger->getMode());
effect->setAudioSource(mAudioSource);
@@ -1825,7 +1825,7 @@
// TODO: We may also match on address as well as device type for
// AUDIO_DEVICE_OUT_BUS, AUDIO_DEVICE_OUT_ALL_A2DP, AUDIO_DEVICE_OUT_REMOTE_SUBMIX
- if (type == MIXER || type == DIRECT) {
+ if (type == MIXER || type == DIRECT || type == OFFLOAD) {
// TODO: This property should be ensure that only contains one single device type.
mTimestampCorrectedDevice = (audio_devices_t)property_get_int64(
"audio.timestamp.corrected_output_device",
@@ -4070,7 +4070,7 @@
#endif
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(type);
+ mEffectChains[i]->setDevices_l(deviceTypeAddrs);
}
// mPatch.num_sinks is not set when the thread is created so that
@@ -8321,7 +8321,7 @@
mInDeviceTypeAddr.mAddress = patch->sources[0].ext.device.address;
audio_port_handle_t deviceId = patch->sources[0].id;
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(mInDeviceTypeAddr.mType);
+ mEffectChains[i]->setInputDevice_l(inDeviceTypeAddr());
}
checkBtNrec_l();
@@ -8391,7 +8391,7 @@
mOutDevices = outDevices;
mOutDeviceTypeAddrs = deviceTypeAddrsFromDescriptors(mOutDevices);
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(deviceTypesToBitMask(outDeviceTypes()));
+ mEffectChains[i]->setDevices_l(outDeviceTypeAddrs());
}
}
@@ -8922,7 +8922,11 @@
}
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->setDevice_l(type);
+ if (isOutput()) {
+ mEffectChains[i]->setDevices_l(sinkDeviceTypeAddrs);
+ } else {
+ mEffectChains[i]->setInputDevice_l(sourceDeviceTypeAddr);
+ }
}
if (!isOutput()) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index a7660f3..8de7632 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -321,6 +321,13 @@
return isOutput() ? outDeviceTypes() : DeviceTypeSet({inDeviceType()});
}
+ const AudioDeviceTypeAddrVector& outDeviceTypeAddrs() const {
+ return mOutDeviceTypeAddrs;
+ }
+ const AudioDeviceTypeAddr& inDeviceTypeAddr() const {
+ return mInDeviceTypeAddr;
+ }
+
virtual bool isOutput() const = 0;
virtual sp<StreamHalInterface> stream() const = 0;
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 7faf90e..a6562d7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -33,9 +33,13 @@
{
public:
// Note that empty name refers by convention to a generic device.
- explicit DeviceDescriptor(audio_devices_t type, const std::string &tagName = "");
- DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
- const std::string &tagName = "");
+ explicit DeviceDescriptor(audio_devices_t type);
+ DeviceDescriptor(audio_devices_t type, const std::string &tagName,
+ const FormatVector &encodedFormats = FormatVector{});
+ DeviceDescriptor(audio_devices_t type, const std::string &tagName,
+ const std::string &address, const FormatVector &encodedFormats = FormatVector{});
+ DeviceDescriptor(const AudioDeviceTypeAddr &deviceTypeAddr, const std::string &tagName = "",
+ const FormatVector &encodedFormats = FormatVector{});
virtual ~DeviceDescriptor() {}
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 993c3a1..86dbba8 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -26,14 +26,30 @@
namespace android {
-DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const std::string &tagName) :
- DeviceDescriptor(type, FormatVector{}, tagName)
+DeviceDescriptor::DeviceDescriptor(audio_devices_t type) :
+ DeviceDescriptor(type, "" /*tagName*/)
{
}
-DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
- const std::string &tagName) :
- DeviceDescriptorBase(type), mTagName(tagName), mEncodedFormats(encodedFormats)
+DeviceDescriptor::DeviceDescriptor(audio_devices_t type,
+ const std::string &tagName,
+ const FormatVector &encodedFormats) :
+ DeviceDescriptor(type, tagName, "" /*address*/, encodedFormats)
+{
+}
+
+DeviceDescriptor::DeviceDescriptor(audio_devices_t type,
+ const std::string &tagName,
+ const std::string &address,
+ const FormatVector &encodedFormats) :
+ DeviceDescriptor(AudioDeviceTypeAddr(type, address), tagName, encodedFormats)
+{
+}
+
+DeviceDescriptor::DeviceDescriptor(const AudioDeviceTypeAddr &deviceTypeAddr,
+ const std::string &tagName,
+ const FormatVector &encodedFormats) :
+ DeviceDescriptorBase(deviceTypeAddr), mTagName(tagName), mEncodedFormats(encodedFormats)
{
mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
/* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
@@ -41,7 +57,7 @@
* For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
* something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
*/
- if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
+ if (mDeviceTypeAddr.mType == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
mEncodedFormats.push_back(AUDIO_FORMAT_AC3);
mEncodedFormats.push_back(AUDIO_FORMAT_IEC61937);
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 0b4d3d4..886e4c9 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -49,8 +49,7 @@
profile->addAudioProfile(new AudioProfile(config->format, config->channel_mask,
config->sample_rate));
- sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
- devDesc->setAddress(address.string());
+ sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, "" /*tagName*/, address.string());
addDynamicDevice(devDesc);
// Reciprocally attach the device to the module
devDesc->attach(this);
@@ -117,8 +116,7 @@
profile->addAudioProfile(new AudioProfile(config->format, config->channel_mask,
config->sample_rate));
- sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
- devDesc->setAddress(address.string());
+ sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device, "" /*tagName*/, address.string());
addDynamicDevice(devDesc);
// Reciprocally attach the device to the module
devDesc->attach(this);
@@ -360,9 +358,9 @@
address);
return nullptr;
}
- sp<DeviceDescriptor> device = new DeviceDescriptor(type, name);
+
+ sp<DeviceDescriptor> device = new DeviceDescriptor(type, name, address);
device->setName(name);
- device->setAddress(address);
device->setEncodedFormat(encodedFormat);
// Add the device to the list of dynamic devices
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 3b27cf6..4de8d3b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -511,13 +511,8 @@
if (!encodedFormatsLiteral.empty()) {
encodedFormats = formatsFromString(encodedFormatsLiteral, " ");
}
- Element deviceDesc = new DeviceDescriptor(type, encodedFormats, name);
-
std::string address = getXmlAttribute(cur, Attributes::address);
- if (!address.empty()) {
- ALOGV("%s: address=%s for %s", __func__, address.c_str(), name.c_str());
- deviceDesc->setAddress(address);
- }
+ Element deviceDesc = new DeviceDescriptor(type, name, address, encodedFormats);
AudioProfileTraits::Collection profiles;
status_t status = deserializeCollection<AudioProfileTraits>(cur, &profiles, NULL);
diff --git a/services/oboeservice/AAudioClientTracker.cpp b/services/oboeservice/AAudioClientTracker.cpp
index 8572561..6e14434 100644
--- a/services/oboeservice/AAudioClientTracker.cpp
+++ b/services/oboeservice/AAudioClientTracker.cpp
@@ -75,10 +75,10 @@
std::lock_guard<std::mutex> lock(mLock);
if (mNotificationClients.count(pid) == 0) {
- sp<NotificationClient> notificationClient = new NotificationClient(pid);
+ sp<IBinder> binder = IInterface::asBinder(client);
+ sp<NotificationClient> notificationClient = new NotificationClient(pid, binder);
mNotificationClients[pid] = notificationClient;
- sp<IBinder> binder = IInterface::asBinder(client);
status_t status = binder->linkToDeath(notificationClient);
ALOGW_IF(status != NO_ERROR, "registerClient() linkToDeath = %d\n", status);
return AAudioConvert_androidToAAudioResult(status);
@@ -113,7 +113,7 @@
if (notificationClient == 0) {
// This will get called the first time the audio server registers an internal stream.
ALOGV("registerClientStream(%d,) unrecognized pid\n", pid);
- notificationClient = new NotificationClient(pid);
+ notificationClient = new NotificationClient(pid, nullptr);
mNotificationClients[pid] = notificationClient;
}
notificationClient->registerClientStream(serviceStream);
@@ -136,8 +136,8 @@
return AAUDIO_OK;
}
-AAudioClientTracker::NotificationClient::NotificationClient(pid_t pid)
- : mProcessId(pid) {
+AAudioClientTracker::NotificationClient::NotificationClient(pid_t pid, const sp<IBinder>& binder)
+ : mProcessId(pid), mBinder(binder) {
}
AAudioClientTracker::NotificationClient::~NotificationClient() {
diff --git a/services/oboeservice/AAudioClientTracker.h b/services/oboeservice/AAudioClientTracker.h
index accf1a7..00ff467 100644
--- a/services/oboeservice/AAudioClientTracker.h
+++ b/services/oboeservice/AAudioClientTracker.h
@@ -73,7 +73,7 @@
*/
class NotificationClient : public IBinder::DeathRecipient {
public:
- NotificationClient(pid_t pid);
+ NotificationClient(pid_t pid, const android::sp<IBinder>& binder);
virtual ~NotificationClient();
int32_t getStreamCount();
@@ -91,6 +91,8 @@
mutable std::mutex mLock;
const pid_t mProcessId;
std::set<android::sp<AAudioServiceStreamBase>> mStreams;
+ // hold onto binder to receive death notifications
+ android::sp<IBinder> mBinder;
};
mutable std::mutex mLock;