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/version_handler.h" 6 7 #include "base/command_line.h" 8 #include "base/files/file_util.h" 9 #include "base/metrics/field_trial.h" 10 #include "base/strings/string_util.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "chrome/browser/plugins/plugin_prefs.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/grit/generated_resources.h" 15 #include "components/variations/active_field_trials.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/plugin_service.h" 18 #include "content/public/browser/web_ui.h" 19 #include "content/public/common/content_constants.h" 20 #include "ui/base/l10n/l10n_util.h" 21 #include "url/gurl.h" 22 23 namespace { 24 25 // Retrieves the executable and profile paths on the FILE thread. 26 void GetFilePaths(const base::FilePath& profile_path, 27 base::string16* exec_path_out, 28 base::string16* profile_path_out) { 29 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); 30 31 base::FilePath executable_path = base::MakeAbsoluteFilePath( 32 CommandLine::ForCurrentProcess()->GetProgram()); 33 if (!executable_path.empty()) { 34 *exec_path_out = executable_path.LossyDisplayName(); 35 } else { 36 *exec_path_out = 37 l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_PATH_NOTFOUND); 38 } 39 40 base::FilePath profile_path_copy(base::MakeAbsoluteFilePath(profile_path)); 41 if (!profile_path.empty() && !profile_path_copy.empty()) { 42 *profile_path_out = profile_path.LossyDisplayName(); 43 } else { 44 *profile_path_out = 45 l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_PATH_NOTFOUND); 46 } 47 } 48 49 } // namespace 50 51 VersionHandler::VersionHandler() 52 : weak_ptr_factory_(this) { 53 } 54 55 VersionHandler::~VersionHandler() { 56 } 57 58 void VersionHandler::RegisterMessages() { 59 web_ui()->RegisterMessageCallback( 60 "requestVersionInfo", 61 base::Bind(&VersionHandler::HandleRequestVersionInfo, 62 base::Unretained(this))); 63 } 64 65 void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { 66 #if defined(ENABLE_PLUGINS) 67 // The Flash version information is needed in the response, so make sure 68 // the plugins are loaded. 69 content::PluginService::GetInstance()->GetPlugins( 70 base::Bind(&VersionHandler::OnGotPlugins, 71 weak_ptr_factory_.GetWeakPtr())); 72 #endif 73 74 // Grab the executable path on the FILE thread. It is returned in 75 // OnGotFilePaths. 76 base::string16* exec_path_buffer = new base::string16; 77 base::string16* profile_path_buffer = new base::string16; 78 content::BrowserThread::PostTaskAndReply( 79 content::BrowserThread::FILE, FROM_HERE, 80 base::Bind(&GetFilePaths, Profile::FromWebUI(web_ui())->GetPath(), 81 base::Unretained(exec_path_buffer), 82 base::Unretained(profile_path_buffer)), 83 base::Bind(&VersionHandler::OnGotFilePaths, 84 weak_ptr_factory_.GetWeakPtr(), 85 base::Owned(exec_path_buffer), 86 base::Owned(profile_path_buffer))); 87 88 // Respond with the variations info immediately. 89 std::vector<std::string> variations; 90 #if !defined(NDEBUG) 91 base::FieldTrial::ActiveGroups active_groups; 92 base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups); 93 94 const unsigned char kNonBreakingHyphenUTF8[] = { 0xE2, 0x80, 0x91, '\0' }; 95 const std::string kNonBreakingHyphenUTF8String( 96 reinterpret_cast<const char*>(kNonBreakingHyphenUTF8)); 97 for (size_t i = 0; i < active_groups.size(); ++i) { 98 std::string line = active_groups[i].trial_name + ":" + 99 active_groups[i].group_name; 100 base::ReplaceChars(line, "-", kNonBreakingHyphenUTF8String, &line); 101 variations.push_back(line); 102 } 103 #else 104 // In release mode, display the hashes only. 105 variations::GetFieldTrialActiveGroupIdsAsStrings(&variations); 106 #endif 107 108 base::ListValue variations_list; 109 for (std::vector<std::string>::const_iterator it = variations.begin(); 110 it != variations.end(); ++it) { 111 variations_list.Append(new base::StringValue(*it)); 112 } 113 114 // In release mode, this will return an empty list to clear the section. 115 web_ui()->CallJavascriptFunction("returnVariationInfo", variations_list); 116 } 117 118 void VersionHandler::OnGotFilePaths(base::string16* executable_path_data, 119 base::string16* profile_path_data) { 120 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 121 122 base::StringValue exec_path(*executable_path_data); 123 base::StringValue profile_path(*profile_path_data); 124 web_ui()->CallJavascriptFunction("returnFilePaths", exec_path, profile_path); 125 } 126 127 #if defined(ENABLE_PLUGINS) 128 void VersionHandler::OnGotPlugins( 129 const std::vector<content::WebPluginInfo>& plugins) { 130 // Obtain the version of the first enabled Flash plugin. 131 std::vector<content::WebPluginInfo> info_array; 132 content::PluginService::GetInstance()->GetPluginInfoArray( 133 GURL(), content::kFlashPluginSwfMimeType, false, &info_array, NULL); 134 base::string16 flash_version = 135 l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_PLUGIN); 136 PluginPrefs* plugin_prefs = 137 PluginPrefs::GetForProfile(Profile::FromWebUI(web_ui())).get(); 138 if (plugin_prefs) { 139 for (size_t i = 0; i < info_array.size(); ++i) { 140 if (plugin_prefs->IsPluginEnabled(info_array[i])) { 141 flash_version = info_array[i].version; 142 break; 143 } 144 } 145 } 146 147 base::StringValue arg(flash_version); 148 web_ui()->CallJavascriptFunction("returnFlashVersion", arg); 149 } 150 #endif // defined(ENABLE_PLUGINS) 151