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