Chromium Code Reviews| 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 "chrome/browser/feedback/feedback_util.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/file_version_info.h" | 14 #include "base/file_version_info.h" |
| 15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/win/windows_version.h" | 20 #include "base/win/windows_version.h" |
| 21 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
| 22 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" | 22 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" |
| 23 #include "chrome/browser/feedback/feedback_data.h" | 23 #include "chrome/browser/feedback/feedback_data.h" |
| 24 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" | 24 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 25 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/browser/profiles/profile_manager.h" | |
| 26 #include "chrome/browser/safe_browsing/safe_browsing_util.h" | 27 #include "chrome/browser/safe_browsing/safe_browsing_util.h" |
| 27 #include "chrome/browser/ui/browser_finder.h" | 28 #include "chrome/browser/ui/browser_finder.h" |
| 28 #include "chrome/browser/ui/browser_list.h" | 29 #include "chrome/browser/ui/browser_list.h" |
| 29 #include "chrome/browser/ui/browser_window.h" | 30 #include "chrome/browser/ui/browser_window.h" |
| 30 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 31 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 31 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
| 32 #include "chrome/common/chrome_version_info.h" | 33 #include "chrome/common/chrome_version_info.h" |
| 33 #include "chrome/common/metrics/metrics_log_manager.h" | 34 #include "chrome/common/metrics/metrics_log_manager.h" |
| 34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
| 35 #include "content/public/browser/navigation_controller.h" | 36 #include "content/public/browser/navigation_controller.h" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 54 #include "ui/aura/window.h" | 55 #include "ui/aura/window.h" |
| 55 #endif | 56 #endif |
| 56 | 57 |
| 57 namespace { | 58 namespace { |
| 58 | 59 |
| 59 const base::FilePath::CharType kLogsFilename[] = | 60 const base::FilePath::CharType kLogsFilename[] = |
| 60 FILE_PATH_LITERAL("system_logs.txt"); | 61 FILE_PATH_LITERAL("system_logs.txt"); |
| 61 | 62 |
| 62 void DispatchFeedback(Profile* profile, std::string* post_body, int64 delay); | 63 void DispatchFeedback(Profile* profile, std::string* post_body, int64 delay); |
| 63 | 64 |
| 64 // Check the key/value pair to see if it is one of the screensize, keys. If so, | |
| 65 // populate the screensize structure with the key. | |
| 66 bool IsScreensizeInfo(const std::string key, | |
| 67 const std::string value, | |
| 68 gfx::Rect* screen_size) { | |
| 69 if (key == FeedbackData::kScreensizeHeightKey) { | |
| 70 int height = 0; | |
| 71 base::StringToInt(value, &height); | |
| 72 screen_size->SetRect(0, 0, screen_size->width(), height); | |
| 73 return true; | |
| 74 } else if (key == FeedbackData::kScreensizeWidthKey) { | |
| 75 int width = 0; | |
| 76 base::StringToInt(value, &width); | |
| 77 screen_size->SetRect(0, 0, width, screen_size->height()); | |
| 78 return true; | |
| 79 } | |
| 80 return false; | |
| 81 } | |
| 82 | |
| 83 GURL GetTargetTabUrl(int session_id, int index) { | 65 GURL GetTargetTabUrl(int session_id, int index) { |
| 84 Browser* browser = chrome::FindBrowserWithID(session_id); | 66 Browser* browser = chrome::FindBrowserWithID(session_id); |
| 85 // Sanity checks. | 67 // Sanity checks. |
| 86 if (!browser || index >= browser->tab_strip_model()->count()) | 68 if (!browser || index >= browser->tab_strip_model()->count()) |
| 87 return GURL(); | 69 return GURL(); |
| 88 | 70 |
| 89 if (index >= 0) { | 71 if (index >= 0) { |
| 90 content::WebContents* target_tab = | 72 content::WebContents* target_tab = |
| 91 browser->tab_strip_model()->GetWebContentsAt(index); | 73 browser->tab_strip_model()->GetWebContentsAt(index); |
| 92 if (target_tab) | 74 if (target_tab) |
| 93 return target_tab->GetURL(); | 75 return target_tab->GetURL(); |
| 94 } | 76 } |
| 95 | 77 |
| 96 return GURL(); | 78 return GURL(); |
| 97 } | 79 } |
| 98 | 80 |
| 99 gfx::Rect GetScreenSize(Browser* browser) { | |
| 100 #if defined(OS_CHROMEOS) | |
| 101 // For ChromeOS, don't use the browser window but the root window | |
| 102 // instead to grab the screenshot. We want everything on the screen, not | |
| 103 // just the current browser. | |
| 104 gfx::NativeWindow native_window = ash::Shell::GetPrimaryRootWindow(); | |
| 105 return gfx::Rect(native_window->bounds()); | |
| 106 #else | |
| 107 return gfx::Rect(browser->window()->GetBounds().size()); | |
| 108 #endif | |
| 109 } | |
| 110 | |
| 111 // URL to post bug reports to. | 81 // URL to post bug reports to. |
| 112 const char kFeedbackPostUrl[] = | 82 const char kFeedbackPostUrl[] = |
| 113 "https://www.google.com/tools/feedback/chrome/__submit"; | 83 "https://www.google.com/tools/feedback/chrome/__submit"; |
| 114 | 84 |
| 115 const char kProtBufMimeType[] = "application/x-protobuf"; | 85 const char kProtBufMimeType[] = "application/x-protobuf"; |
| 116 const char kPngMimeType[] = "image/png"; | 86 const char kPngMimeType[] = "image/png"; |
| 117 | 87 |
| 118 const int kHttpPostSuccessNoContent = 204; | 88 const int kHttpPostSuccessNoContent = 204; |
| 119 const int kHttpPostFailNoConnection = -1; | 89 const int kHttpPostFailNoConnection = -1; |
| 120 const int kHttpPostFailClientError = 400; | 90 const int kHttpPostFailClientError = 400; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 *(web_data->add_product_specific_data()) = log_value; | 217 *(web_data->add_product_specific_data()) = log_value; |
| 248 } | 218 } |
| 249 | 219 |
| 250 } // namespace | 220 } // namespace |
| 251 | 221 |
| 252 namespace chrome { | 222 namespace chrome { |
| 253 | 223 |
| 254 const char kAppLauncherCategoryTag[] = "AppLauncher"; | 224 const char kAppLauncherCategoryTag[] = "AppLauncher"; |
| 255 | 225 |
| 256 void ShowFeedbackPage(Browser* browser, | 226 void ShowFeedbackPage(Browser* browser, |
| 257 const std::string& description_template, | 227 const std::string& description_template, |
|
Zachary Kuznia
2013/09/24 23:46:43
nit: fix this indent while you're here.
rkc
2013/09/25 00:00:36
Done.
| |
| 258 const std::string& category_tag) { | 228 const std::string& category_tag) { |
| 259 DCHECK(browser); | 229 GURL page_url; |
| 230 if (browser) { | |
| 231 page_url = GetTargetTabUrl(browser->session_id().id(), | |
| 232 browser->tab_strip_model()->active_index()); | |
| 233 } | |
| 260 | 234 |
| 261 // Get the current browser's screensize and send it with the feedback request | 235 Profile* profile = NULL; |
| 262 // event - this browser may have changed or even been closed by the time that | 236 if (browser) { |
| 263 // feedback is sent. | 237 profile = browser->profile(); |
| 264 gfx::Rect screen_size = GetScreenSize(browser); | 238 } else { |
| 265 GURL page_url = GetTargetTabUrl( | 239 profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); |
| 266 browser->session_id().id(), browser->tab_strip_model()->active_index()); | 240 } |
| 241 if (!profile) { | |
| 242 LOG(ERROR) << "Cannot invoke feedback: No profile found!"; | |
| 243 return; | |
| 244 } | |
| 267 | 245 |
| 268 extensions::FeedbackPrivateAPI* api = | 246 extensions::FeedbackPrivateAPI* api = |
| 269 extensions::FeedbackPrivateAPI::GetFactoryInstance()->GetForProfile( | 247 extensions::FeedbackPrivateAPI::GetFactoryInstance()->GetForProfile( |
| 270 browser->profile()); | 248 profile); |
| 271 | 249 |
| 272 api->RequestFeedback(description_template, | 250 api->RequestFeedback(description_template, |
| 273 category_tag, | 251 category_tag, |
| 274 page_url, | 252 page_url); |
| 275 screen_size); | |
| 276 } | 253 } |
| 277 | 254 |
| 278 } // namespace chrome | 255 } // namespace chrome |
| 279 | 256 |
| 280 namespace feedback_util { | 257 namespace feedback_util { |
| 281 | 258 |
| 282 void SendReport(scoped_refptr<FeedbackData> data) { | 259 void SendReport(scoped_refptr<FeedbackData> data) { |
| 283 if (!data.get()) { | 260 if (!data.get()) { |
| 284 LOG(ERROR) << "SendReport called with NULL data!"; | 261 LOG(ERROR) << "SendReport called with NULL data!"; |
| 285 NOTREACHED(); | 262 NOTREACHED(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 300 common_data->set_source_description_language(chrome_locale); | 277 common_data->set_source_description_language(chrome_locale); |
| 301 | 278 |
| 302 userfeedback::WebData* web_data = feedback_data.mutable_web_data(); | 279 userfeedback::WebData* web_data = feedback_data.mutable_web_data(); |
| 303 web_data->set_url(data->page_url()); | 280 web_data->set_url(data->page_url()); |
| 304 web_data->mutable_navigator()->set_user_agent(content::GetUserAgent(GURL())); | 281 web_data->mutable_navigator()->set_user_agent(content::GetUserAgent(GURL())); |
| 305 | 282 |
| 306 gfx::Rect screen_size; | 283 gfx::Rect screen_size; |
| 307 if (data->sys_info()) { | 284 if (data->sys_info()) { |
| 308 for (FeedbackData::SystemLogsMap::const_iterator i = | 285 for (FeedbackData::SystemLogsMap::const_iterator i = |
| 309 data->sys_info()->begin(); i != data->sys_info()->end(); ++i) { | 286 data->sys_info()->begin(); i != data->sys_info()->end(); ++i) { |
| 310 if (!IsScreensizeInfo(i->first, i->second, &screen_size)) { | 287 if (FeedbackData::BelowCompressionThreshold(i->second)) |
| 311 if (FeedbackData::BelowCompressionThreshold(i->second)) | 288 AddFeedbackData(&feedback_data, i->first, i->second); |
| 312 AddFeedbackData(&feedback_data, i->first, i->second); | |
| 313 } | |
| 314 } | 289 } |
| 315 | 290 |
| 316 if (data->compressed_logs() && data->compressed_logs()->size()) { | 291 if (data->compressed_logs() && data->compressed_logs()->size()) { |
| 317 userfeedback::ProductSpecificBinaryData attachment; | 292 userfeedback::ProductSpecificBinaryData attachment; |
| 318 attachment.set_mime_type(kArbitraryMimeType); | 293 attachment.set_mime_type(kArbitraryMimeType); |
| 319 attachment.set_name(kLogsAttachmentName); | 294 attachment.set_name(kLogsAttachmentName); |
| 320 attachment.set_data(*(data->compressed_logs())); | 295 attachment.set_data(*(data->compressed_logs())); |
| 321 *(feedback_data.add_product_specific_binary_data()) = attachment; | 296 *(feedback_data.add_product_specific_binary_data()) = attachment; |
| 322 } | 297 } |
| 323 } | 298 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 335 attached_file.set_data(*data->attached_filedata()); | 310 attached_file.set_data(*data->attached_filedata()); |
| 336 *(feedback_data.add_product_specific_binary_data()) = attached_file; | 311 *(feedback_data.add_product_specific_binary_data()) = attached_file; |
| 337 } | 312 } |
| 338 | 313 |
| 339 // NOTE: Screenshot needs to be processed after system info since we'll get | 314 // NOTE: Screenshot needs to be processed after system info since we'll get |
| 340 // the screenshot dimensions from system info. | 315 // the screenshot dimensions from system info. |
| 341 if (data->image() && data->image()->size()) { | 316 if (data->image() && data->image()->size()) { |
| 342 userfeedback::PostedScreenshot screenshot; | 317 userfeedback::PostedScreenshot screenshot; |
| 343 screenshot.set_mime_type(kPngMimeType); | 318 screenshot.set_mime_type(kPngMimeType); |
| 344 | 319 |
| 345 // Set the dimensions of the screenshot | 320 // Set that we 'have' dimensions of the screenshot. These dimensions are |
| 321 // ignored by the server but are a 'required' field in the protobuf. | |
| 346 userfeedback::Dimensions dimensions; | 322 userfeedback::Dimensions dimensions; |
| 347 dimensions.set_width(static_cast<float>(screen_size.width())); | 323 dimensions.set_width(0.0); |
| 348 dimensions.set_height(static_cast<float>(screen_size.height())); | 324 dimensions.set_height(0.0); |
| 349 | 325 |
| 350 *(screenshot.mutable_dimensions()) = dimensions; | 326 *(screenshot.mutable_dimensions()) = dimensions; |
| 351 screenshot.set_binary_content(*data->image()); | 327 screenshot.set_binary_content(*data->image()); |
| 352 | 328 |
| 353 *(feedback_data.mutable_screenshot()) = screenshot; | 329 *(feedback_data.mutable_screenshot()) = screenshot; |
| 354 } | 330 } |
| 355 | 331 |
| 356 if (data->category_tag().size()) | 332 if (data->category_tag().size()) |
| 357 feedback_data.set_bucket(data->category_tag()); | 333 feedback_data.set_bucket(data->category_tag()); |
| 358 | 334 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 if (!zip::Zip(temp_path, zip_file, false)) | 379 if (!zip::Zip(temp_path, zip_file, false)) |
| 404 return false; | 380 return false; |
| 405 | 381 |
| 406 if (!base::ReadFileToString(zip_file, compressed_logs)) | 382 if (!base::ReadFileToString(zip_file, compressed_logs)) |
| 407 return false; | 383 return false; |
| 408 | 384 |
| 409 return true; | 385 return true; |
| 410 } | 386 } |
| 411 | 387 |
| 412 } // namespace feedback_util | 388 } // namespace feedback_util |
| OLD | NEW |