1 /**
2  * Copyright (C) 2022 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 #include <ImsMediaEventHandler.h>
18 #include <ImsMediaTrace.h>
19 #include <string.h>
20 #include <string>
21 
22 std::list<ImsMediaEventHandler*> ImsMediaEventHandler::gListEventHandler;
23 std::mutex ImsMediaEventHandler::mMutex;
24 
ImsMediaEventHandler()25 ImsMediaEventHandler::ImsMediaEventHandler() {}
26 
~ImsMediaEventHandler()27 ImsMediaEventHandler::~ImsMediaEventHandler() {}
28 
Init(const char * strName)29 void ImsMediaEventHandler::Init(const char* strName)
30 {
31     strncpy(mName, strName, MAX_EVENTHANDLER_NAME);
32     mbTerminate = false;
33     gListEventHandler.push_back(this);
34     IMLOGD1("[Init] %s", mName);
35     StartThread("ImsMediaEventHandler");
36 }
37 
Deinit()38 void ImsMediaEventHandler::Deinit()
39 {
40     IMLOGD2("[Deinit] %s, queue size[%d]", mName, mListevent.size());
41     std::lock_guard<std::mutex> guard(mMutexEvent);
42     StopThread();
43     gListEventHandler.remove(this);
44     mListevent.clear();
45     mListParamA.clear();
46     mListParamB.clear();
47     mListParamC.clear();
48     mCondition.signal();
49     mConditionExit.wait();
50 }
51 
SendEvent(const char * strEventHandlerName,uint32_t event,uint64_t paramA,uint64_t paramB,uint64_t paramC)52 void ImsMediaEventHandler::SendEvent(const char* strEventHandlerName, uint32_t event,
53         uint64_t paramA, uint64_t paramB, uint64_t paramC)
54 {
55     if (strEventHandlerName == nullptr)
56     {
57         IMLOGE0("[SendEvent] strEventHandlerName is nullptr");
58         return;
59     }
60 
61     IMLOGD5("[SendEvent] Name[%s], event[%d], paramA[%p], paramB[%p], paramC[%p]",
62             strEventHandlerName, event, paramA, paramB, paramC);
63 
64     for (auto& i : gListEventHandler)
65     {
66         if (i != nullptr && strcmp(i->getName(), strEventHandlerName) == 0)
67         {
68             i->AddEvent(event, paramA, paramB, paramC);
69         }
70     }
71 }
72 
getName()73 char* ImsMediaEventHandler::getName()
74 {
75     return mName;
76 }
77 
AddEvent(uint32_t event,uint64_t paramA,uint64_t paramB,uint64_t paramC)78 void ImsMediaEventHandler::AddEvent(
79         uint32_t event, uint64_t paramA, uint64_t paramB, uint64_t paramC)
80 {
81     std::lock_guard<std::mutex> guard(mMutexEvent);
82     IMLOGD3("[AddEvent] %s, event[%d], size[%d]", mName, event, mListevent.size());
83     mListevent.push_back(event);
84     mListParamA.push_back(paramA);
85     mListParamB.push_back(paramB);
86     mListParamC.push_back(paramC);
87     mCondition.signal();
88 }
89 
run()90 void* ImsMediaEventHandler::run()
91 {
92     IMLOGD2("[run] %s enter, %p", mName, this);
93 
94     for (;;)
95     {
96         IMLOGD1("[run] %s wait", mName);
97         mCondition.wait();
98 
99         for (;;)
100         {
101             if (IsThreadStopped())
102             {
103                 break;
104             }
105 
106             mMutexEvent.lock();
107 
108             if (mListevent.size() == 0)
109             {
110                 mMutexEvent.unlock();
111                 break;
112             }
113 
114             uint32_t event = mListevent.front();
115             uint64_t paramA = mListParamA.front();
116             uint64_t paramB = mListParamB.front();
117             uint64_t paramC = mListParamC.front();
118 
119             mListevent.pop_front();
120             mListParamA.pop_front();
121             mListParamB.pop_front();
122             mListParamC.pop_front();
123             mMutexEvent.unlock();
124 
125             processEvent(event, paramA, paramB, paramC);
126 
127             if (IsThreadStopped())
128             {
129                 break;
130             }
131         }
132 
133         if (IsThreadStopped())
134         {
135             break;
136         }
137     }
138 
139     IMLOGD2("[run] %s exit, %p", mName, this);
140     mConditionExit.signal();
141     return nullptr;
142 }
143