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 22namespace { 23 24// Retrieves the executable and profile paths on the FILE thread. 25void GetFilePaths(const base::FilePath& profile_path, 26 string16* exec_path_out, 27 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 50VersionHandler::VersionHandler() 51 : weak_ptr_factory_(this) { 52} 53 54VersionHandler::~VersionHandler() { 55} 56 57void VersionHandler::RegisterMessages() { 58 web_ui()->RegisterMessageCallback( 59 "requestVersionInfo", 60 base::Bind(&VersionHandler::HandleRequestVersionInfo, 61 base::Unretained(this))); 62} 63 64void 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 string16* exec_path_buffer = new string16; 76 string16* profile_path_buffer = new 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 scoped_ptr<ListValue> variations_list(new ListValue()); 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 ReplaceChars(line, "-", kNonBreakingHyphenUTF8String, &line); 101 variations.push_back(line); 102 } 103#else 104 // In release mode, display the hashes only. 105 std::vector<string16> active_groups; 106 chrome_variations::GetFieldTrialActiveGroupIdsAsStrings(&active_groups); 107 for (size_t i = 0; i < active_groups.size(); ++i) 108 variations.push_back(UTF16ToASCII(active_groups[i])); 109#endif 110 111 for (std::vector<std::string>::const_iterator it = variations.begin(); 112 it != variations.end(); ++it) { 113 variations_list->Append(Value::CreateStringValue(*it)); 114 } 115 116 // In release mode, this will return an empty list to clear the section. 117 web_ui()->CallJavascriptFunction("returnVariationInfo", 118 *variations_list.release()); 119} 120 121void VersionHandler::OnGotFilePaths(string16* executable_path_data, 122 string16* profile_path_data) { 123 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 124 125 StringValue exec_path(*executable_path_data); 126 StringValue profile_path(*profile_path_data); 127 web_ui()->CallJavascriptFunction("returnFilePaths", exec_path, profile_path); 128} 129 130#if defined(ENABLE_PLUGINS) 131void VersionHandler::OnGotPlugins( 132 const std::vector<content::WebPluginInfo>& plugins) { 133 // Obtain the version of the first enabled Flash plugin. 134 std::vector<content::WebPluginInfo> info_array; 135 content::PluginService::GetInstance()->GetPluginInfoArray( 136 GURL(), content::kFlashPluginSwfMimeType, false, &info_array, NULL); 137 string16 flash_version = 138 l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_PLUGIN); 139 PluginPrefs* plugin_prefs = 140 PluginPrefs::GetForProfile(Profile::FromWebUI(web_ui())).get(); 141 if (plugin_prefs) { 142 for (size_t i = 0; i < info_array.size(); ++i) { 143 if (plugin_prefs->IsPluginEnabled(info_array[i])) { 144 flash_version = info_array[i].version; 145 break; 146 } 147 } 148 } 149 150 StringValue arg(flash_version); 151 web_ui()->CallJavascriptFunction("returnFlashVersion", arg); 152} 153#endif // defined(ENABLE_PLUGINS) 154