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_base.h"
23 #include "media_monitor_client.h"
24 #include "media_monitor_death_recipient.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 constexpr int MAX_DUMP_TIME = 90;
39 
MediaMonitorManager()40 MediaMonitorManager::MediaMonitorManager()
41 {
42     versionType_ = OHOS::system::GetParameter("const.logsystem.versiontype", COMMERCIAL_VERSION);
43     MEDIA_LOG_I("version type:%{public}s", versionType_.c_str());
44 }
45 
GetInstance()46 MediaMonitorManager& MediaMonitorManager::GetInstance()
47 {
48     static MediaMonitorManager monitorManager;
49     return monitorManager;
50 }
51 
GetMediaMonitorProxy()52 static const sptr<IMediaMonitor> GetMediaMonitorProxy()
53 {
54     MEDIA_LOG_D("Start to get media monitor manager proxy.");
55     lock_guard<mutex> lock(g_mmProxyMutex);
56 
57     if (g_mmProxy == nullptr) {
58         auto smmgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59         FALSE_RETURN_V_MSG_E(smmgr != nullptr, nullptr, "smmgr init failed.");
60 
61         sptr<IRemoteObject> object = smmgr->CheckSystemAbility(MEDIA_MONITOR_SERVICE_ID);
62         FALSE_RETURN_V_MSG_E(object != nullptr, nullptr, "Object is NULL.");
63 
64         g_mmProxy = iface_cast<IMediaMonitor>(object);
65         FALSE_RETURN_V_MSG_E(g_mmProxy != nullptr, nullptr, "Init g_mmProxy is NULL.");
66 
67         MEDIA_LOG_I("Init g_mmProxy is assigned.");
68         pid_t pid = 0;
69         sptr<MediaMonitorDeathRecipient> deathRecipient = new(std::nothrow) MediaMonitorDeathRecipient(pid);
70         if (deathRecipient != nullptr) {
71             deathRecipient->SetNotifyCb(std::bind(&MediaMonitorManager::MediaMonitorDied,
72                 std::placeholders::_1));
73             MEDIA_LOG_I("Register media monitor death recipient");
74             bool result = object->AddDeathRecipient(deathRecipient);
75             if (!result) {
76                 MEDIA_LOG_E("failed to add deathRecipient");
77             }
78         }
79     }
80     return g_mmProxy;
81 }
82 
MediaMonitorDied(pid_t pid)83 void MediaMonitorManager::MediaMonitorDied(pid_t pid)
84 {
85     MEDIA_LOG_I("media monitor died");
86     lock_guard<mutex> lock(g_mmProxyMutex);
87     if (g_mmProxy == nullptr) {
88         MEDIA_LOG_I("media monitor has already died!");
89         return;
90     }
91     g_mmProxy = nullptr;
92 }
93 
WriteLogMsg(std::shared_ptr<EventBean> & bean)94 void MediaMonitorManager::WriteLogMsg(std::shared_ptr<EventBean> &bean)
95 {
96     MEDIA_LOG_D("Write event to media monitor");
97     sptr<IMediaMonitor> gamp = GetMediaMonitorProxy();
98     if (gamp == nullptr) {
99         MEDIA_LOG_E("gamp is nullptr.");
100         return;
101     }
102     gamp->WriteLogMsg(bean);
103 }
104 
GetAudioRouteMsg(std::map<PerferredType,shared_ptr<MonitorDeviceInfo>> & perferredDevices)105 void MediaMonitorManager::GetAudioRouteMsg(std::map<PerferredType, shared_ptr<MonitorDeviceInfo>> &perferredDevices)
106 {
107     MEDIA_LOG_D("Get audio route devices");
108     sptr<IMediaMonitor> gamp = GetMediaMonitorProxy();
109     if (gamp == nullptr) {
110         MEDIA_LOG_E("gamp is nullptr.");
111         return;
112     }
113     gamp->GetAudioRouteMsg(perferredDevices);
114 }
115 
WriteAudioBuffer(const std::string & fileName,void * ptr,size_t size)116 void MediaMonitorManager::WriteAudioBuffer(const std::string &fileName, void *ptr, size_t size)
117 {
118     if (!dumpEnable_) {
119         MEDIA_LOG_D("dump status error return");
120         return;
121     }
122 
123     if (versionType_ != BETA_VERSION) {
124         return;
125     }
126 
127     int duration = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) - dumpStartTime_;
128     if (duration > MAX_DUMP_TIME) {
129         MEDIA_LOG_I("dump duration > 90 return");
130         dumpEnable_ = false;
131         dumpStartTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
132         return;
133     }
134 
135     FALSE_RETURN_MSG(ptr != nullptr, "in data is empty");
136     sptr<IMediaMonitor> gamp = GetMediaMonitorProxy();
137     FALSE_RETURN_MSG(gamp != nullptr, "gamp is nullptr");
138     int32_t ret = gamp->WriteAudioBuffer(fileName, ptr, size);
139     MEDIA_LOG_D("write audio buffer ret %{public}d", ret);
140 }
141 
SetMediaParameters(const std::vector<std::pair<std::string,std::string>> & kvpairs)142 int32_t MediaMonitorManager::SetMediaParameters(const std::vector<std::pair<std::string, std::string>> &kvpairs)
143 {
144     if (versionType_ != BETA_VERSION) {
145         MEDIA_LOG_E("version type is commercial");
146         return ERROR;
147     }
148     std::string dumpType;
149     std::string dumpEnable;
150     for (auto it = kvpairs.begin(); it != kvpairs.end(); ++it) {
151         if (it->first == DEFAULT_DUMP_TYPE || it->first == BETA_DUMP_TYPE) {
152             dumpType = it->first;
153             dumpEnable = it->second;
154             break;
155         }
156         return ERROR;
157     }
158 
159     if (dumpEnable_ && dumpEnable == "true") {
160         int duration = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) - dumpStartTime_;
161         if (duration < MAX_DUMP_TIME) {
162             MEDIA_LOG_E("set dump media param failed, already dumping");
163             return ERROR;
164         }
165     }
166     dumpType_ = dumpType;
167     dumpEnable_ = (dumpEnable == "true") ? true : false;
168     if (dumpEnable_) {
169         dumpStartTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
170     }
171 
172     MEDIA_LOG_I("set dump media param, %{public}d %{public}s", dumpEnable_, dumpType_.c_str());
173     sptr<IMediaMonitor> gamp = GetMediaMonitorProxy();
174     if (gamp == nullptr) {
175         MEDIA_LOG_E("gamp is nullptr.");
176         return ERROR;
177     }
178 
179     int32_t ret = gamp->SetMediaParameters(dumpType, dumpEnable);
180     if (ret != SUCCESS) {
181         MEDIA_LOG_E("set dump media param failed");
182     }
183     return ret;
184 }
185 
ErasePreferredDeviceByType(const PerferredType preferredType)186 int32_t MediaMonitorManager::ErasePreferredDeviceByType(const PerferredType preferredType)
187 {
188     MEDIA_LOG_D("Erase preferred device by type");
189     sptr<IMediaMonitor> gamp = GetMediaMonitorProxy();
190     if (gamp == nullptr) {
191         MEDIA_LOG_E("gamp is nullptr.");
192         return ERROR;
193     }
194     int32_t ret = gamp->ErasePreferredDeviceByType(preferredType);
195     return ret;
196 }
197 } // namespace MediaMonitor
198 } // namespace Media
199 } // namespace OHOS