OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/feedback/feedback_util.h" | 5 #include "components/feedback/feedback_util.h" |
6 | 6 |
7 #include <sstream> | |
8 #include <string> | 7 #include <string> |
9 #include <vector> | |
10 | 8 |
11 #include "base/bind.h" | 9 #include "base/bind.h" |
12 #include "base/command_line.h" | |
13 #include "base/file_util.h" | 10 #include "base/file_util.h" |
14 #include "base/file_version_info.h" | |
15 #include "base/memory/singleton.h" | |
16 #include "base/message_loop/message_loop.h" | |
17 #include "base/strings/string_number_conversions.h" | |
18 #include "base/strings/stringprintf.h" | |
19 #include "base/strings/utf_string_conversions.h" | |
20 #include "base/win/windows_version.h" | |
21 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
22 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" | |
23 #include "chrome/browser/feedback/feedback_data.h" | |
24 #include "chrome/browser/feedback/feedback_uploader.h" | |
25 #include "chrome/browser/feedback/feedback_uploader_factory.h" | |
26 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" | |
27 #include "chrome/browser/profiles/profile.h" | |
28 #include "chrome/browser/profiles/profile_manager.h" | |
29 #include "chrome/browser/safe_browsing/safe_browsing_util.h" | |
30 #include "chrome/browser/ui/browser_finder.h" | |
31 #include "chrome/browser/ui/browser_list.h" | |
32 #include "chrome/browser/ui/browser_window.h" | |
33 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
34 #include "chrome/common/chrome_content_client.h" | 12 #include "chrome/common/chrome_content_client.h" |
35 #include "chrome/common/chrome_switches.h" | 13 #include "components/feedback/feedback_data.h" |
36 #include "chrome/common/chrome_version_info.h" | 14 #include "components/feedback/feedback_uploader.h" |
37 #include "chrome/common/metrics/metrics_log_manager.h" | 15 #include "components/feedback/feedback_uploader_factory.h" |
38 #include "content/public/browser/navigation_controller.h" | 16 #include "components/feedback/proto/common.pb.h" |
39 #include "content/public/browser/web_contents.h" | 17 #include "components/feedback/proto/dom.pb.h" |
40 #include "grit/generated_resources.h" | 18 #include "components/feedback/proto/extension.pb.h" |
41 #include "grit/locale_settings.h" | 19 #include "components/feedback/proto/math.pb.h" |
42 #include "grit/theme_resources.h" | |
43 #include "net/base/load_flags.h" | |
44 #include "net/http/http_request_headers.h" | |
45 #include "net/url_request/url_fetcher.h" | |
46 #include "net/url_request/url_fetcher_delegate.h" | |
47 #include "net/url_request/url_request_status.h" | |
48 #include "third_party/icu/source/common/unicode/locid.h" | |
49 #include "third_party/zlib/google/zip.h" | 20 #include "third_party/zlib/google/zip.h" |
50 #include "ui/base/l10n/l10n_util.h" | |
51 #include "url/gurl.h" | |
52 | 21 |
53 namespace { | 22 namespace { |
54 | 23 |
55 GURL GetTargetTabUrl(int session_id, int index) { | |
56 Browser* browser = chrome::FindBrowserWithID(session_id); | |
57 // Sanity checks. | |
58 if (!browser || index >= browser->tab_strip_model()->count()) | |
59 return GURL(); | |
60 | |
61 if (index >= 0) { | |
62 content::WebContents* target_tab = | |
63 browser->tab_strip_model()->GetWebContentsAt(index); | |
64 if (target_tab) | |
65 return target_tab->GetURL(); | |
66 } | |
67 | |
68 return GURL(); | |
69 } | |
70 | |
71 const char kPngMimeType[] = "image/png"; | 24 const char kPngMimeType[] = "image/png"; |
72 const char kArbitraryMimeType[] = "application/octet-stream"; | 25 const char kArbitraryMimeType[] = "application/octet-stream"; |
73 const char kHistogramsAttachmentName[] = "histograms.zip"; | 26 const char kHistogramsAttachmentName[] = "histograms.zip"; |
74 const char kLogsAttachmentName[] = "system_logs.zip"; | 27 const char kLogsAttachmentName[] = "system_logs.zip"; |
75 | 28 |
76 #if defined(OS_CHROMEOS) | 29 #if defined(OS_CHROMEOS) |
77 const int kChromeOSProductId = 208; | 30 const int kChromeOSProductId = 208; |
78 #else | 31 #else |
79 const int kChromeBrowserProductId = 237; | 32 const int kChromeBrowserProductId = 237; |
80 #endif | 33 #endif |
(...skipping 19 matching lines...) Expand all Loading... |
100 | 53 |
101 userfeedback::ProductSpecificBinaryData* attachment = | 54 userfeedback::ProductSpecificBinaryData* attachment = |
102 feedback_data->add_product_specific_binary_data(); | 55 feedback_data->add_product_specific_binary_data(); |
103 attachment->set_mime_type(kArbitraryMimeType); | 56 attachment->set_mime_type(kArbitraryMimeType); |
104 attachment->set_name(name); | 57 attachment->set_name(name); |
105 attachment->set_data(*data); | 58 attachment->set_data(*data); |
106 } | 59 } |
107 | 60 |
108 } // namespace | 61 } // namespace |
109 | 62 |
110 namespace chrome { | |
111 | |
112 const char kAppLauncherCategoryTag[] = "AppLauncher"; | |
113 | |
114 void ShowFeedbackPage(Browser* browser, | |
115 const std::string& description_template, | |
116 const std::string& category_tag) { | |
117 GURL page_url; | |
118 if (browser) { | |
119 page_url = GetTargetTabUrl(browser->session_id().id(), | |
120 browser->tab_strip_model()->active_index()); | |
121 } | |
122 | |
123 Profile* profile = NULL; | |
124 if (browser) { | |
125 profile = browser->profile(); | |
126 } else { | |
127 profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); | |
128 } | |
129 if (!profile) { | |
130 LOG(ERROR) << "Cannot invoke feedback: No profile found!"; | |
131 return; | |
132 } | |
133 | |
134 // We do not want to launch on an OTR profile. | |
135 profile = profile->GetOriginalProfile(); | |
136 DCHECK(profile); | |
137 | |
138 extensions::FeedbackPrivateAPI* api = | |
139 extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile); | |
140 | |
141 api->RequestFeedback(description_template, | |
142 category_tag, | |
143 page_url); | |
144 } | |
145 | |
146 } // namespace chrome | |
147 | |
148 namespace feedback_util { | 63 namespace feedback_util { |
149 | 64 |
150 void SendReport(scoped_refptr<FeedbackData> data) { | 65 void SendReport(scoped_refptr<FeedbackData> data) { |
151 if (!data.get()) { | 66 if (!data.get()) { |
152 LOG(ERROR) << "SendReport called with NULL data!"; | 67 LOG(ERROR) << "SendReport called with NULL data!"; |
153 NOTREACHED(); | 68 NOTREACHED(); |
154 return; | 69 return; |
155 } | 70 } |
156 | 71 |
157 userfeedback::ExtensionSubmit feedback_data; | 72 userfeedback::ExtensionSubmit feedback_data; |
158 // Unused field, needs to be 0 though. | 73 // Unused field, needs to be 0 though. |
159 feedback_data.set_type_id(0); | 74 feedback_data.set_type_id(0); |
160 | 75 |
161 userfeedback::CommonData* common_data = feedback_data.mutable_common_data(); | 76 userfeedback::CommonData* common_data = feedback_data.mutable_common_data(); |
162 // We're not using gaia ids, we're using the e-mail field instead. | 77 // We're not using gaia ids, we're using the e-mail field instead. |
163 common_data->set_gaia_id(0); | 78 common_data->set_gaia_id(0); |
164 common_data->set_user_email(data->user_email()); | 79 common_data->set_user_email(data->user_email()); |
165 common_data->set_description(data->description()); | 80 common_data->set_description(data->description()); |
166 | 81 |
167 std::string chrome_locale = g_browser_process->GetApplicationLocale(); | 82 std::string chrome_locale = g_browser_process->GetApplicationLocale(); |
168 common_data->set_source_description_language(chrome_locale); | 83 common_data->set_source_description_language(chrome_locale); |
169 | 84 |
170 userfeedback::WebData* web_data = feedback_data.mutable_web_data(); | 85 userfeedback::WebData* web_data = feedback_data.mutable_web_data(); |
171 web_data->set_url(data->page_url()); | 86 web_data->set_url(data->page_url()); |
172 web_data->mutable_navigator()->set_user_agent(GetUserAgent()); | 87 web_data->mutable_navigator()->set_user_agent(GetUserAgent()); |
173 | 88 |
174 gfx::Rect screen_size; | |
175 if (data->sys_info()) { | 89 if (data->sys_info()) { |
176 for (FeedbackData::SystemLogsMap::const_iterator i = | 90 for (FeedbackData::SystemLogsMap::const_iterator i = |
177 data->sys_info()->begin(); i != data->sys_info()->end(); ++i) { | 91 data->sys_info()->begin(); i != data->sys_info()->end(); ++i) { |
178 if (FeedbackData::BelowCompressionThreshold(i->second)) | 92 if (FeedbackData::BelowCompressionThreshold(i->second)) |
179 AddFeedbackData(&feedback_data, i->first, i->second); | 93 AddFeedbackData(&feedback_data, i->first, i->second); |
180 } | 94 } |
181 | 95 |
182 AddAttachment(&feedback_data, kLogsAttachmentName, data->compressed_logs()); | 96 AddAttachment(&feedback_data, kLogsAttachmentName, data->compressed_logs()); |
183 } | 97 } |
184 | 98 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 #endif | 152 #endif |
239 | 153 |
240 *(feedback_data.mutable_chrome_data()) = chrome_data; | 154 *(feedback_data.mutable_chrome_data()) = chrome_data; |
241 | 155 |
242 // This pointer will eventually get deleted by the PostCleanup class, after | 156 // This pointer will eventually get deleted by the PostCleanup class, after |
243 // we've either managed to successfully upload the report or died trying. | 157 // we've either managed to successfully upload the report or died trying. |
244 std::string post_body; | 158 std::string post_body; |
245 feedback_data.SerializeToString(&post_body); | 159 feedback_data.SerializeToString(&post_body); |
246 | 160 |
247 feedback::FeedbackUploader *uploader = | 161 feedback::FeedbackUploader *uploader = |
248 feedback::FeedbackUploaderFactory::GetForBrowserContext(data->profile()); | 162 feedback::FeedbackUploaderFactory::GetForBrowserContext(data->context()); |
249 uploader->QueueReport(post_body); | 163 uploader->QueueReport(post_body); |
250 } | 164 } |
251 | 165 |
252 bool ZipString(const base::FilePath& filename, | 166 bool ZipString(const base::FilePath& filename, |
253 const std::string& data, std::string* compressed_logs) { | 167 const std::string& data, std::string* compressed_logs) { |
254 base::FilePath temp_path; | 168 base::FilePath temp_path; |
255 base::FilePath zip_file; | 169 base::FilePath zip_file; |
256 | 170 |
257 // Create a temporary directory, put the logs into a file in it. Create | 171 // Create a temporary directory, put the logs into a file in it. Create |
258 // another temporary file to receive the zip file in. | 172 // another temporary file to receive the zip file in. |
259 if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &temp_path)) | 173 if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &temp_path)) |
260 return false; | 174 return false; |
261 if (base::WriteFile(temp_path.Append(filename), data.c_str(), data.size()) == | 175 if (base::WriteFile(temp_path.Append(filename), data.c_str(), data.size()) == |
262 -1) | 176 -1) |
263 return false; | 177 return false; |
264 | 178 |
265 bool succeed = base::CreateTemporaryFile(&zip_file) && | 179 bool succeed = base::CreateTemporaryFile(&zip_file) && |
266 zip::Zip(temp_path, zip_file, false) && | 180 zip::Zip(temp_path, zip_file, false) && |
267 base::ReadFileToString(zip_file, compressed_logs); | 181 base::ReadFileToString(zip_file, compressed_logs); |
268 | 182 |
269 base::DeleteFile(temp_path, true); | 183 base::DeleteFile(temp_path, true); |
270 base::DeleteFile(zip_file, false); | 184 base::DeleteFile(zip_file, false); |
271 | 185 |
272 return succeed; | 186 return succeed; |
273 } | 187 } |
274 | 188 |
275 } // namespace feedback_util | 189 } // namespace feedback_util |
OLD | NEW |