• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 "Sound.h"
20 
21 #include <mutex>
22 #include <unordered_map>
23 
24 #include <android-base/thread_annotations.h>
25 
26 namespace android {
27 
28 class SoundPool;
29 
30 // for queued events
31 class SoundPoolEvent {
32 public:
33     explicit SoundPoolEvent(int msg, int arg1 = 0, int arg2 = 0) :
mMsg(msg)34         mMsg(msg), mArg1(arg1), mArg2(arg2) {}
35     const int mMsg;   // MessageType
36     const int mArg1;  // soundID
37     const int mArg2;  // status
38     enum MessageType { INVALID, SOUND_LOADED };
39 };
40 
41 // callback function prototype
42 typedef void SoundPoolCallback(SoundPoolEvent event, SoundPool* soundPool, void* user);
43 
44 } // namespace android
45 
46 namespace android::soundpool {
47 
48 // This class manages Sounds for the SoundPool.
49 class SoundManager {
50 public:
51     SoundManager();
52     ~SoundManager();
53 
54     // Matches corresponding SoundPool API functions
55     int32_t load(int fd, int64_t offset, int64_t length, int32_t priority);
56     bool unload(int32_t soundID);
57     void setCallback(SoundPool* soundPool, SoundPoolCallback* callback, void* user);
58     void* getUserData() const;
59 
60     // SoundPool and SoundDecoder access
61     std::shared_ptr<Sound> findSound(int32_t soundID) const;
62 
63     // from the SoundDecoder
64     void notify(SoundPoolEvent event);
65 
66 private:
67 
68     // CallbackHandler is used to manage notifications back to the app when a sound
69     // has been loaded.  It uses a recursive lock to allow setting the callback
70     // during the callback.
71     class CallbackHandler {
72     public:
setCallback(SoundPool * soundPool,SoundPoolCallback * callback,void * userData)73         void setCallback(SoundPool *soundPool, SoundPoolCallback* callback, void* userData)
74         {
75             std::lock_guard<std::recursive_mutex> lock(mCallbackLock);
76             mSoundPool = soundPool;
77             mCallback = callback;
78             mUserData = userData;
79         }
notify(SoundPoolEvent event)80         void notify(SoundPoolEvent event) const
81         {
82             std::lock_guard<std::recursive_mutex> lock(mCallbackLock);
83             if (mCallback != nullptr) {
84                 mCallback(event, mSoundPool, mUserData);
85                 // Note: mCallback may call setCallback().
86                 // so mCallback, mUserData may have changed.
87             }
88         }
getUserData()89         void* getUserData() const
90         {
91             std::lock_guard<std::recursive_mutex> lock(mCallbackLock);
92             return mUserData;
93         }
94     private:
95         mutable std::recursive_mutex  mCallbackLock; // allow mCallback to setCallback().
96                                           // No thread-safety checks in R for recursive_mutex.
97         SoundPool*          mSoundPool = nullptr; // GUARDED_BY(mCallbackLock)
98         SoundPoolCallback*  mCallback = nullptr;  // GUARDED_BY(mCallbackLock)
99         void*               mUserData = nullptr;  // GUARDED_BY(mCallbackLock)
100     };
101 
102     std::shared_ptr<Sound> findSound_l(int32_t soundID) const REQUIRES(mSoundManagerLock);
103 
104     // The following variables are initialized in constructor and can be accessed anytime.
105     CallbackHandler mCallbackHandler;              // has its own lock
106     const std::unique_ptr<SoundDecoder> mDecoder;  // has its own lock
107 
108     mutable std::mutex mSoundManagerLock;
109     std::unordered_map<int, std::shared_ptr<Sound>> mSounds GUARDED_BY(mSoundManagerLock);
110     int32_t mNextSoundID GUARDED_BY(mSoundManagerLock) = 0;
111 };
112 
113 } // namespace android::soundpool
114