blob: 65b17bc8f7c19ec60f7067cc73eec64272f49536 [file] [log] [blame]
Phil Burkc0c70e32017-02-09 13:18:38 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Phil Burk71f35bb2017-04-13 16:05:07 -070017#define LOG_TAG "AAudioService"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20
Phil Burkc0c70e32017-02-09 13:18:38 -080021#include <assert.h>
22#include <map>
23#include <mutex>
24#include <utils/Singleton.h>
25
26#include "AAudioEndpointManager.h"
27#include "AAudioServiceEndpoint.h"
28
29using namespace android;
30using namespace aaudio;
31
32ANDROID_SINGLETON_STATIC_INSTANCE(AAudioEndpointManager);
33
34AAudioEndpointManager::AAudioEndpointManager()
Phil Burk71f35bb2017-04-13 16:05:07 -070035 : Singleton<AAudioEndpointManager>()
36 , mInputs()
37 , mOutputs() {
Phil Burkc0c70e32017-02-09 13:18:38 -080038}
39
Phil Burk71f35bb2017-04-13 16:05:07 -070040AAudioServiceEndpoint *AAudioEndpointManager::openEndpoint(AAudioService &audioService, int32_t deviceId,
Phil Burkc0c70e32017-02-09 13:18:38 -080041 aaudio_direction_t direction) {
42 AAudioServiceEndpoint *endpoint = nullptr;
43 std::lock_guard<std::mutex> lock(mLock);
Phil Burk71f35bb2017-04-13 16:05:07 -070044
45 // Try to find an existing endpoint.
46 ALOGD("AAudioEndpointManager::openEndpoint(), device = %d, dir = %d", deviceId, direction);
Phil Burkc0c70e32017-02-09 13:18:38 -080047 switch (direction) {
48 case AAUDIO_DIRECTION_INPUT:
49 endpoint = mInputs[deviceId];
50 break;
51 case AAUDIO_DIRECTION_OUTPUT:
52 endpoint = mOutputs[deviceId];
53 break;
54 default:
55 assert(false); // There are only two possible directions.
56 break;
57 }
58
59 // If we can't find an existing one then open one.
Phil Burk71f35bb2017-04-13 16:05:07 -070060 ALOGD("AAudioEndpointManager::openEndpoint(), found %p", endpoint);
Phil Burkc0c70e32017-02-09 13:18:38 -080061 if (endpoint == nullptr) {
62 endpoint = new AAudioServiceEndpoint(audioService);
63 if (endpoint->open(deviceId, direction) != AAUDIO_OK) {
Phil Burk71f35bb2017-04-13 16:05:07 -070064 ALOGE("AAudioEndpointManager::findEndpoint(), open failed");
Phil Burkc0c70e32017-02-09 13:18:38 -080065 delete endpoint;
66 endpoint = nullptr;
67 } else {
68 switch(direction) {
69 case AAUDIO_DIRECTION_INPUT:
70 mInputs[deviceId] = endpoint;
71 break;
72 case AAUDIO_DIRECTION_OUTPUT:
73 mOutputs[deviceId] = endpoint;
74 break;
75 }
76 }
77 }
Phil Burk71f35bb2017-04-13 16:05:07 -070078
79 if (endpoint != nullptr) {
80 // Increment the reference count under this lock.
81 endpoint->setReferenceCount(endpoint->getReferenceCount() + 1);
82 }
83
Phil Burkc0c70e32017-02-09 13:18:38 -080084 return endpoint;
85}
86
Phil Burk71f35bb2017-04-13 16:05:07 -070087void AAudioEndpointManager::closeEndpoint(AAudioServiceEndpoint *serviceEndpoint) {
Phil Burkc0c70e32017-02-09 13:18:38 -080088 std::lock_guard<std::mutex> lock(mLock);
Phil Burk71f35bb2017-04-13 16:05:07 -070089 if (serviceEndpoint == nullptr) {
90 return;
Phil Burkc0c70e32017-02-09 13:18:38 -080091 }
Phil Burk71f35bb2017-04-13 16:05:07 -070092
93 // Decrement the reference count under this lock.
94 int32_t newRefCount = serviceEndpoint->getReferenceCount() - 1;
95 serviceEndpoint->setReferenceCount(newRefCount);
96 if (newRefCount <= 0) {
97 aaudio_direction_t direction = serviceEndpoint->getDirection();
98 int32_t deviceId = serviceEndpoint->getDeviceId();
99
100 switch (direction) {
101 case AAUDIO_DIRECTION_INPUT:
102 mInputs.erase(deviceId);
103 break;
104 case AAUDIO_DIRECTION_OUTPUT:
105 mOutputs.erase(deviceId);
106 break;
107 }
108 serviceEndpoint->close();
109 delete serviceEndpoint;
110 }
111}