feedback_private_api.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
6
7#include "base/lazy_instance.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/strings/utf_string_conversions.h"
10#include "base/values.h"
11#include "chrome/browser/extensions/api/feedback_private/feedback_service.h"
12#include "chrome/browser/extensions/event_names.h"
13#include "chrome/browser/extensions/event_router.h"
14#include "chrome/browser/extensions/extension_system.h"
15#include "grit/generated_resources.h"
16#include "ui/base/l10n/l10n_util.h"
17#include "ui/webui/web_ui_util.h"
18#include "url/url_util.h"
19
20
21namespace extensions {
22
23using api::feedback_private::SystemInformation;
24using api::feedback_private::FeedbackInfo;
25
26static base::LazyInstance<ProfileKeyedAPIFactory<FeedbackPrivateAPI> >
27    g_factory = LAZY_INSTANCE_INITIALIZER;
28
29// static
30ProfileKeyedAPIFactory<FeedbackPrivateAPI>*
31    FeedbackPrivateAPI::GetFactoryInstance() {
32  return &g_factory.Get();
33}
34
35FeedbackPrivateAPI::FeedbackPrivateAPI(Profile* profile)
36    : profile_(profile),
37      service_(FeedbackService::CreateInstance()) {
38}
39
40FeedbackPrivateAPI::~FeedbackPrivateAPI() {
41  delete service_;
42  service_ = NULL;
43}
44
45FeedbackService* FeedbackPrivateAPI::GetService() const {
46  return service_;
47}
48
49void FeedbackPrivateAPI::RequestFeedback(
50    const std::string& description_template,
51    const std::string& category_tag,
52    const GURL& page_url) {
53  if (profile_ && ExtensionSystem::Get(profile_)->event_router()) {
54    FeedbackInfo info;
55    info.description = description_template;
56    info.category_tag = make_scoped_ptr(new std::string(category_tag));
57    info.page_url = make_scoped_ptr(new std::string(page_url.spec()));
58
59    scoped_ptr<base::ListValue> args(new base::ListValue());
60    args->Append(info.ToValue().release());
61
62    scoped_ptr<Event> event(
63        new Event(event_names::kOnFeedbackRequested, args.Pass()));
64    ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(
65        event.Pass());
66  }
67}
68
69bool FeedbackPrivateGetUserEmailFunction::RunImpl() {
70  FeedbackService* service =
71      FeedbackPrivateAPI::GetFactoryInstance()->GetForProfile(
72          profile())->GetService();
73  DCHECK(service);
74  SetResult(base::Value::CreateStringValue(service->GetUserEmail()));
75  return true;
76}
77
78bool FeedbackPrivateGetSystemInformationFunction::RunImpl() {
79  FeedbackService* service =
80      FeedbackPrivateAPI::GetFactoryInstance()->GetForProfile(
81          profile())->GetService();
82  DCHECK(service);
83  service->GetSystemInformation(
84      base::Bind(
85          &FeedbackPrivateGetSystemInformationFunction::OnCompleted, this));
86  return true;
87}
88
89void FeedbackPrivateGetSystemInformationFunction::OnCompleted(
90    const SystemInformationList& sys_info) {
91  results_ = api::feedback_private::GetSystemInformation::Results::Create(
92      sys_info);
93  SendResponse(true);
94}
95
96bool FeedbackPrivateSendFeedbackFunction::RunImpl() {
97  scoped_ptr<api::feedback_private::SendFeedback::Params> params(
98      api::feedback_private::SendFeedback::Params::Create(*args_));
99  EXTENSION_FUNCTION_VALIDATE(params.get());
100
101  const FeedbackInfo &feedback_info = params->feedback;
102
103  std::string description = feedback_info.description;
104  std::string attached_file_url, screenshot_url;
105  if (feedback_info.attached_file.get() &&
106      feedback_info.attached_file_blob_url.get() &&
107      !feedback_info.attached_file_blob_url->empty()) {
108    attached_file_url = *feedback_info.attached_file_blob_url;
109  }
110
111  if (feedback_info.screenshot.get() &&
112      feedback_info.screenshot_blob_url.get() &&
113      !feedback_info.screenshot_blob_url->empty()) {
114    screenshot_url = *feedback_info.screenshot_blob_url;
115  }
116
117  // Populate feedback data.
118  scoped_refptr<FeedbackData> feedback_data(new FeedbackData());
119  feedback_data->set_profile(profile_);
120  feedback_data->set_description(feedback_info.description);
121
122  if (feedback_info.category_tag.get())
123    feedback_data->set_category_tag(*feedback_info.category_tag.get());
124  if (feedback_info.page_url.get())
125    feedback_data->set_page_url(*feedback_info.page_url.get());
126  if (feedback_info.email.get())
127    feedback_data->set_user_email(*feedback_info.email.get());
128
129  if (!attached_file_url.empty()) {
130    feedback_data->set_attached_filename(
131        (*feedback_info.attached_file.get()).name);
132    feedback_data->set_attached_file_url(GURL(attached_file_url));
133  }
134
135  if (!screenshot_url.empty())
136    feedback_data->set_screenshot_url(GURL(screenshot_url));
137
138  // TODO(rkc): Take this out of OS_CHROMEOS once we have FeedbackData and
139  // FeedbackUtil migrated to handle system logs for both Chrome and ChromeOS.
140#if defined(OS_CHROMEOS)
141  scoped_ptr<chromeos::SystemLogsResponse> sys_logs(
142      new chromeos::SystemLogsResponse);
143  SystemInformationList* sys_info = feedback_info.system_information.get();
144  if (sys_info) {
145    for (SystemInformationList::iterator it = sys_info->begin();
146         it != sys_info->end(); ++it)
147      (*sys_logs.get())[it->get()->key] = it->get()->value;
148  }
149  feedback_data->set_sys_info(sys_logs.Pass());
150#endif
151
152  FeedbackService* service = FeedbackPrivateAPI::GetFactoryInstance()->
153      GetForProfile(profile())->GetService();
154  DCHECK(service);
155  service->SendFeedback(profile(),
156      feedback_data, base::Bind(
157          &FeedbackPrivateSendFeedbackFunction::OnCompleted,
158          this));
159  return true;
160}
161
162void FeedbackPrivateSendFeedbackFunction::OnCompleted(
163    bool success) {
164  results_ = api::feedback_private::SendFeedback::Results::Create(
165      success ? api::feedback_private::STATUS_SUCCESS :
166                api::feedback_private::STATUS_DELAYED);
167  SendResponse(true);
168}
169
170}  // namespace extensions
171