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