Home | History | Annotate | Download | only in src
      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
     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
     38 bool SessionRouteMap::hasRoute(audio_session_t session)
     39 {
     40     return indexOfKey(session) >= 0 && valueFor(session)->mDeviceDescriptor != 0;
     41 }
     42 
     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 
     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 
     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 
     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 
     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 
     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 
    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