• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "boomerang_dumper.h"
17 
18 #include <getopt.h>
19 #include <securec.h>
20 
21 #include "devicestatus_define.h"
22 
23 #undef LOG_TAG
24 #define LOG_TAG "BoomerangDumper"
25 
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
Dump(int32_t fd,const std::vector<std::string> & args)29 void BoomerangDumper::Dump(int32_t fd, const std::vector<std::string> &args)
30 {
31     constexpr size_t bufSize { 1024 };
32     char buf[bufSize] { "hidumper" };
33 
34     std::vector<char *> argv(args.size() + 1);
35     argv[0] = buf;
36 
37     size_t len = std::strlen(buf) + 1;
38     char *pbuf = buf + len;
39     size_t bufLen = sizeof(buf) - len;
40 
41     for (size_t index = 0, cnt = args.size(); index < cnt; ++index) {
42         size_t argLen = args[index].size();
43         if (argLen + 1 > bufLen) {
44             FI_HILOGE("Buffer overflow");
45             return;
46         }
47         if (argLen > 0) {
48             args[index].copy(pbuf, argLen);
49             pbuf[argLen] = '\0';
50         } else {
51             pbuf[0] = '\0';
52         }
53 
54         argv[index + 1] = pbuf;
55         pbuf += argLen + 1;
56         bufLen -= argLen + 1;
57     }
58 
59     struct option dumpOptions[] {
60         { "help", no_argument, nullptr, 'h' },
61         { "subscribe", no_argument, nullptr, 's' },
62         { "list", no_argument, nullptr, 'l' },
63         { "current", no_argument, nullptr, 'c' },
64         { "drag", no_argument, nullptr, 'd' },
65         { "macroState", no_argument, nullptr, 'm' },
66         { nullptr, 0, nullptr, 0 }
67     };
68     optind = 0;
69     int32_t opt = -1;
70 
71     while ((opt = getopt_long(argv.size(), argv.data(), "+hslcodm", dumpOptions, nullptr)) >= 0) {
72         DumpOnce(fd, opt);
73     }
74 }
75 
DumpOnce(int32_t fd,int32_t option)76 void BoomerangDumper::DumpOnce(int32_t fd, int32_t option)
77 {
78     switch (option) {
79         case 's': {
80             DumpDeviceStatusSubscriber(fd);
81             break;
82         }
83         case 'l': {
84             DumpDeviceStatusChanges(fd);
85             break;
86         }
87         case 'c': {
88             DumpCurrentDeviceStatus(fd);
89             break;
90         }
91         case 'd': {
92             DumpDrag(fd);
93             break;
94         }
95         case 'm': {
96             DumpCheckDefine(fd);
97             break;
98         }
99         default: {
100             DumpHelpInfo(fd);
101             break;
102         }
103     }
104 }
105 
DumpHelpInfo(int32_t fd) const106 void BoomerangDumper::DumpHelpInfo(int32_t fd) const
107 {
108     dprintf(fd, "Usage:\n");
109     dprintf(fd, "\t-h\t\tdump help\n");
110     dprintf(fd, "\t-s\t\tdump the subscribers\n");
111     dprintf(fd, "\t-l\t\tdump the last 10 device status change\n");
112     dprintf(fd, "\t-c\t\tdump the current device status\n");
113     dprintf(fd, "\t-d\t\tdump the drag status\n");
114     dprintf(fd, "\t-m\t\tdump the macro state\n");
115 }
116 
DumpDeviceStatusSubscriber(int32_t fd) const117 void BoomerangDumper::DumpDeviceStatusSubscriber(int32_t fd) const
118 {
119     CHKPV(env_);
120     FI_HILOGI("Dump subscribers of device status");
121     int32_t ret = env_->GetDelegateTasks().PostSyncTask([this, fd] {
122         boomerang_.DumpDeviceStatusSubscriber(fd);
123         return RET_OK;
124     });
125     if (ret != RET_OK) {
126         FI_HILOGE("IDelegateTasks::PostSyncTask fail, error:%{public}d", ret);
127     }
128 }
129 
DumpDeviceStatusChanges(int32_t fd) const130 void BoomerangDumper::DumpDeviceStatusChanges(int32_t fd) const
131 {
132     CHKPV(env_);
133     FI_HILOGI("Dump changes of device status");
134     int32_t ret = env_->GetDelegateTasks().PostSyncTask([this, fd] {
135         boomerang_.DumpDeviceStatusChanges(fd);
136         return RET_OK;
137     });
138     if (ret != RET_OK) {
139         FI_HILOGE("IDelegateTasks::PostSyncTask fail, error:%{public}d", ret);
140     }
141 }
142 
DumpCurrentDeviceStatus(int32_t fd)143 void BoomerangDumper::DumpCurrentDeviceStatus(int32_t fd)
144 {
145     CHKPV(env_);
146     FI_HILOGI("Dump current device status");
147     int32_t ret = env_->GetDelegateTasks().PostSyncTask([this, fd] {
148         boomerang_.DumpDeviceStatusChanges(fd);
149         return RET_OK;
150     });
151     if (ret != RET_OK) {
152         FI_HILOGE("IDelegateTasks::PostSyncTask fail, error:%{public}d", ret);
153     }
154 }
155 
DumpDrag(int32_t fd) const156 void BoomerangDumper::DumpDrag(int32_t fd) const
157 {
158     CHKPV(env_);
159     FI_HILOGI("Dump drag information");
160     int32_t ret = env_->GetDelegateTasks().PostSyncTask([env = env_, fd] {
161         env->GetDragManager().Dump(fd);
162         return RET_OK;
163     });
164     if (ret != RET_OK) {
165         FI_HILOGE("IDelegateTasks::PostSyncTask fail, error:%{public}d", ret);
166     }
167 }
168 
DumpCheckDefine(int32_t fd) const169 void BoomerangDumper::DumpCheckDefine(int32_t fd) const
170 {
171     CheckDefineOutput(fd, "Macro switch state:\n");
172 #ifdef OHOS_BUILD_ENABLE_COORDINATION
173     CheckDefineOutput(fd, "\t%s\n", "OHOS_BUILD_ENABLE_COORDINATION");
174 #endif // OHOS_BUILD_ENABLE_COORDINATION
175 }
176 
177 template<class ...Ts>
CheckDefineOutput(int32_t fd,const char * fmt,Ts...args) const178 void BoomerangDumper::CheckDefineOutput(int32_t fd, const char* fmt, Ts... args) const
179 {
180     char buf[MAX_PACKET_BUF_SIZE] {};
181     int32_t ret = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, fmt, args...);
182     if (ret < 0) {
183         FI_HILOGE("snprintf_s fail, error:%{public}d", ret);
184         return;
185     }
186     dprintf(fd, "%s", buf);
187 }
188 } // namespace DeviceStatus
189 } // namespace Msdp
190 } // namespace OHOS