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 23namespace { 24 25// Retrieves the executable and profile paths on the FILE thread. 26void 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 51VersionHandler::VersionHandler() 52 : weak_ptr_factory_(this) { 53} 54 55VersionHandler::~VersionHandler() { 56} 57 58void VersionHandler::RegisterMessages() { 59 web_ui()->RegisterMessageCallback( 60 "requestVersionInfo", 61 base::Bind(&VersionHandler::HandleRequestVersionInfo, 62 base::Unretained(this))); 63} 64 65void 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 118void 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) 128void 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