1 /*
2  * Copyright (C) 2015 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 
17 #define LOG_TAG "APM::SessionRoute"
18 //#define LOG_NDEBUG 0
19 
20 #include "SessionRoute.h"
21 #include "HwModule.h"
22 #include "AudioGain.h"
23 #include "DeviceDescriptor.h"
24 #include <utils/Log.h>
25 
26 namespace android {
27 
28 // --- SessionRoute class implementation
log(const char * prefix)29 void SessionRoute::log(const char* prefix)
30 {
31     ALOGI("%s[SessionRoute strm:0x%X, src:%d, sess:0x%X, dev:0x%X refs:%d act:%d",
32           prefix, mStreamType, mSource, mSession,
33           mDeviceDescriptor != 0 ? mDeviceDescriptor->type() : AUDIO_DEVICE_NONE,
34           mRefCount, mActivityCount);
35 }
36 
37 // --- SessionRouteMap class implementation
hasRoute(audio_session_t session)38 bool SessionRouteMap::hasRoute(audio_session_t session)
39 {
40     return indexOfKey(session) >= 0 && valueFor(session)->mDeviceDescriptor != 0;
41 }
42 
getAndClearRouteChanged(audio_session_t session)43 bool SessionRouteMap::getAndClearRouteChanged(audio_session_t session)
44 {
45     if (indexOfKey(session) >= 0) {
46         if (valueFor(session)->mChanged) {
47             valueFor(session)->mChanged = false;
48             return true;
49         }
50     }
51     return false;
52 }
53 
removeRoute(audio_session_t session)54 void SessionRouteMap::removeRoute(audio_session_t session)
55 {
56     sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
57     if (route != 0) {
58         ALOG_ASSERT(route->mRefCount > 0);
59         --route->mRefCount;
60         if (route->mRefCount <= 0) {
61             removeItem(session);
62         }
63     }
64 }
65 
incRouteActivity(audio_session_t session)66 int SessionRouteMap::incRouteActivity(audio_session_t session)
67 {
68     sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
69     return route != 0 ? ++(route->mActivityCount) : -1;
70 }
71 
decRouteActivity(audio_session_t session)72 int SessionRouteMap::decRouteActivity(audio_session_t session)
73 {
74     sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
75     if (route != 0 && route->mActivityCount > 0) {
76         return --(route->mActivityCount);
77     } else {
78         return -1;
79     }
80 }
81 
log(const char * caption)82 void SessionRouteMap::log(const char* caption)
83 {
84     ALOGI("%s ----", caption);
85     for (size_t index = 0; index < size(); index++) {
86         valueAt(index)->log("  ");
87     }
88 }
89 
addRoute(audio_session_t session,audio_stream_type_t streamType,audio_source_t source,const sp<DeviceDescriptor> & descriptor,uid_t uid)90 void SessionRouteMap::addRoute(audio_session_t session,
91                                audio_stream_type_t streamType,
92                                audio_source_t source,
93                                const sp<DeviceDescriptor>& descriptor,
94                                uid_t uid)
95 {
96     if (mMapType == MAPTYPE_INPUT && streamType != SessionRoute::STREAM_TYPE_NA) {
97         ALOGE("Adding Output Route to InputRouteMap");
98         return;
99     } else if (mMapType == MAPTYPE_OUTPUT && source != SessionRoute::SOURCE_TYPE_NA) {
100         ALOGE("Adding Input Route to OutputRouteMap");
101         return;
102     }
103 
104     sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
105 
106     if (route != 0) {
107         if (descriptor != 0 || route->mDeviceDescriptor != 0) {
108             route->mChanged = true;
109         }
110         route->mRefCount++;
111         route->mDeviceDescriptor = descriptor;
112     } else {
113         route = new SessionRoute(session, streamType, source, descriptor, uid);
114         route->mRefCount++;
115         if (descriptor != 0) {
116             route->mChanged = true;
117         }
118         add(session, route);
119     }
120 }
121 
getActiveDeviceForStream(audio_stream_type_t streamType,const DeviceVector & availableDevices)122 audio_devices_t SessionRouteMap::getActiveDeviceForStream(audio_stream_type_t streamType,
123                                                           const DeviceVector& availableDevices)
124 {
125     audio_devices_t device = AUDIO_DEVICE_NONE;
126 
127     for (size_t index = 0; index < size(); index++) {
128         sp<SessionRoute> route = valueAt(index);
129         if (streamType == route->mStreamType && route->isActiveOrChanged()
130                 && route->mDeviceDescriptor != 0) {
131             device = route->mDeviceDescriptor->type();
132             if (!availableDevices.getDevicesFromType(device).isEmpty()) {
133                 break;
134             }
135         }
136     }
137     return device;
138 }
139 
140 } // namespace android
141