1 /*
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 
17 #ifndef ANDROID_AAUDIO_AAUDIO_CLIENT_TRACKER_H
18 #define ANDROID_AAUDIO_AAUDIO_CLIENT_TRACKER_H
19 
20 #include <map>
21 #include <mutex>
22 #include <set>
23 
24 #include <android-base/thread_annotations.h>
25 #include <utils/Singleton.h>
26 
27 #include <aaudio/AAudio.h>
28 #include <aaudio/IAAudioClient.h>
29 #include "AAudioService.h"
30 
31 namespace aaudio {
32 
33 class AAudioClientTracker : public android::Singleton<AAudioClientTracker>{
34 public:
35     AAudioClientTracker();
36     ~AAudioClientTracker() = default;
37 
38     /**
39      * Returns information about the state of the this class.
40      *
41      * Will attempt to get the object lock, but will proceed
42      * even if it cannot.
43      *
44      * Each line of information ends with a newline.
45      *
46      * @return a string with useful information
47      */
48     std::string dump() const;
49 
50     aaudio_result_t registerClient(pid_t pid, const android::sp<IAAudioClient>& client);
51 
52     void unregisterClient(pid_t pid);
53 
54     int32_t getStreamCount(pid_t pid);
55 
56     aaudio_result_t registerClientStream(pid_t pid,
57                                          const android::sp<AAudioServiceStreamBase>& serviceStream);
58 
59     aaudio_result_t unregisterClientStream(
60             pid_t pid, const android::sp<AAudioServiceStreamBase>& serviceStream);
61 
62     /**
63      * Specify whether a process is allowed to create an EXCLUSIVE MMAP stream.
64      * @param pid
65      * @param enabled
66      */
67     void setExclusiveEnabled(pid_t pid, bool enabled);
68 
69     bool isExclusiveEnabled(pid_t pid);
70 
getAAudioService()71     android::AAudioService *getAAudioService() const {
72         return mAAudioService;
73     }
74 
setAAudioService(android::AAudioService * aaudioService)75     void setAAudioService(android::AAudioService *aaudioService) {
76         mAAudioService = aaudioService;
77     }
78 
79 private:
80 
81     /**
82      * One per process.
83      */
84     class NotificationClient : public IBinder::DeathRecipient {
85     public:
86         NotificationClient(pid_t pid, const android::sp<IBinder>& binder);
87         ~NotificationClient() override = default;
88 
89         int32_t getStreamCount();
90 
91         std::string dump() const;
92 
93         aaudio_result_t registerClientStream(
94                 const android::sp<AAudioServiceStreamBase>& serviceStream);
95 
96         aaudio_result_t unregisterClientStream(
97                 const android::sp<AAudioServiceStreamBase>& serviceStream);
98 
setExclusiveEnabled(bool enabled)99         void setExclusiveEnabled(bool enabled) {
100             mExclusiveEnabled = enabled;
101         }
102 
isExclusiveEnabled()103         bool isExclusiveEnabled() {
104             return mExclusiveEnabled;
105         }
106 
107         // IBinder::DeathRecipient
108         void binderDied(const android::wp<IBinder>& who) override;
109 
110     private:
111         mutable std::mutex                              mLock;
112         const pid_t                                     mProcessId;
113         std::set<android::sp<AAudioServiceStreamBase>>  mStreams GUARDED_BY(mLock);
114         // hold onto binder to receive death notifications
115         android::sp<IBinder>                            mBinder;
116         bool                                            mExclusiveEnabled = true;
117     };
118 
119     // This must be called under mLock
120     android::sp<NotificationClient> getNotificationClient_l(pid_t pid)
121             REQUIRES(mLock);
122 
123     mutable std::mutex                               mLock;
124     std::map<pid_t, android::sp<NotificationClient>> mNotificationClients
125             GUARDED_BY(mLock);
126     android::AAudioService                          *mAAudioService = nullptr;
127 };
128 
129 } /* namespace aaudio */
130 
131 #endif //ANDROID_AAUDIO_AAUDIO_CLIENT_TRACKER_H
132