1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "media_monitor_manager.h"
17 #include "log.h"
18 #include "parameters.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 #include "monitor_error.h"
22 #include "media_monitor_proxy.h"
23 #include "media_monitor_death_recipient.h"
24 #include "dump_buffer_wrap.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FOUNDATION, "MediaMonitorManager"};
28 }
29
30 namespace OHOS {
31 namespace Media {
32 namespace MediaMonitor {
33
34 using namespace std;
35
36 static mutex g_mmProxyMutex;
37 static sptr<IMediaMonitor> g_mmProxy = nullptr;
38 static std::shared_ptr<DumpBufferWrap> g_dumpBufferWrap = nullptr;
39 constexpr int MAX_DUMP_TIME = 90;
40
MediaMonitorManager()41 MediaMonitorManager::MediaMonitorManager()
42 {
43 versionType_ = OHOS::system::GetParameter("const.logsystem.versiontype", COMMERCIAL_VERSION);
44 MEDIA_LOG_I("version type:%{public}s", versionType_.c_str());
45 }
46
GetInstance()47 MediaMonitorManager& MediaMonitorManager::GetInstance()
48 {
49 static MediaMonitorManager monitorManager;
50 return monitorManager;
51 }
52
GetMediaMonitorProxy()53 static const sptr<IMediaMonitor> GetMediaMonitorProxy()
54 {
55 MEDIA_LOG_D("Start to get media monitor manager proxy.");
56 lock_guard<mutex> lock(g_mmProxyMutex);
57
58 if (g_mmProxy == nullptr) {
59 auto smmgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
60 FALSE_RETURN_V_MSG_E(smmgr != nullptr, nullptr, "smmgr init failed.");
61
62 sptr<IRemoteObject> object = smmgr->CheckSystemAbility(MEDIA_MONITOR_SERVICE_ID);
63 FALSE_RETURN_V_MSG_E(object != nullptr, nullptr, "Object is NULL.");
64
65 g_mmProxy = iface_cast<IMediaMonitor>(object);
66 FALSE_RETURN_V_MSG_E(g_mmProxy != nullptr, nullptr, "Init g_mmProxy is NULL.");
67
68 MEDIA_LOG_I("Init g_mmProxy is assigned.");
69 pid_t pid = 0;
70 sptr<MediaMonitorDeathRecipient> deathRecipient = new(std::nothrow) MediaMonitorDeathRecipient(pid);
71 if (deathRecipient != nullptr) {
72 deathRecipient->SetNotifyCb(std::bind(&MediaMonitorManager::MediaMonitorDied,
73 std::placeholders::_1));
74 MEDIA_LOG_I("Register media monitor death recipient");
75 bool result = object->AddDeathRecipient(deathRecipient);
76 if (!result) {
77 MEDIA_LOG_E("failed to add deathRecipient");
78 }
79 }
80 }
81 return g_mmProxy;
82 }
83
MediaMonitorDied(pid_t pid)84 void MediaMonitorManager::MediaMonitorDied(pid_t pid)
85 {
86 MEDIA_LOG_I("media monitor died");
87 lock_guard<mutex> lock(g_mmProxyMutex);
88 if (g_mmProxy == nullptr) {
89 MEDIA_LOG_I("media monitor has already died!");
90 return;
91 }
92 g_mmProxy = nullptr;
93 }
94
WriteLogMsg(std::shared_ptr<EventBean> & bean)95 void MediaMonitorManager::WriteLogMsg(std::shared_ptr<EventBean> &bean)
96 {
97 MEDIA_LOG_D("Write event to media monitor");
98 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
99 if (proxy == nullptr) {
100 MEDIA_LOG_E("proxy is nullptr.");
101 return;
102 }
103 proxy->WriteLogMsg(*bean);
104 }
105
GetAudioRouteMsg(std::map<PreferredType,shared_ptr<MonitorDeviceInfo>> & preferredDevices)106 void MediaMonitorManager::GetAudioRouteMsg(std::map<PreferredType, shared_ptr<MonitorDeviceInfo>> &preferredDevices)
107 {
108 MEDIA_LOG_D("Get audio route devices");
109 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
110 if (proxy == nullptr) {
111 MEDIA_LOG_E("proxy is nullptr.");
112 return;
113 }
114
115 int32_t ret;
116 std::unordered_map<int32_t, MonitorDeviceInfo> deviceInfos;
117 proxy->GetAudioRouteMsg(deviceInfos, ret);
118 for (auto &deviceInfo : deviceInfos) {
119 PreferredType preferredType = static_cast<PreferredType>(deviceInfo.first);
120 shared_ptr<MonitorDeviceInfo> info = std::make_shared<MonitorDeviceInfo>(deviceInfo.second);
121 preferredDevices.emplace(preferredType, info);
122 }
123 }
124
GetAudioExcludedDevicesMsg(std::map<AudioDeviceUsage,std::vector<std::shared_ptr<MonitorDeviceInfo>>> & excludedDevices)125 void MediaMonitorManager::GetAudioExcludedDevicesMsg(std::map<AudioDeviceUsage,
126 std::vector<std::shared_ptr<MonitorDeviceInfo>>> &excludedDevices)
127 {
128 MEDIA_LOG_D("Get audio excluded devices");
129 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
130 if (proxy == nullptr) {
131 MEDIA_LOG_E("proxy is nullptr.");
132 return;
133 }
134 int32_t ret;
135 std::unordered_map<int32_t, std::vector<MonitorDeviceInfo>> deviceInfos;
136 proxy->GetAudioExcludedDevicesMsg(deviceInfos, ret);
137 for (auto &deviceInfo : deviceInfos) {
138 AudioDeviceUsage deviceUsage = static_cast<AudioDeviceUsage>(deviceInfo.first);
139 std::vector<std::shared_ptr<MonitorDeviceInfo>> infoList;
140 for (auto &info : deviceInfo.second) {
141 std::shared_ptr<MonitorDeviceInfo> infoPtr = std::make_shared<MonitorDeviceInfo>(info);
142 infoList.emplace_back(infoPtr);
143 }
144 excludedDevices.emplace(deviceUsage, infoList);
145 }
146 }
147
WriteAudioBuffer(const std::string & fileName,void * ptr,size_t size)148 void MediaMonitorManager::WriteAudioBuffer(const std::string &fileName, void *ptr, size_t size)
149 {
150 if (!dumpEnable_) {
151 MEDIA_LOG_D("dump status error return");
152 return;
153 }
154
155 if (versionType_ != BETA_VERSION) {
156 return;
157 }
158
159 int duration = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) - dumpStartTime_;
160 if (duration > MAX_DUMP_TIME) {
161 MEDIA_LOG_I("dump duration > 90 return");
162 dumpEnable_ = false;
163 dumpStartTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
164 return;
165 }
166
167 FALSE_RETURN_MSG(ptr != nullptr, "in data is empty");
168 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
169 FALSE_RETURN_MSG(proxy != nullptr, "proxy is nullptr");
170
171 int32_t ret;
172 std::shared_ptr<DumpBuffer> bufferPtr = std::make_shared<DumpBuffer>();
173 proxy->GetInputBuffer(*bufferPtr, size, ret);
174 FALSE_RETURN_MSG(ret == SUCCESS, "get buffer failed.");
175 FALSE_RETURN_MSG(bufferPtr != nullptr, "get buffer is nullptr.");
176
177 std::shared_ptr<DumpBufferWrap> tmpBufferWrap = g_dumpBufferWrap;
178 FALSE_RETURN_MSG(tmpBufferWrap != nullptr, "buffer wrap is nullptr.");
179
180 int32_t bufferCapacitySize = tmpBufferWrap->GetCapacity(bufferPtr.get());
181 FALSE_RETURN_MSG(bufferCapacitySize > 0, "get buffer capacity error");
182 int32_t writeSize = tmpBufferWrap->Write(bufferPtr.get(), static_cast<uint8_t*>(ptr), size);
183 FALSE_RETURN_MSG(writeSize > 0, "write buffer error");
184
185 uint64_t bufferId = tmpBufferWrap->GetUniqueId(bufferPtr.get());
186 proxy->InputBufferFilled(fileName, bufferId, writeSize, ret);
187 FALSE_RETURN_MSG(ret == SUCCESS, "write buffer error %{public}d", ret);
188 MEDIA_LOG_D("write audio buffer ret %{public}d", ret);
189 }
190
GetMediaParameters(const std::vector<std::string> & subKeys,std::vector<std::pair<std::string,std::string>> & result)191 int32_t MediaMonitorManager::GetMediaParameters(const std::vector<std::string> &subKeys,
192 std::vector<std::pair<std::string, std::string>> &result)
193 {
194 if (versionType_ != BETA_VERSION) {
195 MEDIA_LOG_E("version type is commercial");
196 return ERROR;
197 }
198
199 bool match = false;
200 std::string matchKey;
201 std::string value = "false";
202 for (auto it = subKeys.begin(); it != subKeys.end(); it++) {
203 if (*it == BETA_DUMP_TYPE || *it == DEFAULT_DUMP_TYPE) {
204 match = true;
205 matchKey = *it;
206 break;
207 }
208 }
209 FALSE_RETURN_V_MSG_E(match, ERROR, "get media param invalid param");
210
211 if (dumpEnable_ == false) {
212 result.emplace_back(std::make_pair(matchKey, value));
213 MEDIA_LOG_I("get media param: close");
214 return SUCCESS;
215 }
216
217 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
218 if (proxy == nullptr) {
219 MEDIA_LOG_E("proxy is nullptr.");
220 return ERROR;
221 }
222
223 int32_t status = 0;
224 int32_t ret;
225 proxy->GetPcmDumpStatus(status, ret);
226 if (ret != SUCCESS) {
227 MEDIA_LOG_E("get dump media param failed");
228 return ERROR;
229 }
230 if (status > 0) {
231 value = "true";
232 }
233
234 result.emplace_back(std::make_pair(matchKey, value));
235 MEDIA_LOG_I("get media param: %{public}s", value.c_str());
236 return SUCCESS;
237 }
238
SetMediaParameters(const std::vector<std::pair<std::string,std::string>> & kvpairs)239 int32_t MediaMonitorManager::SetMediaParameters(const std::vector<std::pair<std::string, std::string>> &kvpairs)
240 {
241 if (versionType_ != BETA_VERSION) {
242 MEDIA_LOG_E("version type is commercial");
243 return ERROR;
244 }
245 std::string dumpType;
246 std::string dumpEnable;
247 for (auto it = kvpairs.begin(); it != kvpairs.end(); ++it) {
248 if (it->first == DEFAULT_DUMP_TYPE || it->first == BETA_DUMP_TYPE) {
249 dumpType = it->first;
250 dumpEnable = it->second;
251 break;
252 }
253 return ERROR;
254 }
255
256 if (dumpEnable_ && dumpEnable == "true") {
257 int duration = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) - dumpStartTime_;
258 if (duration < MAX_DUMP_TIME) {
259 MEDIA_LOG_E("set dump media param failed, already dumping");
260 return ERROR;
261 }
262 }
263 dumpType_ = dumpType;
264 dumpEnable_ = (dumpEnable == "true") ? true : false;
265 if (dumpEnable_) {
266 dumpStartTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
267 }
268
269 MEDIA_LOG_I("set dump media param, %{public}d %{public}s", dumpEnable_, dumpType_.c_str());
270 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
271 if (proxy == nullptr) {
272 MEDIA_LOG_E("proxy is nullptr.");
273 return ERROR;
274 }
275
276 FALSE_RETURN_V_MSG_E(LoadDumpBufferWrap(dumpEnable) == SUCCESS, ERROR, "load buffer wrap error");
277
278 int32_t ret;
279 proxy->SetMediaParameters(dumpType, dumpEnable, ret);
280 if (ret != SUCCESS) {
281 MEDIA_LOG_E("set dump media param failed");
282 }
283 return ret;
284 }
285
ErasePreferredDeviceByType(const PreferredType preferredType)286 int32_t MediaMonitorManager::ErasePreferredDeviceByType(const PreferredType preferredType)
287 {
288 MEDIA_LOG_D("Erase preferred device by type");
289 sptr<IMediaMonitor> proxy = GetMediaMonitorProxy();
290 if (proxy == nullptr) {
291 MEDIA_LOG_E("proxy is nullptr.");
292 return ERROR;
293 }
294 int32_t ret;
295 proxy->ErasePreferredDeviceByType(preferredType, ret);
296 return ret;
297 }
298
LoadDumpBufferWrap(const std::string & dumpEnable)299 int32_t MediaMonitorManager::LoadDumpBufferWrap(const std::string &dumpEnable)
300 {
301 bool flag = (dumpEnable == "true") ? true : false;
302 if (flag && g_dumpBufferWrap != nullptr) {
303 return SUCCESS;
304 }
305
306 if (flag) {
307 g_dumpBufferWrap = std::make_shared<DumpBufferWrap>();
308 bool ret = g_dumpBufferWrap->Open();
309 if (!ret) {
310 MEDIA_LOG_E("load dumpbuffer failed");
311 g_dumpBufferWrap = nullptr;
312 return ERROR;
313 }
314 } else {
315 g_dumpBufferWrap = nullptr;
316 }
317 return SUCCESS;
318 }
319 } // namespace MediaMonitor
320 } // namespace Media
321 } // namespace OHOS