blob: cc038557376c88acd8b4dd487e125ace4b37bc57 [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "settingsd/dbus_settings_service_impl.h"
#include <base/json/json_writer.h>
#include <base/logging.h>
#include "settingsd/settings_document_manager.h"
namespace settingsd {
namespace {
// The error domain reported for dbus errors.
const char kErrorDomain[] = "settingsd";
// Error code for failed document insertions.
const char kErrorInsertionFailed[] = "blob_insertion_failed";
// Error messages for failed document insertions.
const char kErrorMsgInsertionVersionClash[] = "Source version already used.";
const char kErrorMsgInsertionCollision[] = "Collision with other document.";
const char kErrorMsgInsertionParseError[] = "Failed to parse the blob.";
const char kErrorMsgInsertionValidationError[] = "Blob failed validation.";
const char kErrorMsgInsertionBadPayload[] = "Failed to decode blob payload.";
const char kErrorMsgInsertionUnknownSource[] = "Blob origin unknown.";
const char kErrorMsgInsertionStorageFailure[] =
"Failed to write the blob to BlobStore.";
const char kErrorMsgInsertionAccessViolation[] =
"Document touches off-bounds keys.";
// Error code when asking for a key that has no value assigned.
const char kErrorNoValue[] = "get_no_value";
// Error code when asking for a key that has no value assigned.
const char kErrorMsgNoValue[] = "%s has no assigned value.";
// Error code for invalid keys.
const char kErrorInvalidKey[] = "get_invalid_key";
// Error message for invalid keys.
const char kErrorMsgInvalidKey[] =
"%s is not a valid string representation of a key.";
const char* InsertionStatusToErrorMsg(
SettingsDocumentManager::InsertionStatus status) {
switch (status) {
case SettingsDocumentManager::kInsertionStatusSuccess:
LOG(FATAL) << "InsertionStatusToErrorMsg() called on success.";
return nullptr;
case SettingsDocumentManager::kInsertionStatusVersionClash:
return kErrorMsgInsertionVersionClash;
case SettingsDocumentManager::kInsertionStatusCollision:
return kErrorMsgInsertionCollision;
case SettingsDocumentManager::kInsertionStatusAccessViolation:
return kErrorMsgInsertionAccessViolation;
case SettingsDocumentManager::kInsertionStatusParseError:
return kErrorMsgInsertionParseError;
case SettingsDocumentManager::kInsertionStatusValidationError:
return kErrorMsgInsertionValidationError;
case SettingsDocumentManager::kInsertionStatusBadPayload:
return kErrorMsgInsertionBadPayload;
case SettingsDocumentManager::kInsertionStatusStorageFailure:
return kErrorMsgInsertionStorageFailure;
case SettingsDocumentManager::kInsertionStatusUnknownSource:
return kErrorMsgInsertionUnknownSource;
}
NOTREACHED() << "Update: Unhandled error mode.";
return nullptr;
}
} // namespace
DBusSettingsServiceImpl::DBusSettingsServiceImpl(
SettingsDocumentManager* settings_document_manager,
const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>&
object_manager,
const dbus::ObjectPath& object_path)
: settings_document_manager_(settings_document_manager),
dbus_object_(object_manager.get(),
object_manager->GetBus(),
object_path) {
settings_document_manager_->AddSettingsObserver(this);
}
DBusSettingsServiceImpl::~DBusSettingsServiceImpl() {
settings_document_manager_->RemoveSettingsObserver(this);
}
void DBusSettingsServiceImpl::OnSettingsChanged(const std::set<Key>& keys) {
std::vector<std::string> changed_keys;
changed_keys.reserve(keys.size());
for (const auto& key : keys)
changed_keys.push_back(key.ToString());
dbus_adaptor_.SendOnSettingsChangedSignal(changed_keys);
}
void DBusSettingsServiceImpl::Start(
chromeos::dbus_utils::AsyncEventSequencer* sequencer) {
dbus_adaptor_.RegisterWithDBusObject(&dbus_object_);
dbus_object_.RegisterAsync(sequencer->GetHandler(
"DBusSettingsServiceImpl.RegisterAsync() failed.", true));
}
bool DBusSettingsServiceImpl::Get(chromeos::ErrorPtr* error,
const std::string& in_key,
std::vector<uint8_t>* out_value) {
if (!Key::IsValidKey(in_key)) {
chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomain,
kErrorInvalidKey, kErrorMsgInvalidKey,
in_key.c_str());
return false;
}
BlobRef value = settings_document_manager_->GetValue(Key(in_key));
if (!value.valid()) {
chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomain, kErrorNoValue,
kErrorMsgNoValue, in_key.c_str());
return false;
}
*out_value = value.ToVector();
return true;
}
bool DBusSettingsServiceImpl::Enumerate(chromeos::ErrorPtr* error,
const std::string& in_prefix,
std::vector<std::string>* out_values) {
if (!Key::IsValidKey(in_prefix)) {
chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomain,
kErrorInvalidKey, kErrorMsgInvalidKey,
in_prefix.c_str());
return false;
}
const std::set<Key> keys =
settings_document_manager_->GetKeys(Key(in_prefix));
for (const auto& key : keys)
out_values->push_back(key.ToString());
return true;
}
bool DBusSettingsServiceImpl::Update(
chromeos::ErrorPtr* error,
const std::vector<uint8_t>& in_blob,
const std::string& in_source_id) {
SettingsDocumentManager::InsertionStatus insertion_status =
settings_document_manager_->InsertBlob(
in_source_id, BlobRef(&in_blob));
if (insertion_status != SettingsDocumentManager::kInsertionStatusSuccess) {
chromeos::Error::AddTo(error, FROM_HERE, kErrorDomain,
kErrorInsertionFailed,
InsertionStatusToErrorMsg(insertion_status));
return false;
}
return true;
}
} // namespace settingsd