133 lines
4.2 KiB
C++
133 lines
4.2 KiB
C++
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "calibrationfile.h"
|
|
|
|
#include "file.h"
|
|
#include "log.h"
|
|
|
|
namespace android {
|
|
|
|
constexpr char kCalibrationFile[] = "/persist/sensorcal.json";
|
|
|
|
std::shared_ptr<CalibrationFile> CalibrationFile::instance_;
|
|
|
|
std::shared_ptr<CalibrationFile> CalibrationFile::Instance() {
|
|
if (!CalibrationFile::instance_) {
|
|
auto inst = std::shared_ptr<CalibrationFile>(new CalibrationFile());
|
|
if (inst->Initialize()) {
|
|
CalibrationFile::instance_ = inst;
|
|
}
|
|
}
|
|
|
|
return CalibrationFile::instance_;
|
|
}
|
|
|
|
bool CalibrationFile::Initialize() {
|
|
file_ = std::unique_ptr<File>(new File(kCalibrationFile, "rw"));
|
|
|
|
status_t err = file_->initCheck();
|
|
if (err != OK) {
|
|
LOGE("Couldn't open calibration file: %d (%s)", err, strerror(-err));
|
|
return false;
|
|
}
|
|
|
|
off64_t file_size = file_->seekTo(0, SEEK_END);
|
|
if (file_size > 0) {
|
|
auto file_data = std::vector<char>(file_size);
|
|
file_->seekTo(0, SEEK_SET);
|
|
ssize_t bytes_read = file_->read(file_data.data(), file_size);
|
|
if (bytes_read != file_size) {
|
|
LOGE("Read of configuration file returned %zd, expected %" PRIu64,
|
|
bytes_read, file_size);
|
|
return false;
|
|
}
|
|
|
|
sp<JSONCompound> json = JSONCompound::Parse(file_data.data(), file_size);
|
|
if (json == nullptr || !json->isObject()) {
|
|
// If there's an existing file and we couldn't parse it, or it
|
|
// parsed to something unexpected, then we don't want to wipe out
|
|
// the file - the user needs to decide what to do, e.g. they can
|
|
// manually edit to fix corruption, or delete it, etc.
|
|
LOGE("Couldn't parse sensor calibration file (requires manual "
|
|
"resolution)");
|
|
return false;
|
|
} else {
|
|
json_root_ = reinterpret_cast<JSONObject*>(json.get());
|
|
LOGD("Parsed JSONObject from file:\n%s",
|
|
json_root_->toString().c_str());
|
|
}
|
|
}
|
|
|
|
// No errors, but there was no existing calibration data so construct a new
|
|
// object
|
|
if (json_root_ == nullptr) {
|
|
json_root_ = new JSONObject();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const sp<JSONObject> CalibrationFile::GetJSONObject() const {
|
|
return json_root_;
|
|
}
|
|
|
|
bool CalibrationFile::SetSingleAxis(const char *key, int32_t value) {
|
|
json_root_->setInt32(key, value);
|
|
return true;
|
|
}
|
|
|
|
bool CalibrationFile::SetSingleAxis(const char *key, float value) {
|
|
json_root_->setFloat(key, value);
|
|
return true;
|
|
}
|
|
|
|
bool CalibrationFile::SetTripleAxis(const char *key, int32_t x, int32_t y,
|
|
int32_t z) {
|
|
sp<JSONArray> json_array = new JSONArray();
|
|
json_array->addInt32(x);
|
|
json_array->addInt32(y);
|
|
json_array->addInt32(z);
|
|
json_root_->setArray(key, json_array);
|
|
return true;
|
|
}
|
|
|
|
bool CalibrationFile::SetFourAxis(const char *key, int32_t x, int32_t y,
|
|
int32_t z, int32_t w) {
|
|
sp<JSONArray> json_array = new JSONArray();
|
|
json_array->addInt32(x);
|
|
json_array->addInt32(y);
|
|
json_array->addInt32(z);
|
|
json_array->addInt32(w);
|
|
json_root_->setArray(key, json_array);
|
|
return true;
|
|
}
|
|
|
|
bool CalibrationFile::Save() {
|
|
AString json_str = json_root_->toString();
|
|
LOGD("Saving JSONObject to file (%zd bytes):\n%s", json_str.size(),
|
|
json_str.c_str());
|
|
file_->seekTo(0, SEEK_SET);
|
|
ssize_t bytes_written = file_->write(json_str.c_str(), json_str.size());
|
|
if (bytes_written < 0 || static_cast<size_t>(bytes_written) != json_str.size()) {
|
|
LOGE("Write returned %zd, expected %zu", bytes_written, json_str.size());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace android
|