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/ui/webui/components_ui.h" 6 7 #include <algorithm> 8 #include <string> 9 #include <vector> 10 11 #include "base/values.h" 12 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/component_updater/component_updater_service.h" 14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser_window.h" 16 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/url_constants.h" 18 #include "content/public/browser/web_ui.h" 19 #include "content/public/browser/web_ui_data_source.h" 20 #include "content/public/browser/web_ui_message_handler.h" 21 #include "grit/browser_resources.h" 22 #include "grit/generated_resources.h" 23 #include "grit/theme_resources.h" 24 #include "ui/base/l10n/l10n_util.h" 25 #include "ui/base/resource/resource_bundle.h" 26 27 #if defined(OS_CHROMEOS) 28 #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h" 29 #endif 30 31 using content::WebUIMessageHandler; 32 33 namespace { 34 35 content::WebUIDataSource* CreateComponentsUIHTMLSource() { 36 content::WebUIDataSource* source = 37 content::WebUIDataSource::Create(chrome::kChromeUIComponentsHost); 38 source->SetUseJsonJSFormatV2(); 39 40 source->AddLocalizedString("componentsTitle", IDS_COMPONENTS_TITLE); 41 source->AddLocalizedString("componentsNoneInstalled", 42 IDS_COMPONENTS_NONE_INSTALLED); 43 source->AddLocalizedString("componentVersion", IDS_COMPONENTS_VERSION); 44 source->AddLocalizedString("checkUpdate", IDS_COMPONENTS_CHECK_FOR_UPDATE); 45 source->AddLocalizedString("noComponents", IDS_COMPONENTS_NO_COMPONENTS); 46 47 source->SetJsonPath("strings.js"); 48 source->AddResourcePath("components.js", IDR_COMPONENTS_JS); 49 source->SetDefaultResource(IDR_COMPONENTS_HTML); 50 #if defined(OS_CHROMEOS) 51 chromeos::AddAccountUITweaksLocalizedValues(source); 52 #endif 53 return source; 54 } 55 56 //////////////////////////////////////////////////////////////////////////////// 57 // 58 // ComponentsDOMHandler 59 // 60 //////////////////////////////////////////////////////////////////////////////// 61 62 // The handler for Javascript messages for the chrome://components/ page. 63 class ComponentsDOMHandler : public WebUIMessageHandler { 64 public: 65 ComponentsDOMHandler(); 66 virtual ~ComponentsDOMHandler() {} 67 68 // WebUIMessageHandler implementation. 69 virtual void RegisterMessages() OVERRIDE; 70 71 // Callback for the "requestComponentsData" message. 72 void HandleRequestComponentsData(const ListValue* args); 73 74 // Callback for the "checkUpdate" message. 75 void HandleCheckUpdate(const ListValue* args); 76 77 private: 78 void LoadComponents(); 79 80 content::NotificationRegistrar registrar_; 81 82 DISALLOW_COPY_AND_ASSIGN(ComponentsDOMHandler); 83 }; 84 85 ComponentsDOMHandler::ComponentsDOMHandler() { 86 } 87 88 void ComponentsDOMHandler::RegisterMessages() { 89 web_ui()->RegisterMessageCallback("requestComponentsData", 90 base::Bind(&ComponentsDOMHandler::HandleRequestComponentsData, 91 base::Unretained(this))); 92 93 web_ui()->RegisterMessageCallback("checkUpdate", 94 base::Bind(&ComponentsDOMHandler::HandleCheckUpdate, 95 base::Unretained(this))); 96 } 97 98 void ComponentsDOMHandler::HandleRequestComponentsData(const ListValue* args) { 99 LoadComponents(); 100 } 101 102 // This function is called when user presses button from html UI. 103 // TODO(shrikant): We need to make this button available based on current 104 // state e.g. If component state is currently updating then we need to disable 105 // button. (https://code.google.com/p/chromium/issues/detail?id=272540) 106 void ComponentsDOMHandler::HandleCheckUpdate(const ListValue* args) { 107 if (args->GetSize() != 1) { 108 NOTREACHED(); 109 return; 110 } 111 112 std::string component_id; 113 if (!args->GetString(0, &component_id)) { 114 NOTREACHED(); 115 return; 116 } 117 118 ComponentsUI::OnDemandUpdate(component_id); 119 } 120 121 void ComponentsDOMHandler::LoadComponents() { 122 ComponentUpdateService* cus = g_browser_process->component_updater(); 123 std::vector<CrxComponentInfo> components; 124 cus->GetComponents(&components); 125 126 // Construct DictionaryValues to return to UI. 127 ListValue* component_list = new ListValue(); 128 for (size_t j = 0; j < components.size(); ++j) { 129 const CrxComponentInfo& component = components[j]; 130 131 DictionaryValue* component_entry = new DictionaryValue(); 132 component_entry->SetString("id", component.id); 133 component_entry->SetString("name", component.name); 134 component_entry->SetString("version", component.version); 135 136 component_list->Append(component_entry); 137 } 138 139 DictionaryValue results; 140 results.Set("components", component_list); 141 web_ui()->CallJavascriptFunction("returnComponentsData", results); 142 } 143 144 } // namespace 145 146 /////////////////////////////////////////////////////////////////////////////// 147 // 148 // ComponentsUI 149 // 150 /////////////////////////////////////////////////////////////////////////////// 151 152 ComponentsUI::ComponentsUI(content::WebUI* web_ui) : WebUIController(web_ui) { 153 web_ui->AddMessageHandler(new ComponentsDOMHandler()); 154 155 // Set up the chrome://components/ source. 156 Profile* profile = Profile::FromWebUI(web_ui); 157 content::WebUIDataSource::Add(profile, CreateComponentsUIHTMLSource()); 158 } 159 160 // static 161 void ComponentsUI::OnDemandUpdate(const std::string& component_id) { 162 ComponentUpdateService* cus = g_browser_process->component_updater(); 163 cus->OnDemandUpdate(component_id); 164 } 165 166 // static 167 base::RefCountedMemory* ComponentsUI::GetFaviconResourceBytes( 168 ui::ScaleFactor scale_factor) { 169 return ResourceBundle::GetSharedInstance(). 170 LoadDataResourceBytesForScale(IDR_PLUGINS_FAVICON, scale_factor); 171 } 172