• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "input_display_bind_helper.h"
17 
18 #include <fstream>
19 
20 #include "parameters.h"
21 #include "util.h"
22 
23 #undef MMI_LOG_DOMAIN
24 #define MMI_LOG_DOMAIN MMI_LOG_WINDOW
25 #undef MMI_LOG_TAG
26 #define MMI_LOG_TAG "InputDisplayBindHelper"
27 
28 namespace OHOS {
29 namespace MMI {
30 namespace {
31 const std::string FOLD_SCREEN_FLAG = system::GetParameter("const.window.foldscreen.type", "");
32 const char* INPUT_DEVICE_NAME_CONFIG { "/sys_prod/etc/input/input_device_name.cfg" };
33 const std::string DIRECTORY { "/sys/devices/virtual/input" };
34 const char* SEPARATOR { "/" };
35 const char* SUFFIX { "0000:0000" };
36 const std::string INPUT { "input" };
37 const std::string EVENT { "event" };
38 const char* NAME { "name" };
39 const int32_t DISPLAY_ID_MAIN { 0 };
40 const int32_t DISPLAY_ID_SUB { 5 };
41 }
42 
43 namespace fs = std::filesystem;
44 
IsDualDisplayFoldDevice()45 static bool IsDualDisplayFoldDevice()
46 {
47     return (!FOLD_SCREEN_FLAG.empty() && (FOLD_SCREEN_FLAG[0] == '2' || FOLD_SCREEN_FLAG[0] == '4'));
48 }
49 
GetInputDeviceId() const50 int32_t BindInfo::GetInputDeviceId() const
51 {
52     return inputDeviceId_;
53 }
54 
GetInputDeviceName() const55 std::string BindInfo::GetInputDeviceName() const
56 {
57     return inputDeviceName_;
58 }
59 
GetDisplayId() const60 int32_t BindInfo::GetDisplayId() const
61 {
62     return displayId_;
63 }
64 
GetDisplayName() const65 std::string BindInfo::GetDisplayName() const
66 {
67     return displayName_;
68 }
69 
IsUnbind() const70 bool BindInfo::IsUnbind() const
71 {
72     return ((inputDeviceId_ == -1) || (displayId_ == -1));
73 }
74 
InputDeviceNotBind() const75 bool BindInfo::InputDeviceNotBind() const
76 {
77     return (inputDeviceId_ == -1);
78 }
79 
DisplayNotBind() const80 bool BindInfo::DisplayNotBind() const
81 {
82     return (displayId_ == -1);
83 }
84 
AddInputDevice(int32_t deviceId,const std::string & deviceName)85 bool BindInfo::AddInputDevice(int32_t deviceId, const std::string &deviceName)
86 {
87     if ((inputDeviceId_ != -1) || !inputDeviceName_.empty()) {
88         return false;
89     }
90     inputDeviceId_ = deviceId;
91     inputDeviceName_ = deviceName;
92     return true;
93 }
94 
RemoveInputDevice()95 void BindInfo::RemoveInputDevice()
96 {
97     inputDeviceId_ = -1;
98     inputDeviceName_.clear();
99 }
100 
AddDisplay(int32_t id,const std::string & name)101 bool BindInfo::AddDisplay(int32_t id, const std::string &name)
102 {
103     if ((displayId_ != -1) || !displayName_.empty()) {
104         return false;
105     }
106     displayId_ = id;
107     displayName_ = name;
108     return true;
109 }
110 
RemoveDisplay()111 void BindInfo::RemoveDisplay()
112 {
113     displayId_ = -1;
114     displayName_.clear();
115 }
116 
GetDesc() const117 std::string BindInfo::GetDesc() const
118 {
119     std::ostringstream oss;
120     oss << "InputDevice(id:" << inputDeviceId_ << ",name:" << inputDeviceName_ << "),Display(id:" << displayId_ <<
121         ",name:" << displayName_ << ")";
122     return oss.str();
123 }
124 
operator <(const BindInfo & l,const BindInfo & r)125 bool operator < (const BindInfo &l, const BindInfo &r)
126 {
127     if (l.inputDeviceId_ != r.inputDeviceId_) {
128         return (l.inputDeviceId_ < r.inputDeviceId_);
129     }
130     return (l.displayId_ < r.displayId_);
131 }
132 
operator <<(std::ostream & os,const BindInfo & r)133 std::ostream &operator << (std::ostream &os, const BindInfo &r)
134 {
135     os << r.inputDeviceName_ << "<=>" << r.displayName_ << std::endl;
136     return os;
137 }
138 
operator >>(std::istream & is,BindInfo & r)139 std::istream &operator >> (std::istream &is, BindInfo &r)
140 {
141     std::string line;
142     std::getline(is, line);
143     const std::string delim = "<=>";
144     std::string::size_type pos = line.find(delim);
145     if (pos == std::string::npos) {
146         return is;
147     }
148     r.inputDeviceName_ = line.substr(0, pos);
149     r.displayName_ = line.substr(pos + delim.length());
150     r.inputDeviceId_ = 0;
151     r.displayId_ = 0;
152     return is;
153 }
154 
GetDesc() const155 std::string BindInfos::GetDesc() const
156 {
157     int32_t index = 0;
158     std::ostringstream oss;
159     for (const auto &info : infos_) {
160         oss << "index:" << index << "," << info.GetDesc() << std::endl;
161     }
162     return oss.str();
163 }
164 
GetInfos() const165 const std::list<BindInfo> &BindInfos::GetInfos() const
166 {
167     return infos_;
168 }
169 
GetBindDisplayIdByInputDevice(int32_t inputDeviceId) const170 int32_t BindInfos::GetBindDisplayIdByInputDevice(int32_t inputDeviceId) const
171 {
172     for (const auto &item : infos_) {
173         if (item.GetInputDeviceId() == inputDeviceId) {
174             if (!item.IsUnbind()) {
175                 return item.GetDisplayId();
176             }
177         }
178     }
179     return -1;
180 }
181 
GetBindDisplayNameByInputDevice(int32_t inputDeviceId) const182 std::string BindInfos::GetBindDisplayNameByInputDevice(int32_t inputDeviceId) const
183 {
184     for (const auto &item : infos_) {
185         if (item.GetInputDeviceId() == inputDeviceId) {
186             if (!item.IsUnbind()) {
187                 return item.GetDisplayName();
188             }
189         }
190     }
191     return "";
192 }
193 
GetDisplayNameByInputDevice(const std::string & name) const194 std::string BindInfos::GetDisplayNameByInputDevice(const std::string &name) const
195 {
196     for (const auto &item : infos_) {
197         if (item.GetInputDeviceName() == name) {
198             return item.GetDisplayName();
199         }
200     }
201     return "";
202 }
203 
GetInputDeviceByDisplayName(const std::string & name) const204 std::string BindInfos::GetInputDeviceByDisplayName(const std::string &name) const
205 {
206     for (const auto &item : infos_) {
207         if (item.GetDisplayName() == name) {
208             return item.GetInputDeviceName();
209         }
210     }
211     return "";
212 }
213 
Add(const BindInfo & info)214 bool BindInfos::Add(const BindInfo &info)
215 {
216     auto it = infos_.begin();
217     for (; it != infos_.end(); ++it) {
218         if (info < *it) {
219             break;
220         }
221     }
222     auto it2 = infos_.emplace(it, std::move(info));
223     if (it2 == infos_.end()) {
224         MMI_HILOGE("Duplicate %{public}s", info.GetDesc().c_str());
225     }
226     return true;
227 }
228 
UnbindInputDevice(int32_t deviceId)229 void BindInfos::UnbindInputDevice(int32_t deviceId)
230 {
231     auto it = infos_.begin();
232     for (; it != infos_.end(); ++it) {
233         if (it->GetInputDeviceId() == deviceId) {
234             it->RemoveInputDevice();
235             infos_.erase(it);
236             return;
237         }
238     }
239 }
240 
UnbindDisplay(int32_t displayId)241 void BindInfos::UnbindDisplay(int32_t displayId)
242 {
243     auto it = infos_.begin();
244     for (; it != infos_.end(); ++it) {
245         if (it->GetDisplayId() == displayId) {
246             it->RemoveDisplay();
247             infos_.erase(it);
248             return;
249         }
250     }
251 }
252 
GetUnbindInputDevice(const std::string & displayName)253 BindInfo BindInfos::GetUnbindInputDevice(const std::string &displayName)
254 {
255     auto it = infos_.begin();
256     while (it != infos_.end()) {
257         if (it->InputDeviceNotBind()) {
258             if (it->GetDisplayName() == displayName) {
259                 auto info = std::move(*it);
260                 infos_.erase(it);
261                 return info;
262             }
263         }
264         ++it;
265     }
266     return BindInfo();
267 }
268 
GetUnbindDisplay()269 BindInfo BindInfos::GetUnbindDisplay()
270 {
271     auto it = infos_.begin();
272     while (it != infos_.end()) {
273         if (it->DisplayNotBind()) {
274             auto info = std::move(*it);
275             infos_.erase(it);
276             return info;
277         }
278         ++it;
279     }
280     return BindInfo();
281 }
282 
GetUnbindDisplay(const std::string & inputDeviceName)283 BindInfo BindInfos::GetUnbindDisplay(const std::string &inputDeviceName)
284 {
285     auto it = infos_.begin();
286     while (it != infos_.end()) {
287         if (it->DisplayNotBind()) {
288             if (it->GetInputDeviceName() == inputDeviceName) {
289                 auto info = std::move(*it);
290                 infos_.erase(it);
291                 return info;
292             }
293         }
294         ++it;
295     }
296     return GetUnbindDisplay();
297 }
298 
operator <<(std::ostream & os,const BindInfos & r)299 std::ostream &operator << (std::ostream &os, const BindInfos &r)
300 {
301     const auto &infos = r.GetInfos();
302     for (const auto &info : infos) {
303         if (!info.IsUnbind()) {
304             os << info;
305         }
306     }
307     return os;
308 }
309 
operator >>(std::istream & is,BindInfos & r)310 std::istream &operator >> (std::istream &is, BindInfos &r)
311 {
312     while (!is.eof()) {
313         BindInfo info;
314         is >> info;
315         if (info.IsUnbind()) {
316             break;
317         }
318         r.Add(info);
319     }
320     return is;
321 }
322 
InputDisplayBindHelper(const std::string bindCfgFile)323 InputDisplayBindHelper::InputDisplayBindHelper(const std::string bindCfgFile)
324     : fileName_(bindCfgFile), infos_(std::make_shared<BindInfos>()), configFileInfos_(std::make_shared<BindInfos>())
325 {}
326 
GetBindDisplayNameByInputDevice(int32_t inputDeviceId) const327 std::string InputDisplayBindHelper::GetBindDisplayNameByInputDevice(int32_t inputDeviceId) const
328 {
329     CALL_DEBUG_ENTER;
330     CHKPO(infos_);
331     return infos_->GetBindDisplayNameByInputDevice(inputDeviceId);
332 }
333 
AddInputDevice(int32_t id,const std::string & name)334 void InputDisplayBindHelper::AddInputDevice(int32_t id, const std::string &name)
335 {
336     CALL_DEBUG_ENTER;
337     MMI_HILOGD("Param: id:%{public}d, name:%{public}s", id, name.c_str());
338     auto displayName = configFileInfos_->GetDisplayNameByInputDevice(name);
339     BindInfo info = infos_->GetUnbindInputDevice(displayName);
340     info.AddInputDevice(id, name);
341     infos_->Add(info);
342     Store();
343 }
344 
RemoveInputDevice(int32_t id)345 void InputDisplayBindHelper::RemoveInputDevice(int32_t id)
346 {
347     CALL_DEBUG_ENTER;
348     MMI_HILOGD("Param: id:%{public}d", id);
349     infos_->UnbindInputDevice(id);
350 }
351 
IsDisplayAdd(int32_t id,const std::string & name)352 bool InputDisplayBindHelper::IsDisplayAdd(int32_t id, const std::string &name)
353 {
354     const auto &infos = infos_->GetInfos();
355     for (const auto &info : infos) {
356         if ((info.GetDisplayName() == name) && (info.GetDisplayId() == id)) {
357             return true;
358         }
359     }
360     return false;
361 }
362 
GetDisplayIdNames() const363 std::set<std::pair<int32_t, std::string>> InputDisplayBindHelper::GetDisplayIdNames() const
364 {
365     CALL_DEBUG_ENTER;
366     std::set<std::pair<int32_t, std::string>> idNames;
367     const auto &infos = infos_->GetInfos();
368     for (const auto &info : infos) {
369         if (info.GetDisplayId() != -1) {
370             idNames.insert(std::make_pair(info.GetDisplayId(), info.GetDisplayName()));
371         }
372     }
373     return idNames;
374 }
375 
AddDisplay(int32_t id,const std::string & name)376 void InputDisplayBindHelper::AddDisplay(int32_t id, const std::string &name)
377 {
378     CALL_DEBUG_ENTER;
379     MMI_HILOGD("Param: id:%{public}d, name:%{public}s", id, name.c_str());
380     auto inputDeviceName = configFileInfos_->GetInputDeviceByDisplayName(name);
381     if (IsDualDisplayFoldDevice()) {
382         std::string deviceName = GetInputDeviceById(id);
383         if (!deviceName.empty()) {
384             inputDeviceName = deviceName;
385         }
386     }
387     BindInfo info = infos_->GetUnbindDisplay(inputDeviceName);
388     info.AddDisplay(id, name);
389     infos_->Add(info);
390     Store();
391 }
392 
AddLocalDisplay(int32_t id,const std::string & name)393 void InputDisplayBindHelper::AddLocalDisplay(int32_t id, const std::string &name)
394 {
395     CALL_DEBUG_ENTER;
396     MMI_HILOGD("Param: id:%{public}d, name:%{public}s", id, name.c_str());
397     CHKPV(infos_);
398 
399     const auto &infos = infos_->GetInfos();
400     std::vector<std::string> unbindDevices;
401     for (const auto &info : infos) {
402         if (info.DisplayNotBind()) {
403             unbindDevices.push_back(info.GetInputDeviceName());
404             MMI_HILOGI("Unbind InputDevice, id:%{public}d, inputDevice:%{public}s",
405                 info.GetInputDeviceId(), info.GetInputDeviceName().c_str());
406         }
407     }
408 
409     bool IsStore = false;
410     for (auto &item : unbindDevices) {
411         auto inputDeviceName = item;
412         if (IsDualDisplayFoldDevice()) {
413             std::string deviceName = GetInputDeviceById(id);
414             if (!deviceName.empty()) {
415                 inputDeviceName = deviceName;
416             }
417         }
418         BindInfo info = infos_->GetUnbindDisplay(inputDeviceName);
419         info.AddDisplay(id, name);
420         infos_->Add(info);
421         IsStore = true;
422     }
423     if (IsStore) {
424         Store();
425     }
426     unbindDevices.clear();
427 }
428 
GetInputDeviceById(int32_t id)429 std::string InputDisplayBindHelper::GetInputDeviceById(int32_t id)
430 {
431     CALL_DEBUG_ENTER;
432     if (id != DISPLAY_ID_MAIN && id != DISPLAY_ID_SUB) {
433         return "";
434     }
435 
436     std::string inputNodeName = GetInputNodeNameByCfg(id);
437     if (inputNodeName.empty()) {
438         return "";
439     }
440 
441     std::string inputNode = GetInputNode(inputNodeName);
442     if (inputNode.empty()) {
443         return "";
444     }
445 
446     std::string inputEvent = inputNode;
447     size_t pos = inputEvent.find(INPUT);
448     if (pos != std::string::npos) {
449         inputEvent.replace(pos, INPUT.length(), EVENT);
450     }
451 
452     std::string inputDeviceName;
453     inputDeviceName.append(DIRECTORY).append(SEPARATOR)
454         .append(inputNode).append(SEPARATOR)
455         .append(inputEvent).append(SUFFIX);
456 
457     MMI_HILOGI("GetInputDeviceById, id:%{public}d, inputDevice:%{public}s", id, inputDeviceName.c_str());
458     return inputDeviceName;
459 }
460 
GetInputNodeNameByCfg(int32_t id)461 std::string InputDisplayBindHelper::GetInputNodeNameByCfg(int32_t id)
462 {
463     CALL_DEBUG_ENTER;
464     std::ifstream file(INPUT_DEVICE_NAME_CONFIG);
465     std::string res;
466     if (file.is_open()) {
467         std::string line;
468         while (getline(file, line)) {
469             const std::string delim = "<=>";
470             size_t pos = line.find(delim);
471             if (pos == std::string::npos) {
472                 continue;
473             }
474             std::string displayId = line.substr(0, pos);
475             std::string inputNodeName = line.substr(pos + delim.length());
476             if (!displayId.empty() && !inputNodeName.empty()
477                 && std::all_of(displayId.begin(), displayId.end(), ::isdigit)
478                 && std::atoi(displayId.c_str()) == id) {
479                 res = inputNodeName;
480                 break;
481             }
482         }
483         file.close();
484     }
485     if (!res.empty() && (res.back() == '\n' || res.back() == '\r')) {
486         res.pop_back();
487     }
488     return res;
489 }
490 
GetContent(const std::string & fileName)491 std::string InputDisplayBindHelper::GetContent(const std::string &fileName)
492 {
493     CALL_DEBUG_ENTER;
494     std::string content;
495     char realPath[PATH_MAX] = {};
496     if (realpath(fileName.c_str(), realPath) == nullptr) {
497         MMI_HILOGE("The realpath return nullptr");
498         return content;
499     }
500     std::ifstream file(realPath);
501     if (file.is_open()) {
502         std::string line;
503         while (getline(file, line)) {
504             content.append(line);
505         }
506         file.close();
507     }
508     return content;
509 }
510 
GetInputNode(const std::string & inputNodeName)511 std::string InputDisplayBindHelper::GetInputNode(const std::string &inputNodeName)
512 {
513     CALL_DEBUG_ENTER;
514     std::string inputNode;
515     if (fs::exists(DIRECTORY) && fs::is_directory(DIRECTORY)) {
516         for (const auto& entry : fs::directory_iterator(DIRECTORY)) {
517             std::string node = fs::path(entry.path()).filename();
518             std::string file;
519             file.append(DIRECTORY).append(SEPARATOR)
520                 .append(node).append(SEPARATOR)
521                 .append(NAME);
522             if (inputNodeName == GetContent(file)) {
523                 inputNode = node;
524                 break;
525             }
526         }
527     }
528     return inputNode;
529 }
530 
RemoveDisplay(int32_t id)531 void InputDisplayBindHelper::RemoveDisplay(int32_t id)
532 {
533     CALL_DEBUG_ENTER;
534     MMI_HILOGD("Param: id:%{public}d", id);
535     infos_->UnbindDisplay(id);
536 }
537 
Store()538 void InputDisplayBindHelper::Store()
539 {
540     CALL_DEBUG_ENTER;
541     CHKPV(infos_);
542     char realPath[PATH_MAX] = {};
543     CHKPV(realpath(fileName_.c_str(), realPath));
544     if (!IsValidJsonPath(realPath)) {
545         MMI_HILOGE("File path is invalid");
546         return;
547     }
548     std::ofstream ofs(realPath, std::ios::trunc | std::ios::out | std::ios_base::binary);
549     if (!ofs) {
550         MMI_HILOGE("Open file fail.%{public}s, errno:%{public}d", realPath, errno);
551         return;
552     }
553     ofs << *infos_;
554     ofs.close();
555 }
556 
GetDisplayBindInfo(DisplayBindInfos & infos)557 int32_t InputDisplayBindHelper::GetDisplayBindInfo(DisplayBindInfos &infos)
558 {
559     CALL_DEBUG_ENTER;
560     CHKPR(infos_, RET_ERR);
561     for (const auto &item : infos_->GetInfos()) {
562         infos.push_back({
563             .inputDeviceId = item.GetInputDeviceId(),
564             .inputDeviceName = item.GetInputDeviceName(),
565             .displayId = item.GetDisplayId(),
566             .displayName = item.GetDisplayName(),
567         });
568     }
569     return RET_OK;
570 }
571 
SetDisplayBind(int32_t deviceId,int32_t displayId,std::string & msg)572 int32_t InputDisplayBindHelper::SetDisplayBind(int32_t deviceId, int32_t displayId, std::string &msg)
573 {
574     CALL_DEBUG_ENTER;
575     MMI_HILOGD("Param: deviceId:%{public}d, displayId:%{public}d", deviceId, displayId);
576     if ((deviceId == -1) || (displayId == -1)) {
577         msg = "The deviceId or displayId is invalid";
578         MMI_HILOGE("%s", msg.c_str());
579         return RET_ERR;
580     }
581     if (infos_ == nullptr) {
582         msg = "Infos_ is nullptr";
583         MMI_HILOGE("%s", msg.c_str());
584         return RET_ERR;
585     }
586 
587     BindInfo bindByDevice;
588     BindInfo bindByDisplay;
589     for (const auto &item : infos_->GetInfos()) {
590         if (item.GetInputDeviceId() == deviceId) {
591             bindByDevice = item;
592         }
593         if (item.GetDisplayId() == displayId) {
594             bindByDisplay = item;
595         }
596     }
597     if (bindByDevice.GetInputDeviceId() == -1) {
598         msg = "The deviceId is invalid";
599         MMI_HILOGE("%s", msg.c_str());
600         return RET_ERR;
601     }
602     if (bindByDisplay.GetDisplayId() == -1) {
603         msg = "The displayId is invalid";
604         MMI_HILOGE("%s", msg.c_str());
605         return RET_ERR;
606     }
607 
608     if (infos_->GetBindDisplayIdByInputDevice(deviceId) == displayId) {
609         msg = "The input device and display has alread bind";
610         MMI_HILOGE("%s", msg.c_str());
611         return RET_ERR;
612     }
613 
614     infos_->UnbindInputDevice(bindByDevice.GetInputDeviceId());
615     infos_->UnbindInputDevice(bindByDisplay.GetInputDeviceId());
616     infos_->UnbindDisplay(bindByDevice.GetDisplayId());
617     infos_->UnbindDisplay(bindByDisplay.GetDisplayId());
618 
619     BindInfo info1;
620     info1.AddInputDevice(bindByDevice.GetInputDeviceId(), bindByDevice.GetInputDeviceName());
621     info1.AddDisplay(bindByDisplay.GetDisplayId(), bindByDisplay.GetDisplayName());
622     infos_->Add(info1);
623 
624     if ((bindByDevice.GetDisplayId() != -1) && (bindByDisplay.GetInputDeviceId() != -1)) {
625         MMI_HILOGD("Both display id and input device id are invalid");
626         BindInfo info2;
627         info2.AddInputDevice(bindByDisplay.GetInputDeviceId(), bindByDisplay.GetInputDeviceName());
628         info2.AddDisplay(bindByDevice.GetDisplayId(), bindByDevice.GetDisplayName());
629         infos_->Add(info2);
630         return RET_OK;
631     }
632 
633     if (bindByDevice.GetDisplayId() != -1) {
634         MMI_HILOGD("The display id is invalid");
635         AddDisplay(bindByDevice.GetDisplayId(), bindByDevice.GetDisplayName());
636         return RET_OK;
637     }
638 
639     if (bindByDisplay.GetInputDeviceId() != -1) {
640         MMI_HILOGD("The input device id is invalid");
641         AddInputDevice(bindByDisplay.GetInputDeviceId(), bindByDisplay.GetInputDeviceName());
642         return RET_OK;
643     }
644 
645     msg = "Can not reach here";
646     return RET_ERR;
647 }
648 
Load()649 void InputDisplayBindHelper::Load()
650 {
651     CALL_DEBUG_ENTER;
652     char realPath[PATH_MAX] = {};
653     CHKPV(realpath(fileName_.c_str(), realPath));
654     if (!IsValidJsonPath(realPath)) {
655         MMI_HILOGE("The file path is invalid");
656         return;
657     }
658     std::ifstream ifs(realPath);
659     MMI_HILOGEK("Open file end:%{public}s", realPath);
660     if (!ifs) {
661         MMI_HILOGE("Open file fail.%{public}s, errno:%{public}d", realPath, errno);
662         return;
663     }
664     ifs >> *configFileInfos_;
665     ifs.close();
666 }
667 
Dumps() const668 std::string InputDisplayBindHelper::Dumps() const
669 {
670     CALL_DEBUG_ENTER;
671     CHKPO(infos_);
672     std::ostringstream oss;
673     oss << *infos_;
674     return oss.str();
675 }
676 } // namespace MMI
677 } // namespace OHOS
678