1 /*
2  * Copyright (C) 2019 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 "HardwareBase.h"
18 
19 #include <cutils/properties.h>
20 #include <log/log.h>
21 
22 #include <fstream>
23 #include <sstream>
24 
25 #include "utils.h"
26 
27 namespace aidl {
28 namespace android {
29 namespace hardware {
30 namespace vibrator {
31 
HwApiBase()32 HwApiBase::HwApiBase() {
33     mPathPrefix = std::getenv("HWAPI_PATH_PREFIX") ?: "";
34     if (mPathPrefix.empty()) {
35         ALOGE("Failed get HWAPI path prefix!");
36     }
37 }
38 
saveName(const std::string & name,const std::ios * stream)39 void HwApiBase::saveName(const std::string &name, const std::ios *stream) {
40     mNames[stream] = name;
41 }
42 
debug(int fd)43 void HwApiBase::debug(int fd) {
44     dprintf(fd, "Kernel:\n");
45 
46     for (auto &entry : utils::pathsFromEnv("HWAPI_DEBUG_PATHS", mPathPrefix)) {
47         auto &path = entry.first;
48         auto &stream = entry.second;
49         std::string line;
50 
51         dprintf(fd, "  %s:\n", path.c_str());
52         while (std::getline(stream, line)) {
53             dprintf(fd, "    %s\n", line.c_str());
54         }
55     }
56 
57     mRecordsMutex.lock();
58     dprintf(fd, "  Records:\n");
59     for (auto &r : mRecords) {
60         if (r == nullptr) {
61             continue;
62         }
63         dprintf(fd, "    %s\n", r->toString(mNames).c_str());
64     }
65     mRecordsMutex.unlock();
66 }
67 
HwCalBase()68 HwCalBase::HwCalBase() {
69     std::ifstream calfile;
70     std::ifstream calfile_dual;
71     auto propertyPrefix = std::getenv("PROPERTY_PREFIX");
72     auto calPath = std::getenv("CALIBRATION_FILEPATH");
73 
74     if (propertyPrefix != NULL) {
75         mPropertyPrefix = std::string(propertyPrefix);
76     } else {
77         ALOGE("Failed get property prefix!");
78     }
79 
80     // Keep the cal file path for the current HwCalBase instance.
81     if (calPath != NULL) {
82         mCalPath = std::string(calPath);
83     } else {
84         ALOGE("Failed get the calibration file path!");
85     }
86 
87     // Read the cal data for the current instance.
88     utils::fileFromEnv("CALIBRATION_FILEPATH", &calfile);
89 
90     for (std::string line; std::getline(calfile, line);) {
91         if (line.empty() || line[0] == '#') {
92             continue;
93         }
94         std::istringstream is_line(line);
95         std::string key, value;
96         if (std::getline(is_line, key, ':') && std::getline(is_line, value)) {
97             mCalData[utils::trim(key)] = utils::trim(value);
98         }
99     }
100 
101     // Read the cal data for the other instance.
102     utils::fileFromEnv("CALIBRATION_FILEPATH_DUAL", &calfile_dual);
103 
104     for (std::string line; std::getline(calfile_dual, line);) {
105         if (line.empty() || line[0] == '#') {
106             continue;
107         }
108         std::istringstream is_line(line);
109         std::string key, value;
110         if (std::getline(is_line, key, ':') && std::getline(is_line, value)) {
111             key = utils::trim(key) + "_dual";
112             mCalData[key] = utils::trim(value);
113         }
114     }
115 }
116 
debug(int fd)117 void HwCalBase::debug(int fd) {
118     std::ifstream stream;
119     std::string line;
120     struct context {
121         HwCalBase *obj;
122         int fd;
123     } context{this, fd};
124 
125     dprintf(fd, "Properties:\n");
126 
127     property_list(
128             [](const char *key, const char *value, void *cookie) {
129                 struct context *context = static_cast<struct context *>(cookie);
130                 HwCalBase *obj = context->obj;
131                 int fd = context->fd;
132                 const std::string expect{obj->mPropertyPrefix};
133                 const std::string actual{key, std::min(strlen(key), expect.size())};
134                 if (actual == expect) {
135                     dprintf(fd, "  %s:\n", key);
136                     dprintf(fd, "    %s\n", value);
137                 }
138             },
139             &context);
140 
141     dprintf(fd, "\n");
142 
143     dprintf(fd, "Persist:\n");
144 
145     utils::openNoCreate(mCalPath, &stream);
146     dprintf(fd, "  %s:\n", mCalPath.c_str());
147     while (std::getline(stream, line)) {
148         dprintf(fd, "    %s\n", line.c_str());
149     }
150 }
151 
152 }  // namespace vibrator
153 }  // namespace hardware
154 }  // namespace android
155 }  // namespace aidl
156