111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk/* 211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * Copyright (C) 2017 The Android Open Source Project 311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * 411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * you may not use this file except in compliance with the License. 611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * You may obtain a copy of the License at 711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * 811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * 1011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * Unless required by applicable law or agreed to in writing, software 1111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 1211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * See the License for the specific language governing permissions and 1411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk * limitations under the License. 1511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk */ 1611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 1711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 18fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk#define LOG_TAG "AAudioClientTracker" 1911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk//#define LOG_NDEBUG 0 2011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <utils/Log.h> 2111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 2211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <assert.h> 2311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <binder/IPCThreadState.h> 2455e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk#include <iomanip> 2555e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk#include <iostream> 2611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <map> 2711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <mutex> 2811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <utils/Singleton.h> 2911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 3011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include "utility/AAudioUtilities.h" 3111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include "AAudioEndpointManager.h" 3211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include "AAudioServiceEndpoint.h" 3311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include "AAudioClientTracker.h" 3411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 3511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkusing namespace android; 3611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkusing namespace aaudio; 3711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 3811e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkANDROID_SINGLETON_STATIC_INSTANCE(AAudioClientTracker); 3911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 4011e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioClientTracker::AAudioClientTracker() 4111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk : Singleton<AAudioClientTracker>() { 4211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 4311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 444501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burkstd::string AAudioClientTracker::dump() const { 454501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk std::stringstream result; 464501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk const bool isLocked = AAudio_tryUntilTrue( 474501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk [this]()->bool { return mLock.try_lock(); } /* f */, 484501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 50 /* times */, 494501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 20 /* sleepMs */); 504501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk if (!isLocked) { 514501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk result << "AAudioClientTracker may be deadlocked\n"; 524501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } 534501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 544501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk result << "AAudioClientTracker:\n"; 554501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk for (const auto& it : mNotificationClients) { 564501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk result << it.second->dump(); 574501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } 584501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 594501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk if (isLocked) { 604501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk mLock.unlock(); 614501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } 624501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk return result.str(); 634501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk} 644501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 6511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk// Create a tracker for the client. 6611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkaaudio_result_t AAudioClientTracker::registerClient(pid_t pid, 6711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk const sp<IAAudioClient>& client) { 68fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("registerClient(), calling pid = %d, getpid() = %d\n", pid, getpid()); 6911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 7011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 7111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk if (mNotificationClients.count(pid) == 0) { 7211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<NotificationClient> notificationClient = new NotificationClient(pid); 7311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mNotificationClients[pid] = notificationClient; 7411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 7511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<IBinder> binder = IInterface::asBinder(client); 7611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk status_t status = binder->linkToDeath(notificationClient); 77fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGW_IF(status != NO_ERROR, "registerClient() linkToDeath = %d\n", status); 7811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return AAudioConvert_androidToAAudioResult(status); 7911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } else { 80fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGW("registerClient(%d) already registered!", pid); 8111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return AAUDIO_OK; // TODO should this be considered an error 8211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 8311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 8411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 8511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkvoid AAudioClientTracker::unregisterClient(pid_t pid) { 86fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("unregisterClient(), calling pid = %d, getpid() = %d\n", pid, getpid()); 8711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 8811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mNotificationClients.erase(pid); 8911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 9011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 919169294539ad46e08e2fe76a93c37ed965c13058Phil Burkint32_t AAudioClientTracker::getStreamCount(pid_t pid) { 929169294539ad46e08e2fe76a93c37ed965c13058Phil Burk std::lock_guard<std::mutex> lock(mLock); 939169294539ad46e08e2fe76a93c37ed965c13058Phil Burk auto it = mNotificationClients.find(pid); 949169294539ad46e08e2fe76a93c37ed965c13058Phil Burk if (it != mNotificationClients.end()) { 959169294539ad46e08e2fe76a93c37ed965c13058Phil Burk return it->second->getStreamCount(); 969169294539ad46e08e2fe76a93c37ed965c13058Phil Burk } else { 979169294539ad46e08e2fe76a93c37ed965c13058Phil Burk return 0; // no existing client 989169294539ad46e08e2fe76a93c37ed965c13058Phil Burk } 999169294539ad46e08e2fe76a93c37ed965c13058Phil Burk} 1009169294539ad46e08e2fe76a93c37ed965c13058Phil Burk 10111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkaaudio_result_t 10211e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioClientTracker::registerClientStream(pid_t pid, sp<AAudioServiceStreamBase> serviceStream) { 10311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk aaudio_result_t result = AAUDIO_OK; 104fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("registerClientStream(%d, %p)\n", pid, serviceStream.get()); 10511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 10611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<NotificationClient> notificationClient = mNotificationClients[pid]; 10711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk if (notificationClient == 0) { 10811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // This will get called the first time the audio server registers an internal stream. 109fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("registerClientStream(%d,) unrecognized pid\n", pid); 11011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk notificationClient = new NotificationClient(pid); 11111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mNotificationClients[pid] = notificationClient; 11211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 11311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk notificationClient->registerClientStream(serviceStream); 11411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return result; 11511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 11611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 11711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk// Find the tracker for this process and remove it. 11811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkaaudio_result_t 11911e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioClientTracker::unregisterClientStream(pid_t pid, 12011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<AAudioServiceStreamBase> serviceStream) { 121fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("unregisterClientStream(%d, %p)\n", pid, serviceStream.get()); 12211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 1239169294539ad46e08e2fe76a93c37ed965c13058Phil Burk auto it = mNotificationClients.find(pid); 12411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk if (it != mNotificationClients.end()) { 125fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("unregisterClientStream(%d, %p) found NotificationClient\n", 1264501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk pid, serviceStream.get()); 12711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk it->second->unregisterClientStream(serviceStream); 1284501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } else { 129fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("unregisterClientStream(%d, %p) missing NotificationClient\n", 1304501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk pid, serviceStream.get()); 13111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 13211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return AAUDIO_OK; 13311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 13411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 13511e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioClientTracker::NotificationClient::NotificationClient(pid_t pid) 13611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk : mProcessId(pid) { 137fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk //ALOGD("NotificationClient(%d) created %p\n", pid, this); 13811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 13911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 14011e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioClientTracker::NotificationClient::~NotificationClient() { 141fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk //ALOGD("~NotificationClient() destroyed %p\n", this); 14211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 14311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 1449169294539ad46e08e2fe76a93c37ed965c13058Phil Burkint32_t AAudioClientTracker::NotificationClient::getStreamCount() { 1459169294539ad46e08e2fe76a93c37ed965c13058Phil Burk std::lock_guard<std::mutex> lock(mLock); 1469169294539ad46e08e2fe76a93c37ed965c13058Phil Burk return mStreams.size(); 1479169294539ad46e08e2fe76a93c37ed965c13058Phil Burk} 1489169294539ad46e08e2fe76a93c37ed965c13058Phil Burk 14911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkaaudio_result_t AAudioClientTracker::NotificationClient::registerClientStream( 15011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<AAudioServiceStreamBase> serviceStream) { 15111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 15211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mStreams.insert(serviceStream); 15311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return AAUDIO_OK; 15411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 15511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 15611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkaaudio_result_t AAudioClientTracker::NotificationClient::unregisterClientStream( 15711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<AAudioServiceStreamBase> serviceStream) { 15811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 15911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mStreams.erase(serviceStream); 16011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return AAUDIO_OK; 16111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 16211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 16311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk// Close any open streams for the client. 16411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkvoid AAudioClientTracker::NotificationClient::binderDied(const wp<IBinder>& who __unused) { 16511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk AAudioService *aaudioService = AAudioClientTracker::getInstance().getAAudioService(); 16611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk if (aaudioService != nullptr) { 16711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // Copy the current list of streams to another vector because closing them below 16811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // will cause unregisterClientStream() calls back to this object. 1694501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk std::set<sp<AAudioServiceStreamBase>> streamsToClose; 17011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 17111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk { 17211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk std::lock_guard<std::mutex> lock(mLock); 17348fc6191823ffa0708f60802fb6724c232760b9aChih-Hung Hsieh for (const auto& serviceStream : mStreams) { 17411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk streamsToClose.insert(serviceStream); 17511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 17611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 17711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 17848fc6191823ffa0708f60802fb6724c232760b9aChih-Hung Hsieh for (const auto& serviceStream : streamsToClose) { 17911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk aaudio_handle_t handle = serviceStream->getHandle(); 180fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGW("binderDied() close abandoned stream 0x%08X\n", handle); 18111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk aaudioService->closeStream(handle); 18211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 18311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // mStreams should be empty now 18411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 18511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<NotificationClient> keep(this); 18611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk AAudioClientTracker::getInstance().unregisterClient(mProcessId); 18711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 1884501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 1894501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 1904501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burkstd::string AAudioClientTracker::NotificationClient::dump() const { 1914501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk std::stringstream result; 1924501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk const bool isLocked = AAudio_tryUntilTrue( 1934501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk [this]()->bool { return mLock.try_lock(); } /* f */, 1944501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 50 /* times */, 1954501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 20 /* sleepMs */); 1964501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk if (!isLocked) { 1974501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk result << "AAudioClientTracker::NotificationClient may be deadlocked\n"; 1984501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } 1994501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 2004501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk result << " client: pid = " << mProcessId << " has " << mStreams.size() << " streams\n"; 20148fc6191823ffa0708f60802fb6724c232760b9aChih-Hung Hsieh for (const auto& serviceStream : mStreams) { 20255e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk result << " stream: 0x" << std::setfill('0') << std::setw(8) << std::hex 20355e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk << serviceStream->getHandle() 20455e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk << std::dec << std::setfill(' ') << "\n"; 2054501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } 2064501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk 2074501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk if (isLocked) { 2084501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk mLock.unlock(); 2094501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk } 2104501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk return result.str(); 2114501b3510f9b2af2ff63a0471de24e3feea1d0a8Phil Burk} 212