1 /*
2 * Copyright (c) 2022-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 "dscreen_handler.h"
17
18 #include "avcodec_info.h"
19 #include "avcodec_list.h"
20 #include "nlohmann/json.hpp"
21 #include "screen.h"
22 #include "histreamer_query_tool.h"
23
24 #include "dscreen_constants.h"
25 #include "dscreen_errcode.h"
26 #include "dscreen_log.h"
27 #include "dscreen_util.h"
28
29 using json = nlohmann::json;
30
31 namespace OHOS {
32 namespace DistributedHardware {
33 namespace {
34 const std::string KEY_HISTREAMER_VIDEO_ENCODER = "histmVidEnc";
35 const std::string KEY_HISTREAMER_VIDEO_DECODER = "histmVidDec";
36 }
37 IMPLEMENT_SINGLE_INSTANCE(DScreenHandler);
38
DScreenHandler()39 DScreenHandler::DScreenHandler()
40 {
41 DHLOGI("DScreenHandler constructor.");
42 }
43
~DScreenHandler()44 DScreenHandler::~DScreenHandler()
45 {
46 DHLOGI("~DScreenHandler");
47 Rosen::ScreenManager::GetInstance().UnregisterScreenListener(screenListener_);
48 }
49
Initialize()50 int32_t DScreenHandler::Initialize()
51 {
52 DHLOGI("DScreenHandler Initialize");
53 if (screenListener_ == nullptr) {
54 screenListener_ = new (std::nothrow) ScreenListener();
55 }
56 Rosen::DMError ret = Rosen::ScreenManager::GetInstance().RegisterScreenListener(screenListener_);
57 if (ret != Rosen::DMError::DM_OK) {
58 DHLOGE("register screen listener failed.");
59 return DSCREEN_INIT_ERR;
60 }
61 return DH_SUCCESS;
62 }
63
ByteCalculate(std::uint32_t screenWidth)64 uint32_t ScreenListener::ByteCalculate(std::uint32_t screenWidth)
65 {
66 if (screenWidth % BYTE_ALIGNMENT == 0) {
67 return screenWidth;
68 }
69 uint32_t alignedInt = (screenWidth + BYTE_ALIGNMENT_CALCULATION) / BYTE_ALIGNMENT * BYTE_ALIGNMENT;
70 return alignedInt;
71 }
72
OnConnect(uint64_t screenId)73 void ScreenListener::OnConnect(uint64_t screenId)
74 {
75 DHLOGI("on screen connect");
76 if (screenId != SCREEN_ID_DEFAULT) {
77 DHLOGI("screenId is invalid, screenId is: %{public}" PRIu64, screenId);
78 return;
79 }
80 sptr<Rosen::Screen> screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenId);
81 if (screen == nullptr) {
82 DHLOGE("screen not found, screenId is: %{public}" PRIu64, screenId);
83 return;
84 }
85 if (!screen->IsReal()) {
86 DHLOGI("screen is not real");
87 return;
88 }
89 std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screenId);
90 uint32_t screenWidth = screen->GetWidth();
91 screenWidth = ByteCalculate(screenWidth);
92 uint32_t screenHeight = screen->GetHeight();
93
94 json attrJson;
95 attrJson[KEY_VERSION] = DSCREEN_VERSION;
96 attrJson[KEY_SCREEN_WIDTH] = screenWidth;
97 attrJson[KEY_SCREEN_HEIGHT] = screenHeight;
98 attrJson[KEY_CODECTYPE] = DScreenHandler::GetInstance().QueryCodecInfo();
99 std::string subtype = "screen";
100
101 DScreenHandler::GetInstance().PluginHardware(dhId, attrJson.dump(), subtype);
102 }
103
OnDisconnect(uint64_t screenId)104 void ScreenListener::OnDisconnect(uint64_t screenId)
105 {
106 DHLOGI("on screen disconnect");
107 std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screenId);
108 DScreenHandler::GetInstance().UnPluginHardware(dhId);
109 }
110
PluginHardware(const std::string &dhId, const std::string &attr, const std::string &subtype)111 void DScreenHandler::PluginHardware(const std::string &dhId, const std::string &attr, const std::string &subtype)
112 {
113 DHLOGI("DScreenHandler PluginHardware");
114 if (listener_ != nullptr) {
115 listener_->PluginHardware(dhId, attr, subtype);
116 }
117 }
118
UnPluginHardware(const std::string &dhId)119 void DScreenHandler::UnPluginHardware(const std::string &dhId)
120 {
121 DHLOGI("DScreenHandler UnPluginHardware");
122 if (listener_ != nullptr) {
123 listener_->UnPluginHardware(dhId);
124 }
125 }
126
QueryMeta()127 std::vector<DHItem> DScreenHandler::QueryMeta()
128 {
129 DHLOGI("DScreenHandler query meta hardware info");
130 return RealQuery();
131 }
132
Query()133 std::vector<DHItem> DScreenHandler::Query()
134 {
135 DHLOGI("DScreenHandler query full hardware info");
136 return RealQuery();
137 }
138
RealQuery()139 std::vector<DHItem> DScreenHandler::RealQuery()
140 {
141 DHLOGI("DScreenHandler RealQuery");
142 std::vector<DHItem> dhItemVec;
143 std::vector<sptr<Rosen::Screen>> screens;
144 Rosen::ScreenManager::GetInstance().GetAllScreens(screens);
145 DHLOGI("screens size is: %{public}zu", screens.size());
146 for (const auto &screen : screens) {
147 if (screen == nullptr) {
148 DHLOGE("screen is nullptr.");
149 continue;
150 }
151 if (screen->GetWidth() <= 0) {
152 continue;
153 }
154 if (!screen->IsReal()) {
155 continue;
156 }
157 std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screen->GetId());
158 uint32_t screenWidth = screen->GetWidth();
159 if (screenListener_ == nullptr) {
160 screenListener_ = new (std::nothrow) ScreenListener();
161 }
162 screenWidth = screenListener_->ByteCalculate(screenWidth);
163 uint32_t screenHeight = screen->GetHeight();
164
165 json attrJson;
166 attrJson[KEY_VERSION] = DSCREEN_VERSION;
167 attrJson[KEY_SCREEN_WIDTH] = screenWidth;
168 attrJson[KEY_SCREEN_HEIGHT] = screenHeight;
169 attrJson[KEY_CODECTYPE] = QueryCodecInfo();
170 std::string videoEncoders =
171 HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::VIDEO_ENCODER);
172 DHLOGI("DScreen QueryVideoEncoderAbility info: %{public}s", videoEncoders.c_str());
173 attrJson[KEY_HISTREAMER_VIDEO_ENCODER] = videoEncoders;
174 std::string videoDecoders =
175 HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::VIDEO_DECODER);
176 DHLOGI("DScreen QueryVideoDecoderAbility info: %{public}s", videoDecoders.c_str());
177 attrJson[KEY_HISTREAMER_VIDEO_DECODER] = videoDecoders;
178
179 DHItem dhItem;
180 dhItem.dhId = dhId;
181 dhItem.subtype = "screen";
182 dhItem.attrs = attrJson.dump();
183 dhItemVec.push_back(dhItem);
184 DHLOGD("query result: dhId: %{public}s, attrs: %{public}s", dhId.c_str(), attrJson.dump().c_str());
185 }
186 return dhItemVec;
187 }
188
QueryExtraInfo()189 std::map<std::string, std::string> DScreenHandler::QueryExtraInfo()
190 {
191 DHLOGD("DScreenHandler queryExtraInfo");
192 std::map<std::string, std::string> extraInfo;
193 return extraInfo;
194 }
195
IsSupportPlugin()196 bool DScreenHandler::IsSupportPlugin()
197 {
198 DHLOGD("DScreenHandler IsSupportPlugin");
199 return true;
200 }
201
RegisterPluginListener(std::shared_ptr<PluginListener> listener)202 void DScreenHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
203 {
204 DHLOGD("DScreenHandler register plugin listener");
205 if (listener == nullptr) {
206 DHLOGE("DScreenHandler unregistering plugin listener");
207 return;
208 }
209 listener_ = listener;
210 }
211
UnRegisterPluginListener()212 void DScreenHandler::UnRegisterPluginListener()
213 {
214 DHLOGI("DScreenHandler unRegister plugin listener");
215 listener_ = nullptr;
216 }
217
QueryCodecInfo()218 std::string DScreenHandler::QueryCodecInfo()
219 {
220 DHLOGD("DScreenHandler QueryCodecInfo");
221 if (!codecInfoStr_.empty()) {
222 return codecInfoStr_;
223 }
224
225 // query codec info
226 std::shared_ptr<MediaAVCodec::AVCodecList> codecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList();
227 if (codecList == nullptr) {
228 DHLOGE("Create avCodecList failed.");
229 return codecInfoStr_;
230 }
231 const std::vector<std::string> encoderName = {std::string(MediaAVCodec::CodecMimeType::VIDEO_AVC),
232 std::string(MediaAVCodec::CodecMimeType::VIDEO_HEVC)};
233 json codecTypeArray = json::array();
234
235 for (const auto &coder : encoderName) {
236 MediaAVCodec::CapabilityData *capData = codecList->GetCapability(coder, true,
237 MediaAVCodec::AVCodecCategory::AVCODEC_HARDWARE);
238 if (capData == nullptr) {
239 continue;
240 }
241 std::string mimeType = capData->mimeType;
242 codecTypeArray.push_back(mimeType);
243 }
244
245 codecInfoStr_ = codecTypeArray.dump();
246 return codecInfoStr_;
247 }
248
GetHardwareHandler()249 IHardwareHandler* GetHardwareHandler()
250 {
251 DHLOGI("DScreenHandler::GetHardwareHandler");
252 return &DScreenHandler::GetInstance();
253 }
254 } // namespace DistributedHardware
255 } // namespace OHOS