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.
5 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/extensions/api/feedback_private/feedback_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "components/feedback/tracing_manager.h"
18 #include "extensions/browser/event_router.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/webui/web_ui_util.h"
21 #include "url/url_util.h"
23 using feedback::FeedbackData
;
27 // Getting the filename of a blob prepends a "C:\fakepath" to the filename.
28 // This is undesirable, strip it if it exists.
29 std::string
StripFakepath(const std::string
& path
) {
30 const char kFakePathStr
[] = "C:\\fakepath\\";
31 if (StartsWithASCII(path
, kFakePathStr
, false))
32 return path
.substr(arraysize(kFakePathStr
) - 1);
38 namespace extensions
{
40 namespace feedback_private
= api::feedback_private
;
42 using feedback_private::SystemInformation
;
43 using feedback_private::FeedbackInfo
;
45 char kFeedbackExtensionId
[] = "gfdkimpbcpahaombhbimeihdjnejgicl";
47 static base::LazyInstance
<BrowserContextKeyedAPIFactory
<FeedbackPrivateAPI
> >
48 g_factory
= LAZY_INSTANCE_INITIALIZER
;
51 BrowserContextKeyedAPIFactory
<FeedbackPrivateAPI
>*
52 FeedbackPrivateAPI::GetFactoryInstance() {
53 return g_factory
.Pointer();
56 FeedbackPrivateAPI::FeedbackPrivateAPI(content::BrowserContext
* context
)
57 : browser_context_(context
), service_(FeedbackService::CreateInstance()) {}
59 FeedbackPrivateAPI::~FeedbackPrivateAPI() {
64 FeedbackService
* FeedbackPrivateAPI::GetService() const {
68 void FeedbackPrivateAPI::RequestFeedback(
69 const std::string
& description_template
,
70 const std::string
& category_tag
,
71 const GURL
& page_url
) {
72 if (browser_context_
&& EventRouter::Get(browser_context_
)) {
74 info
.description
= description_template
;
75 info
.category_tag
= make_scoped_ptr(new std::string(category_tag
));
76 info
.page_url
= make_scoped_ptr(new std::string(page_url
.spec()));
77 info
.system_information
.reset(new SystemInformationList
);
78 // The manager is only available if tracing is enabled.
79 if (TracingManager
* manager
= TracingManager::Get()) {
80 info
.trace_id
.reset(new int(manager
->RequestTrace()));
83 scoped_ptr
<base::ListValue
> args(new base::ListValue());
84 args
->Append(info
.ToValue().release());
86 scoped_ptr
<Event
> event(new Event(
87 feedback_private::OnFeedbackRequested::kEventName
, args
.Pass()));
88 event
->restrict_to_browser_context
= browser_context_
;
90 EventRouter::Get(browser_context_
)
91 ->DispatchEventToExtension(kFeedbackExtensionId
, event
.Pass());
96 base::Closure
* FeedbackPrivateGetStringsFunction::test_callback_
= NULL
;
98 bool FeedbackPrivateGetStringsFunction::RunSync() {
99 base::DictionaryValue
* dict
= new base::DictionaryValue();
102 #define SET_STRING(id, idr) \
103 dict->SetString(id, l10n_util::GetStringUTF16(idr))
104 SET_STRING("page-title", IDS_FEEDBACK_REPORT_PAGE_TITLE
);
105 SET_STRING("page-url", IDS_FEEDBACK_REPORT_URL_LABEL
);
106 SET_STRING("screenshot", IDS_FEEDBACK_SCREENSHOT_LABEL
);
107 SET_STRING("user-email", IDS_FEEDBACK_USER_EMAIL_LABEL
);
108 #if defined(OS_CHROMEOS)
109 SET_STRING("sys-info",
110 IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_AND_METRICS_CHKBOX
);
112 SET_STRING("sys-info", IDS_FEEDBACK_INCLUDE_SYSTEM_INFORMATION_CHKBOX
);
114 SET_STRING("attach-file-label", IDS_FEEDBACK_ATTACH_FILE_LABEL
);
115 SET_STRING("attach-file-note", IDS_FEEDBACK_ATTACH_FILE_NOTE
);
116 SET_STRING("attach-file-to-big", IDS_FEEDBACK_ATTACH_FILE_TO_BIG
);
117 SET_STRING("reading-file", IDS_FEEDBACK_READING_FILE
);
118 SET_STRING("send-report", IDS_FEEDBACK_SEND_REPORT
);
119 SET_STRING("cancel", IDS_CANCEL
);
120 SET_STRING("no-description", IDS_FEEDBACK_NO_DESCRIPTION
);
121 SET_STRING("privacy-note", IDS_FEEDBACK_PRIVACY_NOTE
);
122 SET_STRING("performance-trace",
123 IDS_FEEDBACK_INCLUDE_PERFORMANCE_TRACE_CHECKBOX
);
126 const std::string
& app_locale
= g_browser_process
->GetApplicationLocale();
127 webui::SetLoadTimeDataDefaults(app_locale
, dict
);
129 if (test_callback_
&& !test_callback_
->is_null())
130 test_callback_
->Run();
135 bool FeedbackPrivateGetUserEmailFunction::RunSync() {
136 FeedbackService
* service
=
137 FeedbackPrivateAPI::GetFactoryInstance()->Get(GetProfile())->GetService();
139 SetResult(new base::StringValue(service
->GetUserEmail()));
143 bool FeedbackPrivateGetSystemInformationFunction::RunAsync() {
144 FeedbackService
* service
=
145 FeedbackPrivateAPI::GetFactoryInstance()->Get(GetProfile())->GetService();
147 service
->GetSystemInformation(
149 &FeedbackPrivateGetSystemInformationFunction::OnCompleted
, this));
153 void FeedbackPrivateGetSystemInformationFunction::OnCompleted(
154 const SystemInformationList
& sys_info
) {
155 results_
= feedback_private::GetSystemInformation::Results::Create(
160 bool FeedbackPrivateSendFeedbackFunction::RunAsync() {
161 scoped_ptr
<feedback_private::SendFeedback::Params
> params(
162 feedback_private::SendFeedback::Params::Create(*args_
));
163 EXTENSION_FUNCTION_VALIDATE(params
.get());
165 const FeedbackInfo
&feedback_info
= params
->feedback
;
167 std::string attached_file_uuid
;
168 if (feedback_info
.attached_file_blob_uuid
.get() &&
169 !feedback_info
.attached_file_blob_uuid
->empty())
170 attached_file_uuid
= *feedback_info
.attached_file_blob_uuid
;
172 std::string screenshot_uuid
;
173 if (feedback_info
.screenshot_blob_uuid
.get() &&
174 !feedback_info
.screenshot_blob_uuid
->empty())
175 screenshot_uuid
= *feedback_info
.screenshot_blob_uuid
;
177 // Populate feedback data.
178 scoped_refptr
<FeedbackData
> feedback_data(new FeedbackData());
179 feedback_data
->set_context(GetProfile());
180 feedback_data
->set_description(feedback_info
.description
);
182 if (feedback_info
.category_tag
.get())
183 feedback_data
->set_category_tag(*feedback_info
.category_tag
.get());
184 if (feedback_info
.page_url
.get())
185 feedback_data
->set_page_url(*feedback_info
.page_url
.get());
186 if (feedback_info
.email
.get())
187 feedback_data
->set_user_email(*feedback_info
.email
.get());
189 if (!attached_file_uuid
.empty()) {
190 feedback_data
->set_attached_filename(
191 StripFakepath((*feedback_info
.attached_file
.get()).name
));
192 feedback_data
->set_attached_file_uuid(attached_file_uuid
);
195 if (!screenshot_uuid
.empty())
196 feedback_data
->set_screenshot_uuid(screenshot_uuid
);
198 if (feedback_info
.trace_id
.get()) {
199 feedback_data
->set_trace_id(*feedback_info
.trace_id
.get());
202 scoped_ptr
<FeedbackData::SystemLogsMap
> sys_logs(
203 new FeedbackData::SystemLogsMap
);
204 SystemInformationList
* sys_info
= feedback_info
.system_information
.get();
206 for (SystemInformationList::iterator it
= sys_info
->begin();
207 it
!= sys_info
->end(); ++it
)
208 (*sys_logs
.get())[it
->get()->key
] = it
->get()->value
;
210 feedback_data
->SetAndCompressSystemInfo(sys_logs
.Pass());
212 FeedbackService
* service
=
213 FeedbackPrivateAPI::GetFactoryInstance()->Get(GetProfile())->GetService();
216 if (feedback_info
.send_histograms
) {
217 scoped_ptr
<std::string
> histograms(new std::string
);
218 service
->GetHistograms(histograms
.get());
219 if (!histograms
->empty())
220 feedback_data
->SetAndCompressHistograms(histograms
.Pass());
223 service
->SendFeedback(
226 base::Bind(&FeedbackPrivateSendFeedbackFunction::OnCompleted
, this));
231 void FeedbackPrivateSendFeedbackFunction::OnCompleted(
233 results_
= feedback_private::SendFeedback::Results::Create(
234 success
? feedback_private::STATUS_SUCCESS
:
235 feedback_private::STATUS_DELAYED
);
239 } // namespace extensions