1 /*
2 * Copyright (c) 2021-2022 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 "rs_uni_render_processor.h"
17
18 #include <vector>
19
20 #include "hdi_layer.h"
21 #include "hdi_layer_info.h"
22 #include "luminance/rs_luminance_control.h"
23 #include "rs_trace.h"
24 #include "rs_uni_render_util.h"
25 #include "string_utils.h"
26 #include "surface_type.h"
27
28 #include "common/rs_optional_trace.h"
29 #include "drawable/rs_display_render_node_drawable.h"
30 #include "drawable/rs_surface_render_node_drawable.h"
31 #include "params/rs_display_render_params.h"
32 #include "params/rs_surface_render_params.h"
33 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
34 #include "pipeline/round_corner_display/rs_rcd_surface_render_node.h"
35 #include "platform/common/rs_log.h"
36 #ifdef USE_VIDEO_PROCESSING_ENGINE
37 #include "metadata_helper.h"
38 #endif
39 namespace OHOS {
40 namespace Rosen {
RSUniRenderProcessor()41 RSUniRenderProcessor::RSUniRenderProcessor()
42 : uniComposerAdapter_(std::make_unique<RSUniRenderComposerAdapter>())
43 {
44 }
45
~RSUniRenderProcessor()46 RSUniRenderProcessor::~RSUniRenderProcessor() noexcept
47 {
48 }
49
Init(RSDisplayRenderNode & node,int32_t offsetX,int32_t offsetY,ScreenId mirroredId,std::shared_ptr<RSBaseRenderEngine> renderEngine)50 bool RSUniRenderProcessor::Init(RSDisplayRenderNode& node, int32_t offsetX, int32_t offsetY, ScreenId mirroredId,
51 std::shared_ptr<RSBaseRenderEngine> renderEngine)
52 {
53 if (!RSProcessor::Init(node, offsetX, offsetY, mirroredId, renderEngine)) {
54 return false;
55 }
56 // In uni render mode, we can handle screen rotation in the rendering process,
57 // so we do not need to handle rotation in composer adapter any more,
58 // just pass the buffer to composer straightly.
59 screenInfo_.rotation = ScreenRotation::ROTATION_0;
60 isPhone_ = RSMainThread::Instance()->GetDeviceType() == DeviceType::PHONE;
61 return uniComposerAdapter_->Init(screenInfo_, offsetX_, offsetY_, mirrorAdaptiveCoefficient_);
62 }
63
InitForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,ScreenId mirroredId,std::shared_ptr<RSBaseRenderEngine> renderEngine)64 bool RSUniRenderProcessor::InitForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
65 ScreenId mirroredId, std::shared_ptr<RSBaseRenderEngine> renderEngine)
66 {
67 if (!RSProcessor::InitForRenderThread(displayDrawable, mirroredId, renderEngine)) {
68 return false;
69 }
70 // In uni render mode, we can handle screen rotation in the rendering process,
71 // so we do not need to handle rotation in composer adapter any more,
72 // just pass the buffer to composer straightly.
73 screenInfo_.rotation = ScreenRotation::ROTATION_0;
74 isPhone_ = RSMainThread::Instance()->GetDeviceType() == DeviceType::PHONE;
75 return uniComposerAdapter_->Init(screenInfo_, offsetX_, offsetY_, mirrorAdaptiveCoefficient_);
76 }
77
PostProcess()78 void RSUniRenderProcessor::PostProcess()
79 {
80 uniComposerAdapter_->CommitLayers(layers_);
81 if (!isPhone_) {
82 MultiLayersPerf(layerNum_);
83 }
84 RS_LOGD("RSUniRenderProcessor::PostProcess layers_:%{public}zu", layers_.size());
85 }
86
CreateLayer(RSSurfaceRenderNode & node,RSSurfaceRenderParams & params)87 void RSUniRenderProcessor::CreateLayer(RSSurfaceRenderNode& node, RSSurfaceRenderParams& params)
88 {
89 auto surfaceHandler = node.GetRSSurfaceHandler();
90 auto buffer = surfaceHandler->GetBuffer();
91 if (buffer == nullptr || surfaceHandler->GetConsumer() == nullptr) {
92 return;
93 }
94 auto& layerInfo = params.GetLayerInfo();
95 const Rect& dirtyRect = params.GetBufferDamage();
96 RS_OPTIONAL_TRACE_NAME_FMT(
97 "CreateLayer name:%s zorder:%d src:[%d, %d, %d, %d] dst:[%d, %d, %d, %d] dirty:[%d, %d, %d, %d] "
98 "buffer:[%d, %d] alpha:[%f] ",
99 node.GetName().c_str(), layerInfo.zOrder,
100 layerInfo.srcRect.x, layerInfo.srcRect.y, layerInfo.srcRect.w, layerInfo.srcRect.h,
101 layerInfo.dstRect.x, layerInfo.dstRect.y, layerInfo.dstRect.w, layerInfo.dstRect.h,
102 dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h,
103 buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), layerInfo.alpha);
104 RS_LOGD("CreateLayer name:%{public}s zorder:%{public}d src:[%{public}d, %{public}d, %{public}d, %{public}d] "
105 "dst:[%{public}d, %{public}d, %{public}d, %{public}d] "
106 "drity:[%{public}d, %{public}d, %{public}d, %{public}d] "
107 "buffer:[%{public}d, %{public}d] alpha:[%{public}f]",
108 node.GetName().c_str(), layerInfo.zOrder,
109 layerInfo.srcRect.x, layerInfo.srcRect.y, layerInfo.srcRect.w, layerInfo.srcRect.h,
110 layerInfo.dstRect.x, layerInfo.dstRect.y, layerInfo.dstRect.w, layerInfo.dstRect.h,
111 dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h,
112 buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), layerInfo.alpha);
113 auto preBuffer = surfaceHandler->GetPreBuffer();
114 ScalingMode scalingMode = params.GetScalingMode();
115 if (surfaceHandler->GetConsumer()->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
116 params.SetScalingMode(scalingMode);
117 }
118 LayerInfoPtr layer = GetLayerInfo(
119 params, buffer, preBuffer, surfaceHandler->GetConsumer(), surfaceHandler->GetAcquireFence());
120 layer->SetSdrNit(params.GetSdrNit());
121 layer->SetDisplayNit(params.GetDisplayNit());
122 layer->SetBrightnessRatio(params.GetBrightnessRatio());
123
124 uniComposerAdapter_->SetMetaDataInfoToLayer(layer, surfaceHandler->GetBuffer(), surfaceHandler->GetConsumer());
125 layers_.emplace_back(layer);
126 params.SetLayerCreated(true);
127 }
128
CreateLayerForRenderThread(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable)129 void RSUniRenderProcessor::CreateLayerForRenderThread(DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable)
130 {
131 auto& paramsSp = surfaceDrawable.GetRenderParams();
132 if (!paramsSp) {
133 return;
134 }
135 auto& params = *paramsSp;
136 auto buffer = params.GetBuffer();
137 if (buffer == nullptr) {
138 return;
139 }
140 auto& layerInfo = params.GetLayerInfo();
141 const Rect& dirtyRect = params.GetBufferDamage();
142 RS_OPTIONAL_TRACE_NAME_FMT(
143 "CreateLayer name:%s zorder:%d src:[%d, %d, %d, %d] dst:[%d, %d, %d, %d] dirty:[%d, %d, %d, %d] "
144 "buffer:[%d, %d] alpha:[%f] ",
145 surfaceDrawable.GetName().c_str(), layerInfo.zOrder,
146 layerInfo.srcRect.x, layerInfo.srcRect.y, layerInfo.srcRect.w, layerInfo.srcRect.h,
147 layerInfo.dstRect.x, layerInfo.dstRect.y, layerInfo.dstRect.w, layerInfo.dstRect.h,
148 dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h,
149 buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), layerInfo.alpha);
150 RS_LOGD("CreateLayer name:%{public}s zorder:%{public}d src:[%{public}d, %{public}d, %{public}d, %{public}d] "
151 "dst:[%{public}d, %{public}d, %{public}d, %{public}d] "
152 "drity:[%{public}d, %{public}d, %{public}d, %{public}d] "
153 "buffer:[%{public}d, %{public}d] alpha:[%{public}f]",
154 surfaceDrawable.GetName().c_str(), layerInfo.zOrder,
155 layerInfo.srcRect.x, layerInfo.srcRect.y, layerInfo.srcRect.w, layerInfo.srcRect.h,
156 layerInfo.dstRect.x, layerInfo.dstRect.y, layerInfo.dstRect.w, layerInfo.dstRect.h,
157 dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h,
158 buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), layerInfo.alpha);
159 auto preBuffer = params.GetPreBuffer();
160 LayerInfoPtr layer = GetLayerInfo(static_cast<RSSurfaceRenderParams&>(params), buffer, preBuffer,
161 surfaceDrawable.GetConsumerOnDraw(), params.GetAcquireFence());
162 layer->SetNodeId(surfaceDrawable.GetId());
163 auto& renderParams = static_cast<RSSurfaceRenderParams&>(params);
164 layer->SetSdrNit(renderParams.GetSdrNit());
165 layer->SetDisplayNit(renderParams.GetDisplayNit());
166 layer->SetBrightnessRatio(renderParams.GetBrightnessRatio());
167 uniComposerAdapter_->SetMetaDataInfoToLayer(layer, params.GetBuffer(), surfaceDrawable.GetConsumerOnDraw());
168 layers_.emplace_back(layer);
169 params.SetLayerCreated(true);
170 }
171
CreateUIFirstLayer(DrawableV2::RSSurfaceRenderNodeDrawable & drawable,RSSurfaceRenderParams & params)172 void RSUniRenderProcessor::CreateUIFirstLayer(DrawableV2::RSSurfaceRenderNodeDrawable& drawable,
173 RSSurfaceRenderParams& params)
174 {
175 auto surfaceHandler = drawable.GetMutableRSSurfaceHandlerUiFirstOnDraw();
176 if (!surfaceHandler) {
177 return;
178 }
179 auto buffer = surfaceHandler->GetBuffer();
180 if (buffer == nullptr && surfaceHandler->GetAvailableBufferCount() <= 0) {
181 RS_TRACE_NAME_FMT("HandleSubThreadNode wait %" PRIu64 "", params.GetId());
182 RSSubThreadManager::Instance()->WaitNodeTask(params.GetId());
183 }
184 if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(*surfaceHandler) || !surfaceHandler->GetBuffer()) {
185 RS_LOGE("CreateUIFirstLayer ConsumeAndUpdateBuffer or GetBuffer return false");
186 return;
187 }
188 buffer = surfaceHandler->GetBuffer();
189 auto preBuffer = surfaceHandler->GetPreBuffer();
190 LayerInfoPtr layer = GetLayerInfo(
191 params, buffer, preBuffer, surfaceHandler->GetConsumer(), surfaceHandler->GetAcquireFence());
192 uniComposerAdapter_->SetMetaDataInfoToLayer(layer, params.GetBuffer(), surfaceHandler->GetConsumer());
193 layers_.emplace_back(layer);
194 auto& layerInfo = params.layerInfo_;
195 RS_LOGD("RSUniRenderProcessor::CreateUIFirstLayer: [%{public}s-%{public}" PRIu64 "] "
196 "src: %{public}d %{public}d %{public}d %{public}d, "
197 "dst: %{public}d %{public}d %{public}d %{public}d, zOrder: %{public}d",
198 drawable.GetName().c_str(), drawable.GetId(),
199 layerInfo.srcRect.x, layerInfo.srcRect.y, layerInfo.srcRect.w, layerInfo.srcRect.h,
200 layerInfo.dstRect.x, layerInfo.dstRect.y, layerInfo.dstRect.w, layerInfo.dstRect.h, layerInfo.zOrder);
201 }
202
GetForceClientForDRM(RSSurfaceRenderParams & params)203 bool RSUniRenderProcessor::GetForceClientForDRM(RSSurfaceRenderParams& params)
204 {
205 if (params.GetIsProtectedLayer() == false) {
206 return false;
207 }
208 if (params.GetAnimateState() == true ||
209 RSUniRenderUtil::GetRotationDegreeFromMatrix(params.GetTotalMatrix()) % RS_ROTATION_90 != 0) {
210 return true;
211 }
212 if (!params.GetCornerRadiusInfoForDRM().empty()) {
213 return true;
214 }
215 bool forceClientForDRM = false;
216 auto ancestorDisplayDrawable =
217 std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(params.GetAncestorDisplayDrawable().lock());
218 auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
219 if (ancestorDisplayDrawable == nullptr || ancestorDisplayDrawable->GetRenderParams() == nullptr ||
220 uniParam == nullptr) {
221 RS_LOGE("%{public}s ancestorDisplayDrawable/ancestorDisplayDrawableParams/uniParam is nullptr", __func__);
222 return false;
223 } else {
224 auto displayParams = static_cast<RSDisplayRenderParams*>(ancestorDisplayDrawable->GetRenderParams().get());
225 forceClientForDRM = displayParams->IsRotationChanged() || uniParam->GetCacheEnabledForRotation();
226 }
227 return forceClientForDRM;
228 }
229
GetLayerInfo(RSSurfaceRenderParams & params,sptr<SurfaceBuffer> & buffer,sptr<SurfaceBuffer> & preBuffer,const sptr<IConsumerSurface> & consumer,const sptr<SyncFence> & acquireFence)230 LayerInfoPtr RSUniRenderProcessor::GetLayerInfo(RSSurfaceRenderParams& params, sptr<SurfaceBuffer>& buffer,
231 sptr<SurfaceBuffer>& preBuffer, const sptr<IConsumerSurface>& consumer, const sptr<SyncFence>& acquireFence)
232 {
233 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
234 auto& layerInfo = params.layerInfo_;
235 layer->SetSurface(consumer);
236 layer->SetBuffer(buffer, acquireFence);
237 layer->SetPreBuffer(preBuffer);
238 params.SetPreBuffer(nullptr);
239 layer->SetZorder(layerInfo.zOrder);
240 layer->SetRotationFixed(params.GetFixRotationByUser());
241
242 GraphicLayerAlpha alpha;
243 alpha.enGlobalAlpha = true;
244 // Alpha of 255 indicates opacity
245 alpha.gAlpha = static_cast<uint8_t>(std::clamp(layerInfo.alpha, 0.0f, 1.0f) * RGBA_MAX);
246 layer->SetAlpha(alpha);
247 layer->SetLayerSize(layerInfo.dstRect);
248 layer->SetBoundSize(layerInfo.boundRect);
249 bool forceClientForDRM = GetForceClientForDRM(params);
250 RS_OPTIONAL_TRACE_NAME_FMT("%s nodeName[%s] forceClientForDRM[%d]",
251 __func__, params.GetName().c_str(), forceClientForDRM);
252 RS_LOGD("%{public}s nodeName[%{public}s] forceClientForDRM[%{public}d]",
253 __func__, params.GetName().c_str(), forceClientForDRM);
254 bool forceClient = RSSystemProperties::IsForceClient() || forceClientForDRM;
255 layer->SetCompositionType(forceClient ? GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT :
256 GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
257 layer->SetCornerRadiusInfoForDRM(params.GetCornerRadiusInfoForDRM());
258 auto bufferBackgroundColor = params.GetBackgroundColor();
259 GraphicLayerColor backgroundColor = {
260 .r = bufferBackgroundColor.GetRed(),
261 .g = bufferBackgroundColor.GetGreen(),
262 .b = bufferBackgroundColor.GetBlue(),
263 .a = bufferBackgroundColor.GetAlpha()
264 };
265 layer->SetBackgroundColor(backgroundColor);
266
267 std::vector<GraphicIRect> visibleRegions;
268 visibleRegions.emplace_back(layerInfo.dstRect);
269 layer->SetVisibleRegions(visibleRegions);
270 std::vector<GraphicIRect> dirtyRegions;
271 if (RSSystemProperties::GetHwcDirtyRegionEnabled()) {
272 const auto& dirtyRect = params.GetBufferDamage();
273 dirtyRegions.emplace_back(GraphicIRect { dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h });
274 } else {
275 dirtyRegions.emplace_back(layerInfo.srcRect);
276 }
277 layer->SetDirtyRegions(dirtyRegions);
278
279 layer->SetBlendType(layerInfo.blendType);
280 layer->SetCropRect(layerInfo.srcRect);
281 layer->SetGravity(layerInfo.gravity);
282 layer->SetTransform(layerInfo.transformType);
283 auto matrix = GraphicMatrix {layerInfo.matrix.Get(Drawing::Matrix::Index::SCALE_X),
284 layerInfo.matrix.Get(Drawing::Matrix::Index::SKEW_X), layerInfo.matrix.Get(Drawing::Matrix::Index::TRANS_X),
285 layerInfo.matrix.Get(Drawing::Matrix::Index::SKEW_Y), layerInfo.matrix.Get(Drawing::Matrix::Index::SCALE_Y),
286 layerInfo.matrix.Get(Drawing::Matrix::Index::TRANS_Y), layerInfo.matrix.Get(Drawing::Matrix::Index::PERSP_0),
287 layerInfo.matrix.Get(Drawing::Matrix::Index::PERSP_1), layerInfo.matrix.Get(Drawing::Matrix::Index::PERSP_2)};
288 layer->SetMatrix(matrix);
289 layer->SetScalingMode(params.GetScalingMode());
290 layer->SetLayerSourceTuning(params.GetLayerSourceTuning());
291 layer->SetClearCacheSet(params.GetBufferClearCacheSet());
292 layer->SetLayerArsr(layerInfo.arsrTag);
293 return layer;
294 }
295
ProcessSurface(RSSurfaceRenderNode & node)296 void RSUniRenderProcessor::ProcessSurface(RSSurfaceRenderNode &node)
297 {
298 RS_LOGE("It is update to DrawableV2 to process node now!!");
299 }
300
ProcessSurfaceForRenderThread(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable)301 void RSUniRenderProcessor::ProcessSurfaceForRenderThread(DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable)
302 {
303 auto layer = uniComposerAdapter_->CreateLayer(surfaceDrawable);
304 if (layer == nullptr) {
305 RS_LOGE("RSUniRenderProcessor::ProcessSurface: failed to createLayer for node(id: %{public}" PRIu64 ")",
306 surfaceDrawable.GetId());
307 return;
308 }
309 layers_.emplace_back(layer);
310 }
311
ProcessDisplaySurface(RSDisplayRenderNode & node)312 void RSUniRenderProcessor::ProcessDisplaySurface(RSDisplayRenderNode& node)
313 {
314 auto layer = uniComposerAdapter_->CreateLayer(node);
315 if (layer == nullptr) {
316 RS_LOGE("RSUniRenderProcessor::ProcessDisplaySurface: failed to createLayer for node(id: %{public}" PRIu64 ")",
317 node.GetId());
318 return;
319 }
320 if (node.GetFingerprint()) {
321 layer->SetLayerMaskInfo(HdiLayerInfo::LayerMask::LAYER_MASK_HBM_SYNC);
322 RS_LOGD("RSUniRenderProcessor::ProcessDisplaySurface, set layer mask hbm sync");
323 } else {
324 layer->SetLayerMaskInfo(HdiLayerInfo::LayerMask::LAYER_MASK_NORMAL);
325 }
326 layers_.emplace_back(layer);
327 layerNum_ = node.GetSurfaceCountForMultiLayersPerf();
328 auto drawable = node.GetRenderDrawable();
329 if (!drawable) {
330 return;
331 }
332 auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
333 auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
334 RSUniRenderThread::Instance().SetAcquireFence(surfaceHandler->GetAcquireFence());
335 }
336
ProcessDisplaySurfaceForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)337 void RSUniRenderProcessor::ProcessDisplaySurfaceForRenderThread(
338 DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
339 {
340 auto layer = uniComposerAdapter_->CreateLayer(displayDrawable);
341 if (layer == nullptr) {
342 RS_LOGE("RSUniRenderProcessor::ProcessDisplaySurface: failed to createLayer for node(id: %{public}" PRIu64 ")",
343 displayDrawable.GetId());
344 return;
345 }
346 auto& params = displayDrawable.GetRenderParams();
347 if (!params) {
348 return;
349 }
350 if (params->GetFingerprint()) {
351 layer->SetLayerMaskInfo(HdiLayerInfo::LayerMask::LAYER_MASK_HBM_SYNC);
352 RS_LOGD("RSUniRenderProcessor::ProcessDisplaySurface, set layer mask hbm sync");
353 } else {
354 layer->SetLayerMaskInfo(HdiLayerInfo::LayerMask::LAYER_MASK_NORMAL);
355 }
356 layers_.emplace_back(layer);
357 auto displayParams = static_cast<RSDisplayRenderParams*>(params.get());
358 for (const auto& drawable : displayParams->GetAllMainAndLeashSurfaceDrawables()) {
359 auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
360 if (!surfaceDrawable || !surfaceDrawable->GetRenderParams() ||
361 !surfaceDrawable->GetRenderParams()->GetOcclusionVisible() ||
362 surfaceDrawable->GetRenderParams()->IsLeashWindow()) {
363 continue;
364 }
365 layerNum_++;
366 }
367 auto surfaceHandler = displayDrawable.GetRSSurfaceHandlerOnDraw();
368 if (!surfaceHandler) {
369 return;
370 }
371 RSUniRenderThread::Instance().SetAcquireFence(surfaceHandler->GetAcquireFence());
372 }
373
ProcessRcdSurface(RSRcdSurfaceRenderNode & node)374 void RSUniRenderProcessor::ProcessRcdSurface(RSRcdSurfaceRenderNode& node)
375 {
376 auto layer = uniComposerAdapter_->CreateLayer(node);
377 if (layer == nullptr) {
378 RS_LOGE("RSUniRenderProcessor::ProcessRcdSurface: failed to createLayer for node(id: %{public}" PRIu64 ")",
379 node.GetId());
380 return;
381 }
382 layers_.emplace_back(layer);
383 }
384
385 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
GetLayers() const386 std::vector<LayerInfoPtr> RSUniRenderProcessor::GetLayers() const
387 {
388 return layers_;
389 }
390 #endif
391 } // namespace Rosen
392 } // namespace OHOS
393