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 #include "FileNode.h"
18
19 #include <log/log.h>
20 #include <sstream>
21
22 namespace android {
23
24 ANDROID_SINGLETON_STATIC_INSTANCE(hardware::graphics::composer::FileNodeManager);
25
26 namespace hardware::graphics::composer {
27
FileNode(const std::string & nodePath)28 FileNode::FileNode(const std::string& nodePath) : mNodePath(nodePath) {}
29
~FileNode()30 FileNode::~FileNode() {
31 for (auto& fd : mFds) {
32 close(fd.second);
33 }
34 }
35
dump()36 std::string FileNode::dump() {
37 std::ostringstream os;
38 os << "FileNode: root path: " << mNodePath << std::endl;
39 for (const auto& item : mFds) {
40 auto lastWrittenValue = getLastWrittenValue(item.first);
41 os << "FileNode: sysfs node = " << item.first << ", last written value = 0x" << std::setw(8)
42 << std::setfill('0') << std::hex << lastWrittenValue << std::endl;
43 }
44 return os.str();
45 }
46
getLastWrittenValue(const std::string & nodeName)47 uint32_t FileNode::getLastWrittenValue(const std::string& nodeName) {
48 int fd = getFileHandler(nodeName);
49 if ((fd < 0) || (mLastWrittenValue.count(fd) <= 0)) return 0;
50 return mLastWrittenValue[fd];
51 }
52
readString(const std::string & nodeName)53 std::optional<std::string> FileNode::readString(const std::string& nodeName) {
54 std::string fullPath = mNodePath + nodeName;
55 std::ifstream ifs(fullPath);
56 if (ifs) {
57 std::ostringstream os;
58 os << ifs.rdbuf(); // reading data
59 return os.str();
60 }
61 return std::nullopt;
62 }
63
WriteUint32(const std::string & nodeName,uint32_t value)64 bool FileNode::WriteUint32(const std::string& nodeName, uint32_t value) {
65 int fd = getFileHandler(nodeName);
66 if (fd >= 0) {
67 std::string cmdString = std::to_string(value);
68 int ret = write(fd, cmdString.c_str(), std::strlen(cmdString.c_str()));
69 if (ret < 0) {
70 ALOGE("Write 0x%x to file node %s%s failed, ret = %d errno = %d", value,
71 mNodePath.c_str(), nodeName.c_str(), ret, errno);
72 return false;
73 }
74 } else {
75 ALOGE("Write to invalid file node %s%s", mNodePath.c_str(), nodeName.c_str());
76 return false;
77 }
78 mLastWrittenValue[fd] = value;
79 return true;
80 }
81
getFileHandler(const std::string & nodeName)82 int FileNode::getFileHandler(const std::string& nodeName) {
83 if (mFds.count(nodeName) > 0) {
84 return mFds[nodeName];
85 }
86 std::string fullPath = mNodePath + nodeName;
87 int fd = open(fullPath.c_str(), O_WRONLY, 0);
88 if (fd < 0) {
89 ALOGE("Open file node %s failed, fd = %d", fullPath.c_str(), fd);
90 return fd;
91 }
92 mFds[nodeName] = fd;
93 return fd;
94 }
95
96 }; // namespace hardware::graphics::composer
97 }; // namespace android
98