• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "record_input.h"
17 
18 #include <ctime>
19 #include <dirent.h>
20 #include <fstream>
21 #include <iostream>
22 #include <regex>
23 #include <sys/stat.h>
24 #include <typeinfo>
25 
26 #include "ability_manager_client.h"
27 #include "multimode_manager.h"
28 
29 namespace OHOS {
30 namespace WuKong {
31 namespace {
32 const int INTERVALTIME = 1000;
33 const int OPERATIONINTERVAL = 400;
34 const int NUMTWO = 2;
35 std::string g_defaultDir = "/data/local/tmp/wukong/record";
36 std::ofstream g_outFile;
37 int64_t g_timeTemp = -1;
38 struct EventData {
39     int xPosi;
40     int yPosi;
41     int interval = 1;
42 };
43 
GetMillisTime()44 int64_t GetMillisTime()
45 {
46     auto timeNow = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
47     auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow.time_since_epoch());
48     return tmp.count();
49 }
50 
split(const std::string & in,const std::string & delim)51 static std::vector<std::string> split(const std::string &in, const std::string &delim)
52 {
53     std::regex reg(delim);
54     std::vector<std::string> res = {std::sregex_token_iterator(in.begin(), in.end(), reg, -1),
55                                     std::sregex_token_iterator()};
56     return res;
57 }
58 
WriteEventHead(std::ofstream & outFile)59 static void WriteEventHead(std::ofstream &outFile)
60 {
61     outFile << "x" << ',';
62     outFile << "y" << ',';
63     outFile << "interval" << std::endl;
64 }
65 
WriteEventData(std::ofstream & outFile,const EventData & data)66 static void WriteEventData(std::ofstream &outFile, const EventData &data)
67 {
68     outFile << data.xPosi << ',';
69     outFile << data.yPosi << ',';
70     outFile << data.interval << std::endl;
71 }
72 
InitReportFolder()73 bool InitReportFolder()
74 {
75     DIR *rootDir = nullptr;
76     if ((rootDir = opendir(g_defaultDir.c_str())) == nullptr) {
77         int ret = mkdir(g_defaultDir.c_str(), S_IROTH | S_IRWXU | S_IRWXG);
78         if (ret != 0) {
79             std::cerr << "failed to create dir: " << g_defaultDir << std::endl;
80             return false;
81         }
82     } else {
83         closedir(rootDir);
84     }
85     return true;
86 }
87 
InitEventRecordFile(std::ofstream & outFile,const std::string & recordName)88 bool InitEventRecordFile(std::ofstream &outFile, const std::string &recordName)
89 {
90     if (!InitReportFolder()) {
91         ERROR_LOG("init folder failed");
92         return false;
93     }
94     std::string filePath = g_defaultDir + "/" + recordName + ".csv";
95     outFile.open(filePath, std::ios_base::out | std::ios_base::trunc);
96     if (!outFile) {
97         ERROR_LOG_STR("Failed to create csv file at: %s", filePath.c_str());
98         return false;
99     }
100     WriteEventHead(outFile);
101     INFO_LOG_STR("The result will be written in csv file at location: %s", filePath.c_str());
102     return true;
103 }
104 
ReadEventLine(std::ifstream & inFile)105 ErrCode ReadEventLine(std::ifstream &inFile)
106 {
107     ErrCode result = OHOS::ERR_OK;
108     if (inFile.is_open()) {
109         int xPosi = -1;
110         int yPosi = -1;
111         int interval = -1;
112         bool jumpFlag = true;
113         std::string line;
114         while (std::getline(inFile, line)) {
115             if (jumpFlag) {
116                 jumpFlag = !jumpFlag;
117                 continue;
118             }
119             std::string delim = ",";
120             auto caseInfo = split(line, delim);
121             xPosi = std::stoi(caseInfo[0]);
122             yPosi = std::stoi(caseInfo[1]);
123             interval = std::stoi(caseInfo[NUMTWO]);
124             INFO_LOG_STR("Position: (%d,%d)  interval: %d", xPosi, yPosi, interval);
125             auto recordTouchInput = MultimodeManager::GetInstance();
126             result = recordTouchInput->PointerInput(xPosi, yPosi, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
127                                                     MMI::PointerEvent::POINTER_ACTION_DOWN);
128             if (result != OHOS::ERR_OK) {
129                 ERROR_LOG("input failed");
130                 inFile.close();
131                 return result;
132             }
133             result = recordTouchInput->PointerInput(xPosi, yPosi, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
134                                                     MMI::PointerEvent::POINTER_ACTION_UP);
135             usleep(interval * INTERVALTIME);
136         }
137         inFile.close();
138     }
139     return result;
140 }
141 
142 class InputEventCallback : public MMI::IInputEventConsumer {
143 public:
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const144     void OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const override
145     {
146         INFO_LOG_STR("keyCode: %d", keyEvent->GetKeyCode());
147     }
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const148     void OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const override
149     {
150         MMI::PointerEvent::PointerItem item;
151         bool result = pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), item);
152         if (!result) {
153             ERROR_LOG("GetPointerItem Fail");
154         }
155         EventData data {};
156         int64_t currentTime = GetMillisTime();
157         if (g_timeTemp == -1) {
158             g_timeTemp = currentTime;
159             data.interval = INTERVALTIME;
160         } else {
161             data.interval = currentTime - g_timeTemp;
162             if (data.interval < OPERATIONINTERVAL) {
163                 return;
164             }
165             g_timeTemp = currentTime;
166         }
167         data.xPosi = item.GetDisplayX();
168         data.yPosi = item.GetDisplayY();
169         WriteEventData(g_outFile, data);
170         INFO_LOG_STR("PointerEvent received. interval: %d xPosi: %d yPosi: %d", data.interval, data.xPosi, data.yPosi);
171     }
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const172     void OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const override
173     {
174     }
175     static std::shared_ptr<InputEventCallback> GetPtr();
176 };
177 
GetPtr()178 std::shared_ptr<InputEventCallback> InputEventCallback::GetPtr()
179 {
180     return std::make_shared<InputEventCallback>();
181 }
182 }  // namespace
RecordInput()183 RecordInput::RecordInput() : InputAction()
184 {
185 }
186 
~RecordInput()187 RecordInput::~RecordInput()
188 {
189 }
190 
OrderInput(const std::shared_ptr<SpcialTestObject> & specialTestObject)191 ErrCode RecordInput::OrderInput(const std::shared_ptr<SpcialTestObject> &specialTestObject)
192 {
193     int result = ERR_OK;
194     auto recordPtr = std::static_pointer_cast<RecordParam>(specialTestObject);
195     if (recordPtr->recordStatus_) {
196         if (!InitEventRecordFile(g_outFile, recordPtr->recordName_)) {
197             ERROR_LOG("init file failed");
198             specialTestObject->isAllFinished_ = true;
199             return OHOS::ERR_INVALID_VALUE;
200         }
201         auto callBackPtr = InputEventCallback::GetPtr();
202         if (callBackPtr == nullptr) {
203             ERROR_LOG("input callback is nullptr");
204             specialTestObject->isAllFinished_ = true;
205             return OHOS::ERR_INVALID_VALUE;
206         }
207         int32_t id1 = MMI::InputManager::GetInstance()->AddMonitor(callBackPtr);
208         if (id1 == -1) {
209             ERROR_LOG("Startup Failed!");
210             specialTestObject->isAllFinished_ = true;
211             return OHOS::ERR_INVALID_VALUE;
212         }
213         INFO_LOG("Started Recording Successfully...");
214         int flag = getc(stdin);
215         specialTestObject->isAllFinished_ = true;
216         TRACK_LOG_STR("flag: %d", flag);
217     } else {
218         std::ifstream inFile(g_defaultDir + "/" + recordPtr->recordName_ + ".csv");
219         result = ReadEventLine(inFile);
220         if (result != ERR_OK) {
221             WARN_LOG("this input failed");
222             return result;
223         }
224     }
225     return result;
226 }
227 }  // namespace WuKong
228 }  // namespace OHOS
229