| // 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 "feedback/feedback_service.h" |
| |
| #include "base/logging.h" |
| #include "chromeos/dbus/service_constants.h" |
| #include "components/feedback/feedback_uploader.h" |
| #include "components/feedback/proto/extension.pb.h" |
| #include "dbus/bus.h" |
| #include "dbus/exported_object.h" |
| #include "dbus/message.h" |
| #include "dbus/object_proxy.h" |
| |
| namespace feedback { |
| |
| FeedbackService::FeedbackService(feedback::FeedbackUploader* uploader) |
| : uploader_(uploader) {} |
| |
| FeedbackService::~FeedbackService() {} |
| |
| void FeedbackService::SendFeedback( |
| const userfeedback::ExtensionSubmit& report, |
| const base::Callback<void(bool, const std::string&)>& callback) { |
| std::string data; |
| report.SerializeToString(&data); |
| uploader_->QueueReport(data); |
| |
| // Currently, we don't implement status reporting; if QueueReport |
| // returns then the report is at least queued. |
| callback.Run(true, std::string()); |
| } |
| |
| void FeedbackService::QueueExistingReport(const std::string& data) { |
| uploader_->QueueReport(data); |
| } |
| |
| DBusFeedbackServiceImpl::DBusFeedbackServiceImpl( |
| feedback::FeedbackUploader* uploader) : FeedbackService(uploader) {} |
| |
| DBusFeedbackServiceImpl::~DBusFeedbackServiceImpl() {} |
| |
| bool DBusFeedbackServiceImpl::Start(dbus::Bus* bus) { |
| if (!bus || !bus->Connect()) { |
| LOG(ERROR) << "Failed to connect to DBus"; |
| return false; |
| } |
| |
| dbus::ObjectPath path(feedback::kFeedbackServicePath); |
| dbus::ExportedObject* object = bus->GetExportedObject(path); |
| if (!object) { |
| LOG(ERROR) << "Failed to get exported object at " << path.value(); |
| return false; |
| } |
| |
| if (!object->ExportMethodAndBlock( |
| feedback::kFeedbackServiceName, |
| feedback::kSendFeedback, |
| base::Bind(&DBusFeedbackServiceImpl::DBusSendFeedback, |
| this))) { |
| bus->UnregisterExportedObject(path); |
| LOG(ERROR) << "Failed to export method " << feedback::kSendFeedback; |
| return false; |
| } |
| if (!bus->RequestOwnershipAndBlock(feedback::kFeedbackServiceName, |
| dbus::Bus::REQUIRE_PRIMARY)) { |
| bus->UnregisterExportedObject(path); |
| LOG(ERROR) << "Failed to get ownership of " |
| << feedback::kFeedbackServiceName; |
| return false; |
| } |
| return true; |
| } |
| |
| void DBusFeedbackServiceImpl::DBusSendFeedback( |
| dbus::MethodCall* method_call, |
| dbus::ExportedObject::ResponseSender sender) { |
| dbus::MessageReader reader(method_call); |
| userfeedback::ExtensionSubmit in; |
| if (!reader.PopArrayOfBytesAsProto(&in)) { |
| LOG(ERROR) << "Got feedback request with bad param"; |
| DBusFeedbackSent(method_call, sender, false, |
| "Can't deserialize proto of type userfeedback::ExtensionSubmit"); |
| } else { |
| LOG(INFO) << "Sending feedback"; |
| SendFeedback(in, base::Bind(&DBusFeedbackServiceImpl::DBusFeedbackSent, |
| this, method_call, sender)); |
| } |
| } |
| |
| void DBusFeedbackServiceImpl::DBusFeedbackSent( |
| dbus::MethodCall* method_call, |
| dbus::ExportedObject::ResponseSender sender, |
| bool status, const std::string& reason) { |
| scoped_ptr<dbus::Response> response = |
| dbus::Response::FromMethodCall(method_call); |
| dbus::MessageWriter writer(response.get()); |
| writer.AppendBool(status); |
| writer.AppendString(reason); |
| sender.Run(response.Pass()); |
| } |
| |
| } // namespace feedback |