|  | // Copyright 2014 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 "buffet/manager.h" | 
|  |  | 
|  | #include <map> | 
|  | #include <string> | 
|  |  | 
|  | #include <base/bind.h> | 
|  | #include <base/bind_helpers.h> | 
|  | #include <base/json/json_reader.h> | 
|  | #include <base/json/json_writer.h> | 
|  | #include <chromeos/dbus/async_event_sequencer.h> | 
|  | #include <chromeos/dbus/exported_object_manager.h> | 
|  | #include <chromeos/errors/error.h> | 
|  | #include <dbus/bus.h> | 
|  | #include <dbus/object_path.h> | 
|  | #include <dbus/values_util.h> | 
|  |  | 
|  | #include "buffet/commands/command_instance.h" | 
|  | #include "buffet/commands/command_manager.h" | 
|  | #include "buffet/libbuffet/dbus_constants.h" | 
|  | #include "buffet/states/state_manager.h" | 
|  |  | 
|  | using chromeos::dbus_utils::AsyncEventSequencer; | 
|  | using chromeos::dbus_utils::ExportedObjectManager; | 
|  |  | 
|  | namespace buffet { | 
|  |  | 
|  | Manager::Manager(const base::WeakPtr<ExportedObjectManager>& object_manager) | 
|  | : dbus_object_(object_manager.get(), | 
|  | object_manager->GetBus(), | 
|  | dbus::ObjectPath(dbus_constants::kManagerServicePath)) {} | 
|  |  | 
|  | void Manager::RegisterAsync(const AsyncEventSequencer::CompletionAction& cb) { | 
|  | chromeos::dbus_utils::DBusInterface* itf = | 
|  | dbus_object_.AddOrGetInterface(dbus_constants::kManagerInterface); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerStartDevice, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleStartDevice); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerCheckDeviceRegistered, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleCheckDeviceRegistered); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerGetDeviceInfo, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleGetDeviceInfo); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerRegisterDevice, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleRegisterDevice); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerUpdateStateMethod, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleUpdateState); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerAddCommand, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleAddCommand); | 
|  | itf->AddMethodHandler(dbus_constants::kManagerTestMethod, | 
|  | base::Unretained(this), | 
|  | &Manager::HandleTestMethod); | 
|  | dbus_object_.RegisterAsync(cb); | 
|  | command_manager_ = | 
|  | std::make_shared<CommandManager>(dbus_object_.GetObjectManager()); | 
|  | command_manager_->Startup(); | 
|  | state_manager_ = std::make_shared<StateManager>(); | 
|  | state_manager_->Startup(); | 
|  | device_info_ = std::unique_ptr<DeviceRegistrationInfo>( | 
|  | new DeviceRegistrationInfo(command_manager_, state_manager_)); | 
|  | device_info_->Load(); | 
|  | } | 
|  |  | 
|  | void Manager::HandleStartDevice(chromeos::ErrorPtr* error) { | 
|  | LOG(INFO) << "Received call to Manager.StartDevice()"; | 
|  |  | 
|  | device_info_->StartDevice(error); | 
|  | } | 
|  |  | 
|  | std::string Manager::HandleCheckDeviceRegistered(chromeos::ErrorPtr* error) { | 
|  | LOG(INFO) << "Received call to Manager.CheckDeviceRegistered()"; | 
|  | std::string device_id; | 
|  | bool registered = device_info_->CheckRegistration(error); | 
|  | // If it fails due to any reason other than 'device not registered', | 
|  | // treat it as a real error and report it to the caller. | 
|  | if (!registered && | 
|  | !(*error)->HasError(kErrorDomainGCD, "device_not_registered")) { | 
|  | return device_id; | 
|  | } | 
|  |  | 
|  | error->reset(); | 
|  |  | 
|  | if (registered) | 
|  | device_id = device_info_->GetDeviceId(error); | 
|  |  | 
|  | return device_id; | 
|  | } | 
|  |  | 
|  | std::string Manager::HandleGetDeviceInfo(chromeos::ErrorPtr* error) { | 
|  | LOG(INFO) << "Received call to Manager.GetDeviceInfo()"; | 
|  |  | 
|  | std::string device_info_str; | 
|  | auto device_info = device_info_->GetDeviceInfo(error); | 
|  | if (!device_info) | 
|  | return device_info_str; | 
|  |  | 
|  | base::JSONWriter::Write(device_info.get(), &device_info_str); | 
|  | return device_info_str; | 
|  | } | 
|  |  | 
|  | std::string Manager::HandleRegisterDevice( | 
|  | chromeos::ErrorPtr* error, | 
|  | const std::map<std::string, std::string>& params) { | 
|  | LOG(INFO) << "Received call to Manager.RegisterDevice()"; | 
|  |  | 
|  | return device_info_->RegisterDevice(params, error); | 
|  | } | 
|  |  | 
|  | void Manager::HandleUpdateState( | 
|  | chromeos::ErrorPtr* error, | 
|  | const chromeos::VariantDictionary& property_set) { | 
|  | state_manager_->UpdateProperties(property_set, error); | 
|  | } | 
|  |  | 
|  | void Manager::HandleAddCommand( | 
|  | chromeos::ErrorPtr* error, const std::string& json_command) { | 
|  | std::string error_message; | 
|  | std::unique_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( | 
|  | json_command, base::JSON_PARSE_RFC, nullptr, &error_message)); | 
|  | if (!value) { | 
|  | chromeos::Error::AddTo(error, chromeos::errors::json::kDomain, | 
|  | chromeos::errors::json::kParseError, error_message); | 
|  | return; | 
|  | } | 
|  | auto command_instance = buffet::CommandInstance::FromJson( | 
|  | value.get(), command_manager_->GetCommandDictionary(), error); | 
|  | if (command_instance) | 
|  | command_manager_->AddCommand(std::move(command_instance)); | 
|  | } | 
|  |  | 
|  | std::string Manager::HandleTestMethod(chromeos::ErrorPtr* error, | 
|  | const std::string& message) { | 
|  | LOG(INFO) << "Received call to test method: " << message; | 
|  | return message; | 
|  | } | 
|  |  | 
|  | }  // namespace buffet |