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 "image_dfx.h"
17
18 #include <unistd.h>
19 #include <fstream>
20 #include <chrono>
21
22 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
23 #include <sys/timerfd.h>
24 #include "ffrt.h"
25 #include "hisysevent.h"
26 #endif
27
28 #include "image_utils.h"
29 #include "image_log.h"
30
31 namespace OHOS {
32 namespace Media {
33 static constexpr char IMAGE_FWK_UE[] = "IMAGE_FWK_UE";
34 const static std::string DEFAULT_VERSION_ID = "1";
35
ImageEvent()36 ImageEvent::ImageEvent()
37 {
38 startTime_ = ImageUtils::GetNowTimeMilliSeconds();
39 }
40
~ImageEvent()41 ImageEvent::~ImageEvent()
42 {
43 if (!options_.errorMsg.empty()) {
44 ReportDecodeFault();
45 } else {
46 ReportDecodeInfo();
47 }
48 }
49
SetDecodeInfoOptions(const DecodeInfoOptions & options)50 void ImageEvent::SetDecodeInfoOptions(const DecodeInfoOptions &options)
51 {
52 options_ = options;
53 }
54
GetDecodeInfoOptions()55 DecodeInfoOptions& ImageEvent::GetDecodeInfoOptions()
56 {
57 return options_;
58 }
59
SetDecodeErrorMsg(std::string msg)60 void ImageEvent::SetDecodeErrorMsg(std::string msg)
61 {
62 options_.errorMsg = msg;
63 }
64
getInvokeType()65 std::string ImageEvent::getInvokeType()
66 {
67 std::string invokeType;
68 switch (options_.invokeType) {
69 case (JS_INTERFACE):
70 invokeType = "js_interface";
71 break;
72 case (C_INTERFACE):
73 invokeType = "c_interface";
74 break;
75 default:
76 invokeType = "inner_interface";
77 }
78 return invokeType;
79 }
80
ReportDecodeFault()81 void ImageEvent::ReportDecodeFault()
82 {
83 std::string temp = getInvokeType();
84 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
85 int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
86 if (timerFd < 0) {
87 return;
88 }
89 close(timerFd);
90 DecodeInfoOptions options = options_;
91 ffrt::submit([options, temp] {
92 std::string packageName = ImageUtils::GetCurrentProcessName();
93 HiSysEventWrite(IMAGE_FWK_UE,
94 "DECODE_FAULT",
95 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
96 "PNAMEID", packageName,
97 "PVERSIONID", DEFAULT_VERSION_ID,
98 "APPLICATION_NAME", packageName,
99 "ROTATE", options.rotate,
100 "EDITABLE", options.editable,
101 "SAMPLE_SIZE", options.sampleSize,
102 "SOURCE_WIDTH", options.sourceWidth,
103 "SOURCE_HEIGHT", options.sourceHeight,
104 "DESIRE_SIZE_WIDTH", options.desireSizeWidth,
105 "DESIRE_SIZE_HEIGHT", options.desireSizeHeight,
106 "DESIRE_REGION_WIDTH", options.desireRegionWidth,
107 "DESIRE_REGION_HEIGHT", options.desireRegionHeight,
108 "DESIRE_REGION_X", options.desireRegionX,
109 "DESIRE_REGION_Y", options.desireRegionY,
110 "DESIRE_DESIRE_PIXEL_FORMAT", options.desirePixelFormat,
111 "INDEX", options.index,
112 "FIT_DENSITY", options.fitDensity,
113 "DESIRE_COLOR_SPACE", options.desireColorSpace,
114 "MIMETYPE", options.mimeType,
115 "MEMORY_SIZE", options.memorySize,
116 "MEMORY_TYPE", options.memoryType,
117 "IMAGE_SOURCE", options.imageSource,
118 "INVOKE_TYPE", temp,
119 "INCREMENTAL_DECODE", options.isIncrementalDecode,
120 "HARD_DECODE", options.isHardDecode,
121 "HARD_DECODE_ERROR", options.hardDecodeError,
122 "ERROR_MSG", options.errorMsg);
123 }, {}, {});
124 #endif
125 }
126
GetInvokeTypeStr(uint16_t invokeType)127 std::string GetInvokeTypeStr(uint16_t invokeType)
128 {
129 switch (invokeType) {
130 case (JS_INTERFACE):
131 return "js_interface";
132 case (C_INTERFACE):
133 return "c_interface";
134 default:
135 return "inner_interface";
136 }
137 }
138
ReportDecodeInfo()139 void ImageEvent::ReportDecodeInfo()
140 {
141 uint64_t costTime = ImageUtils::GetNowTimeMilliSeconds() - startTime_;
142 std::string temp = GetInvokeTypeStr(options_.invokeType);
143 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
144 int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
145 if (timerFd < 0) {
146 return;
147 }
148 close(timerFd);
149 DecodeInfoOptions options = options_;
150 ffrt::submit([options, temp, costTime] {
151 std::string packageName = ImageUtils::GetCurrentProcessName();
152 HiSysEventParam params[] = {
153 { .name = "PNAMEID", .t = HISYSEVENT_STRING, .v = { .s = const_cast<char*>(packageName.c_str()) } },
154 { .name = "PVERSIONID", .t = HISYSEVENT_STRING,
155 .v = { .s = const_cast<char*>(DEFAULT_VERSION_ID.c_str()) } },
156 { .name = "APPLICATION_NAME", .t = HISYSEVENT_STRING,
157 .v = { .s = const_cast<char*>(packageName.c_str()) } },
158 { .name = "ROTATE", .t = HISYSEVENT_FLOAT, .v = { .f = options.rotate } },
159 { .name = "EDITABLE", .t = HISYSEVENT_BOOL, .v = { .b = options.editable } },
160 { .name = "SAMPLE_SIZE", .t = HISYSEVENT_UINT32, .v = { .ui32 = options.sampleSize } },
161 { .name = "SOURCE_WIDTH", .t = HISYSEVENT_INT32, .v = { .i32 = options.sourceWidth } },
162 { .name = "SOURCE_HEIGHT", .t = HISYSEVENT_INT32, .v = { .i32 = options.sourceHeight } },
163 { .name = "DESIRE_SIZE_WIDTH", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireSizeWidth } },
164 { .name = "DESIRE_SIZE_HEIGHT", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireSizeHeight } },
165 { .name = "DESIRE_REGION_WIDTH", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireRegionWidth } },
166 { .name = "DESIRE_REGION_HEIGHT", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireRegionHeight } },
167 { .name = "DESIRE_REGION_X", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireRegionX } },
168 { .name = "DESIRE_REGION_Y", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireRegionY } },
169 { .name = "DESIRE_DESIRE_PIXEL_FORMAT", .t = HISYSEVENT_INT32, .v = { .i32 = options.desirePixelFormat } },
170 { .name = "INDEX", .t = HISYSEVENT_UINT32, .v = { .ui32 = options.index } },
171 { .name = "FIT_DENSITY", .t = HISYSEVENT_INT32, .v = { .i32 = options.fitDensity } },
172 { .name = "DESIRE_COLOR_SPACE", .t = HISYSEVENT_INT32, .v = { .i32 = options.desireColorSpace } },
173 { .name = "MIMETYPE", .t = HISYSEVENT_STRING, .v = { .s = const_cast<char*>(options.mimeType.c_str()) } },
174 { .name = "MEMORY_SIZE", .t = HISYSEVENT_UINT32, .v = { .ui32 = options.memorySize } },
175 { .name = "MEMORY_TYPE", .t = HISYSEVENT_INT32, .v = { .i32 = options.memoryType } },
176 { .name = "IMAGE_SOURCE", .t = HISYSEVENT_STRING,
177 .v = { .s = const_cast<char*>(options.imageSource.c_str()) } },
178 { .name = "INVOKE_TYPE", .t = HISYSEVENT_STRING, .v = { .s = const_cast<char*>(temp.c_str()) } },
179 { .name = "INCREMENTAL_DECODE", .t = HISYSEVENT_BOOL, .v = { .b = options.isIncrementalDecode } },
180 { .name = "HARD_DECODE", .t = HISYSEVENT_BOOL, .v = { .b = options.isHardDecode } },
181 { .name = "HARD_DECODE_ERROR", .t = HISYSEVENT_STRING,
182 .v = { .s = const_cast<char*>(options.hardDecodeError.c_str()) } },
183 { .name = "COST_TIME", .t = HISYSEVENT_UINT64, .v = { .ui64 = costTime } },
184 };
185 OH_HiSysEvent_Write(IMAGE_FWK_UE, "DECODE_INFORMATION", HISYSEVENT_BEHAVIOR, params,
186 sizeof(params) / sizeof(params[0]));
187 }, {}, {});
188 #endif
189 }
190
ReportCreateImageSourceFault(uint32_t width,uint32_t height,std::string type,std::string message)191 void ReportCreateImageSourceFault(uint32_t width, uint32_t height, std::string type, std::string message)
192 {
193 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
194 std::string packageName = ImageUtils::GetCurrentProcessName();
195 HiSysEventWrite(IMAGE_FWK_UE,
196 "CREATE_IMAGESOURCE_FAULT",
197 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
198 "PNAMEID", packageName,
199 "PVERSIONID", DEFAULT_VERSION_ID,
200 "WIDTH", width,
201 "HEIGHT", height,
202 "TYPE", type,
203 "ERROR_MSG", message);
204 #endif
205 }
206
ReportEncodeFault(uint32_t width,uint32_t height,std::string mimeType,std::string message)207 void ReportEncodeFault(uint32_t width, uint32_t height, std::string mimeType, std::string message)
208 {
209 #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
210 std::string packageName = ImageUtils::GetCurrentProcessName();
211 HiSysEventWrite(IMAGE_FWK_UE,
212 "ENCODE_FAULT",
213 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
214 "PNAMEID", packageName,
215 "PVERSIONID", DEFAULT_VERSION_ID,
216 "WIDTH", width,
217 "HEIGHT", height,
218 "MIME_TYPE", mimeType,
219 "ERROR_MSG", message);
220 #endif
221 }
222 } // namespace Media
223 } // namespace OHOS