• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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 "dfx_module.h"
17 #include "ace_log.h"
18 #include "ui_dump_dom_tree.h"
19 #ifdef FEATURE_ACELITE_MC_DFX_MODULE
20 #include "ui_snapshot.h"
21 #elif (FEATURE_ACELITE_LITE_DFX_MODULE == 1)
22 #ifdef __LITEOS_A__
23 #include "ability_env.h"
24 #endif
25 #include "ace_mem_base.h"
26 #include "js_fwk_common.h"
27 #include "ui_screenshot.h"
28 #endif
29 #ifdef __LITEOS_A__
30 #include "window/window.h"
31 #endif
32 
33 namespace OHOS {
34 namespace ACELite {
35 const char * const DfxModule::DOM_TREE_PATH = "dump_dom_tree.json";
36 
37 const char * const DfxModule::SCREEN_SNAP_PATH = "screensnap.bin";
38 
PreCheck(uint8_t argsNum)39 bool DfxModule::PreCheck(uint8_t argsNum)
40 {
41     if (argsNum > 1) {
42         HILOG_ERROR(HILOG_MODULE_ACE, "Dfx Module args num(%{public}d) is invalid, at most one parameter", argsNum);
43         return false;
44     }
45     return true;
46 }
47 
GetDomViewId(const JSIValue * args)48 char *DfxModule::GetDomViewId(const JSIValue *args)
49 {
50     if (args == nullptr) {
51         return nullptr;
52     }
53     return JSI::ValueToString(args[0]);
54 }
55 
IsEventInjectorRegistered(EventDataType type)56 bool DfxModule::IsEventInjectorRegistered(EventDataType type)
57 {
58     if ((EventInjector::GetInstance() == nullptr) || (!EventInjector::GetInstance()->IsEventInjectorRegistered(type) &&
59         !EventInjector::GetInstance()->RegisterEventInjector(type))) {
60         HILOG_ERROR(HILOG_MODULE_ACE, "register event error");
61         return false;
62     }
63 #ifdef __LITEOS_A__
64 #if ENABLE_WINDOW
65     if (RootView::GetInstance() == nullptr) {
66         HILOG_ERROR(HILOG_MODULE_ACE, "get root view error");
67         return false;
68     }
69     Window *window = RootView::GetInstance()->GetBoundWindow();
70     if (window == nullptr) {
71         HILOG_ERROR(HILOG_MODULE_ACE, "set window id error");
72         return false;
73     }
74     EventInjector::GetInstance()->SetWindowId(window->GetWindowId());
75 #endif
76 #endif
77     return true;
78 }
79 
80 #if (FEATURE_ACELITE_DFX_MODULE == 1)
Screenshot(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)81 JSIValue DfxModule::Screenshot(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
82 {
83 #ifdef FEATURE_ACELITE_MC_DFX_MODULE
84     JSIValue retVal = JSI::CreateBoolean(true);
85     if (!UISnapShot::ScreenshotToFile()) {
86         HILOG_ERROR(HILOG_MODULE_ACE, "screenshot failed");
87         JSI::ReleaseValue(retVal);
88         retVal = JSI::CreateBoolean(false);
89     }
90     return retVal;
91 #elif (FEATURE_ACELITE_LITE_DFX_MODULE == 1)
92     JSIValue retVal = JSI::CreateBoolean(true);
93 #ifdef __LITEOS_A__
94     const char * const savingPath = GetDataPath();
95 #elif defined(__linux__)
96     const char * const savingPath = "/storage/nfs";
97 #else
98     const char * const savingPath = "user/log";
99 #endif
100     char *path = RelocateResourceFilePath(savingPath, SCREEN_SNAP_PATH);
101     // uikit will deal with if path is null
102     if ((UIScreenshot::GetInstance() == nullptr) || (!UIScreenshot::GetInstance()->ScreenshotToFile(path))) {
103         HILOG_ERROR(HILOG_MODULE_ACE, "screenshot failed");
104         JSI::ReleaseValue(retVal);
105         retVal = JSI::CreateBoolean(false);
106     }
107     if (path != nullptr) {
108         ace_free(path);
109     }
110     return retVal;
111 #endif
112 }
113 #endif
114 
DumpDomTree(const JSIValue thisVal,const JSIValue * args,uint8_t argsNum)115 JSIValue DfxModule::DumpDomTree(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
116 {
117     JSIValue retVal = JSI::CreateBoolean(false);
118     if (!PreCheck(argsNum)) {
119         return retVal;
120     }
121 
122     char *viewId = GetDomViewId(args);
123 #if (FEATURE_ACELITE_LITE_DFX_MODULE == 1)
124 #ifdef __LITEOS_A__
125     const char * const savingPath = GetDataPath();
126 #elif defined(__linux__)
127     const char * const savingPath = "/storage/nfs";
128 #else
129     const char * const savingPath = "user/log";
130 #endif
131     char *path = RelocateResourceFilePath(savingPath, DOM_TREE_PATH);
132     // uikit will deal with if path and viewid is null
133     if ((UIDumpDomTree::GetInstance() != nullptr) && (UIDumpDomTree::GetInstance()->DumpDomTree(viewId, path))) {
134 #else
135     if ((UIDumpDomTree::GetInstance() != nullptr) && (UIDumpDomTree::GetInstance()->DumpDomTree(viewId))) {
136 #endif
137         JSI::ReleaseValue(retVal);
138         retVal = JSI::CreateBoolean(true);
139     }
140 
141 #if (FEATURE_ACELITE_LITE_DFX_MODULE == 1)
142     if (path != nullptr) {
143         ace_free(path);
144     }
145 #endif
146     JSI::ReleaseString(viewId);
147     return retVal;
148 }
149 
150 JSIValue DfxModule::DumpDomNode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
151 {
152     if (!PreCheck(argsNum) || (UIDumpDomTree::GetInstance() == nullptr)) {
153         return JSI::CreateUndefined();
154     }
155 
156     char *viewId = GetDomViewId(args);
157     char *msg = UIDumpDomTree::GetInstance()->DumpDomNode(viewId);
158     if (msg == nullptr) {
159         JSI::ReleaseString(viewId);
160         return JSI::CreateUndefined();
161     }
162     JSIValue retVal = JSI::CreateString(msg);
163     cJSON_free(msg); // use cjson malloc memory, use cJSON_free() instead of ace_free()
164     JSI::ReleaseString(viewId);
165     return retVal;
166 }
167 
168 JSIValue DfxModule::InjectPointEvent(const JSIValue *args, EventDataType type)
169 {
170     JSIValue retVal = JSI::CreateBoolean(true);
171     const uint8_t index = 2;
172     const uint32_t maxLen = 40;
173     // over 40 are ignored, ignore from beginning of the array
174     uint32_t len = JSI::GetArrayLength(args[0]);
175     uint32_t arrIndex = 0;
176     uint32_t realLen = (len > maxLen) ? maxLen : len;
177     DeviceData *data = (realLen > 0) ? static_cast<DeviceData *>(ace_malloc(sizeof(DeviceData) * realLen)) : nullptr;
178     if (len > maxLen) {
179         arrIndex = len - maxLen;
180     }
181     if (data == nullptr) {
182         HILOG_ERROR(HILOG_MODULE_ACE, "create device data failed");
183         JSI::ReleaseValue(retVal);
184         return JSI::CreateBoolean(false);
185     }
186 
187     for (uint16_t i = 0; arrIndex < len; i++, arrIndex++) {
188         JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
189         if (JSI::ValueIsUndefined(point)) {
190             HILOG_ERROR(HILOG_MODULE_ACE, "point is error");
191             ace_free(data);
192             JSI::ReleaseValue(retVal);
193             return JSI::CreateBoolean(false);
194         }
195         JSIValue point_x = JSI::GetPropertyByIndex(point, 0);
196         JSIValue point_y = JSI::GetPropertyByIndex(point, 1);
197         JSIValue state = JSI::GetPropertyByIndex(point, index);
198         data[i].point = {
199             static_cast<int16_t>(JSI::ValueToNumber(point_x)),
200             static_cast<int16_t>(JSI::ValueToNumber(point_y))
201         };
202         data[i].state = static_cast<uint16_t>(JSI::ValueToNumber(state));
203         JSI::ReleaseValueList(point_x, point_y, state, point);
204     }
205 
206     // simulate point event
207     if ((EventInjector::GetInstance() != nullptr) &&
208         (EventInjector::GetInstance()->SetInjectEvent(data, realLen, type))) {
209         ace_free(data);
210         return retVal;
211     }
212     HILOG_ERROR(HILOG_MODULE_ACE, "simulator point event error");
213     ace_free(data);
214     JSI::ReleaseValue(retVal);
215     return JSI::CreateBoolean(false);
216 }
217 
218 JSIValue DfxModule::InjectEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
219 {
220     // pre check
221     const uint8_t num = 2;
222     if (argsNum != num) {
223         HILOG_ERROR(HILOG_MODULE_ACE, "Dfx Module args num(%{public}d) is invalid, only one parameter", argsNum);
224         return JSI::CreateBoolean(false);
225     }
226 
227     // dispatch register event
228     char *eventType = JSI::ValueToString(args[1]);
229     if (eventType == nullptr) {
230         return JSI::CreateBoolean(false);
231     }
232     if (!strcmp(eventType, "point")) {
233         JSI::ReleaseString(eventType);
234         EventDataType type = EventDataType::POINT_TYPE;
235         if (!IsEventInjectorRegistered(type)) {
236             return JSI::CreateBoolean(false);
237         }
238         return InjectPointEvent(args, type);
239     }
240     HILOG_ERROR(HILOG_MODULE_ACE, "only support point event");
241 
242     JSI::ReleaseString(eventType);
243     return JSI::CreateBoolean(false);
244 }
245 
246 void DfxModule::OnDestroy()
247 {
248     // iterator remove all registered event
249     if (EventInjector::GetInstance() != nullptr) {
250         EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::POINT_TYPE);
251         EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::OTHERS);
252     }
253 }
254 } // namespace ACELite
255 } // namespace OHOS
256