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 #pragma once
18 
19 #include <system/audio.h>
20 #include <utils/KeyedVector.h>
21 #include <utils/RefBase.h>
22 #include <utils/Errors.h>
23 
24 namespace android {
25 
26 class DeviceDescriptor;
27 class DeviceVector;
28 
29 class SessionRoute : public RefBase
30 {
31 public:
32     // For Input (Source) routes, use STREAM_TYPE_NA ("NA" = "not applicable)for the
33     // streamType argument
34     static const audio_stream_type_t STREAM_TYPE_NA = AUDIO_STREAM_DEFAULT;
35 
36     // For Output (Sink) routes, use SOURCE_TYPE_NA ("NA" = "not applicable") for the
37     // source argument
38 
39     static const audio_source_t SOURCE_TYPE_NA = AUDIO_SOURCE_DEFAULT;
40 
SessionRoute(audio_session_t session,audio_stream_type_t streamType,audio_source_t source,sp<DeviceDescriptor> deviceDescriptor,uid_t uid)41     SessionRoute(audio_session_t session,
42                  audio_stream_type_t streamType,
43                  audio_source_t source,
44                  sp<DeviceDescriptor> deviceDescriptor,
45                  uid_t uid)
46         : mUid(uid),
47           mSession(session),
48           mDeviceDescriptor(deviceDescriptor),
49           mRefCount(0),
50           mActivityCount(0),
51           mChanged(false),
52           mStreamType(streamType),
53           mSource(source)
54     {}
55 
56     void log(const char* prefix);
57 
isActiveOrChanged()58     bool isActiveOrChanged() {
59         return (mDeviceDescriptor != 0) && (mChanged || (mActivityCount > 0));
60     }
61 
62     uid_t                       mUid;
63     audio_session_t             mSession;
64     sp<DeviceDescriptor>        mDeviceDescriptor;
65 
66     // "reference" counting
67     int                         mRefCount;      // +/- on references
68     int                         mActivityCount; // +/- on start/stop
69     bool                        mChanged;
70     // for outputs
71     const audio_stream_type_t   mStreamType;
72     // for inputs
73     const audio_source_t        mSource;
74 };
75 
76 class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute> >
77 {
78 public:
79     // These constants identify the SessionRoutMap as holding EITHER input routes,
80     // or output routes.  An error will occur if an attempt is made to add a SessionRoute
81     // object with mStreamType == STREAM_TYPE_NA (i.e. an input SessionRoute) to a
82     // SessionRoutMap that is marked for output (i.e. mMapType == SESSION_ROUTE_MAP_OUTPUT)
83     // and similarly  for output SessionRoutes and Input SessionRouteMaps.
84     typedef enum
85     {
86         MAPTYPE_INPUT = 0,
87         MAPTYPE_OUTPUT = 1
88     } session_route_map_type_t;
89 
SessionRouteMap(session_route_map_type_t mapType)90     explicit SessionRouteMap(session_route_map_type_t mapType) :
91         mMapType(mapType)
92     {}
93 
94     bool hasRoute(audio_session_t session);
95 
96     void removeRoute(audio_session_t session);
97 
98     int incRouteActivity(audio_session_t session);
99     int decRouteActivity(audio_session_t session);
100     bool getAndClearRouteChanged(audio_session_t session); // also clears the changed flag
101     void log(const char* caption);
102     audio_devices_t getActiveDeviceForStream(audio_stream_type_t streamType,
103                                              const DeviceVector& availableDevices);
104     // Specify an Output(Sink) route by passing SessionRoute::SOURCE_TYPE_NA in the
105     // source argument.
106     // Specify an Input(Source) rout by passing SessionRoute::AUDIO_STREAM_DEFAULT
107     // in the streamType argument.
108     void addRoute(audio_session_t session,
109                   audio_stream_type_t streamType,
110                   audio_source_t source,
111                   const sp<DeviceDescriptor>& deviceDescriptor,
112                   uid_t uid);
113 
114 private:
115     // Used to mark a SessionRoute as for either inputs (mMapType == kSessionRouteMap_Input)
116     // or outputs (mMapType == kSessionRouteMap_Output)
117     const session_route_map_type_t mMapType;
118 };
119 
120 } // namespace android
121