crashes_ui.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/webui/crashes_ui.h" 6 7#include <vector> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/i18n/time_formatting.h" 12#include "base/memory/ref_counted_memory.h" 13#include "base/utf_string_conversions.h" 14#include "base/values.h" 15#include "chrome/browser/browser_process.h" 16#include "chrome/browser/crash_upload_list.h" 17#include "chrome/browser/prefs/pref_service.h" 18#include "chrome/browser/profiles/profile.h" 19#include "chrome/browser/ui/webui/chrome_url_data_manager.h" 20#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" 21#include "chrome/common/chrome_version_info.h" 22#include "chrome/common/pref_names.h" 23#include "chrome/common/url_constants.h" 24#include "content/public/browser/web_contents.h" 25#include "content/public/browser/web_ui.h" 26#include "content/public/browser/web_ui_message_handler.h" 27#include "grit/browser_resources.h" 28#include "grit/chromium_strings.h" 29#include "grit/generated_resources.h" 30#include "grit/theme_resources.h" 31#include "ui/base/l10n/l10n_util.h" 32#include "ui/base/resource/resource_bundle.h" 33 34#if defined(OS_CHROMEOS) 35#include "chrome/browser/chromeos/settings/cros_settings.h" 36#endif 37 38using content::WebContents; 39using content::WebUIMessageHandler; 40 41namespace { 42 43ChromeWebUIDataSource* CreateCrashesUIHTMLSource() { 44 ChromeWebUIDataSource* source = 45 new ChromeWebUIDataSource(chrome::kChromeUICrashesHost); 46 source->set_use_json_js_format_v2(); 47 48 source->AddLocalizedString("crashesTitle", IDS_CRASHES_TITLE); 49 source->AddLocalizedString("crashCountFormat", 50 IDS_CRASHES_CRASH_COUNT_BANNER_FORMAT); 51 source->AddLocalizedString("crashHeaderFormat", 52 IDS_CRASHES_CRASH_HEADER_FORMAT); 53 source->AddLocalizedString("crashTimeFormat", IDS_CRASHES_CRASH_TIME_FORMAT); 54 source->AddLocalizedString("bugLinkText", IDS_CRASHES_BUG_LINK_LABEL); 55 source->AddLocalizedString("noCrashesMessage", 56 IDS_CRASHES_NO_CRASHES_MESSAGE); 57 source->AddLocalizedString("disabledHeader", IDS_CRASHES_DISABLED_HEADER); 58 source->AddLocalizedString("disabledMessage", IDS_CRASHES_DISABLED_MESSAGE); 59 source->set_json_path("strings.js"); 60 source->add_resource_path("crashes.js", IDR_CRASHES_JS); 61 source->set_default_resource(IDR_CRASHES_HTML); 62 return source; 63} 64 65//////////////////////////////////////////////////////////////////////////////// 66// 67// CrashesDOMHandler 68// 69//////////////////////////////////////////////////////////////////////////////// 70 71// The handler for Javascript messages for the chrome://crashes/ page. 72class CrashesDOMHandler : public WebUIMessageHandler, 73 public CrashUploadList::Delegate { 74 public: 75 explicit CrashesDOMHandler(); 76 virtual ~CrashesDOMHandler(); 77 78 // WebUIMessageHandler implementation. 79 virtual void RegisterMessages() OVERRIDE; 80 81 // CrashUploadList::Delegate implemenation. 82 virtual void OnCrashListAvailable() OVERRIDE; 83 84 private: 85 // Asynchronously fetches the list of crashes. Called from JS. 86 void HandleRequestCrashes(const ListValue* args); 87 88 // Sends the recent crashes list JS. 89 void UpdateUI(); 90 91 scoped_refptr<CrashUploadList> upload_list_; 92 bool list_available_; 93 bool js_request_pending_; 94 95 DISALLOW_COPY_AND_ASSIGN(CrashesDOMHandler); 96}; 97 98CrashesDOMHandler::CrashesDOMHandler() 99 : list_available_(false), js_request_pending_(false) { 100 upload_list_ = CrashUploadList::Create(this); 101} 102 103CrashesDOMHandler::~CrashesDOMHandler() { 104 upload_list_->ClearDelegate(); 105} 106 107void CrashesDOMHandler::RegisterMessages() { 108 upload_list_->LoadCrashListAsynchronously(); 109 110 web_ui()->RegisterMessageCallback("requestCrashList", 111 base::Bind(&CrashesDOMHandler::HandleRequestCrashes, 112 base::Unretained(this))); 113} 114 115void CrashesDOMHandler::HandleRequestCrashes(const ListValue* args) { 116 if (!CrashesUI::CrashReportingEnabled() || list_available_) 117 UpdateUI(); 118 else 119 js_request_pending_ = true; 120} 121 122void CrashesDOMHandler::OnCrashListAvailable() { 123 list_available_ = true; 124 if (js_request_pending_) 125 UpdateUI(); 126} 127 128void CrashesDOMHandler::UpdateUI() { 129 bool crash_reporting_enabled = CrashesUI::CrashReportingEnabled(); 130 ListValue crash_list; 131 132 if (crash_reporting_enabled) { 133 std::vector<CrashUploadList::CrashInfo> crashes; 134 upload_list_->GetUploadedCrashes(50, &crashes); 135 136 for (std::vector<CrashUploadList::CrashInfo>::iterator i = crashes.begin(); 137 i != crashes.end(); ++i) { 138 DictionaryValue* crash = new DictionaryValue(); 139 crash->SetString("id", i->crash_id); 140 crash->SetString("time", 141 base::TimeFormatFriendlyDateAndTime(i->crash_time)); 142 crash_list.Append(crash); 143 } 144 } 145 146 base::FundamentalValue enabled(crash_reporting_enabled); 147 148 const chrome::VersionInfo version_info; 149 base::StringValue version(version_info.Version()); 150 151 web_ui()->CallJavascriptFunction("updateCrashList", enabled, crash_list, 152 version); 153} 154 155} // namespace 156 157/////////////////////////////////////////////////////////////////////////////// 158// 159// CrashesUI 160// 161/////////////////////////////////////////////////////////////////////////////// 162 163CrashesUI::CrashesUI(content::WebUI* web_ui) : WebUIController(web_ui) { 164 web_ui->AddMessageHandler(new CrashesDOMHandler()); 165 166 // Set up the chrome://crashes/ source. 167 Profile* profile = Profile::FromWebUI(web_ui); 168 ChromeURLDataManager::AddDataSource(profile, CreateCrashesUIHTMLSource()); 169} 170 171// static 172base::RefCountedMemory* CrashesUI::GetFaviconResourceBytes( 173 ui::ScaleFactor scale_factor) { 174 return ResourceBundle::GetSharedInstance(). 175 LoadDataResourceBytesForScale(IDR_SAD_FAVICON, scale_factor); 176} 177 178// static 179bool CrashesUI::CrashReportingEnabled() { 180#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) 181 PrefService* prefs = g_browser_process->local_state(); 182 return prefs->GetBoolean(prefs::kMetricsReportingEnabled); 183#elif defined(GOOGLE_CHROME_BUILD) && defined(OS_CHROMEOS) 184 bool reporting_enabled = false; 185 chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref, 186 &reporting_enabled); 187 return reporting_enabled; 188#else 189 return false; 190#endif 191} 192