1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18 #include "FileNode.h"
19 #include <log/log.h>
20 #include <utils/Trace.h>
21 #include <sstream>
22
23 namespace android {
24
25 ANDROID_SINGLETON_STATIC_INSTANCE(hardware::graphics::composer::FileNodeManager);
26
27 namespace hardware::graphics::composer {
28
FileNode(const std::string & nodePath)29 FileNode::FileNode(const std::string& nodePath) : mNodePath(nodePath) {}
30
~FileNode()31 FileNode::~FileNode() {
32 for (auto& fd : mFds) {
33 close(fd.second);
34 }
35 }
36
dump()37 std::string FileNode::dump() {
38 std::ostringstream os;
39 os << "FileNode: root path: " << mNodePath << std::endl;
40 for (const auto& item : mFds) {
41 auto lastWrittenString = getLastWrittenString(item.first);
42 if (lastWrittenString)
43 os << "FileNode: sysfs node = " << item.first
44 << ", last written value = " << *lastWrittenString << std::endl;
45 }
46 return os.str();
47 }
48
getLastWrittenString(const std::string & nodeName)49 std::optional<std::string> FileNode::getLastWrittenString(const std::string& nodeName) {
50 int fd = getFileHandler(nodeName);
51 if ((fd < 0) || (mLastWrittenString.count(fd) <= 0)) return std::nullopt;
52 return mLastWrittenString[fd];
53 }
54
readString(const std::string & nodeName)55 std::optional<std::string> FileNode::readString(const std::string& nodeName) {
56 std::string fullPath = mNodePath + nodeName;
57 std::ifstream ifs(fullPath);
58 if (ifs) {
59 std::ostringstream os;
60 os << ifs.rdbuf(); // reading data
61 return os.str();
62 }
63 return std::nullopt;
64 }
65
getFileHandler(const std::string & nodeName)66 int FileNode::getFileHandler(const std::string& nodeName) {
67 if (mFds.count(nodeName) > 0) {
68 return mFds[nodeName];
69 }
70 std::string fullPath = mNodePath + nodeName;
71 int fd = open(fullPath.c_str(), O_WRONLY, 0);
72 if (fd < 0) {
73 ALOGE("Open file node %s failed, fd = %d", fullPath.c_str(), fd);
74 return fd;
75 }
76 mFds[nodeName] = fd;
77 return fd;
78 }
79
writeString(const std::string & nodeName,const std::string & str)80 bool FileNode::writeString(const std::string& nodeName, const std::string& str) {
81 int fd = getFileHandler(nodeName);
82 if (fd < 0) {
83 ALOGE("Write to invalid file node %s%s", mNodePath.c_str(), nodeName.c_str());
84 return false;
85 }
86 int ret = write(fd, str.c_str(), str.size());
87 if (ret < 0) {
88 ALOGE("Write %s to file node %s%s failed, ret = %d errno = %d", str.c_str(),
89 mNodePath.c_str(), nodeName.c_str(), ret, errno);
90 return false;
91 }
92 std::ostringstream oss;
93 oss << "Write " << str << " to file node " << mNodePath.c_str() << nodeName.c_str();
94 ATRACE_NAME(oss.str().c_str());
95 mLastWrittenString[fd] = str;
96 return true;
97 }
98 }; // namespace hardware::graphics::composer
99 }; // namespace android
100