Commit e5a1aeda authored by Orin Jaworski's avatar Orin Jaworski Committed by Commit Bot

Refactor VersionHandler to interop with JS via promises

This CL reworks the interop mechanism for obtaining version info
from VersionHandler in about:version.  Instead of relying on
chrome.send to result in several asynchronous callbacks, the
parts are requested using cr.sendWithPromise and handlers are
explicitly called by JS.  The original chrome.send mechanism
is left intact for use by platform-specific derived classes.

Bug: 964528

Change-Id: Ia68e95beb68b38201d29d5d51448ee989bdf333f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1717483Reviewed-by: default avatarPeter Lee <pkl@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarTommy Li <tommycli@chromium.org>
Commit-Queue: Orin Jaworski <orinj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682332}
parent 154ae328
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "content/public/common/content_constants.h" #include "content/public/common/content_constants.h"
#include "ppapi/buildflags/buildflags.h" #include "ppapi/buildflags/buildflags.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -66,17 +67,73 @@ void VersionHandler::RegisterMessages() { ...@@ -66,17 +67,73 @@ void VersionHandler::RegisterMessages() {
version_ui::kRequestVersionInfo, version_ui::kRequestVersionInfo,
base::BindRepeating(&VersionHandler::HandleRequestVersionInfo, base::BindRepeating(&VersionHandler::HandleRequestVersionInfo,
base::Unretained(this))); base::Unretained(this)));
web_ui()->RegisterMessageCallback(
version_ui::kRequestVariationInfo,
base::BindRepeating(&VersionHandler::HandleRequestVariationInfo,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
version_ui::kRequestPluginInfo,
base::BindRepeating(&VersionHandler::HandleRequestPluginInfo,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
version_ui::kRequestPathInfo,
base::BindRepeating(&VersionHandler::HandleRequestPathInfo,
base::Unretained(this)));
} }
void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) {
// This method is overridden by platform-specific handlers which may still
// use |CallJavascriptFunction|. Main version info is returned by promise
// using handlers below.
// TODO(orinj): To fully eliminate chrome.send usage in JS, derived classes
// could be made to work more like this base class, using
// |ResolveJavascriptCallback| instead of |CallJavascriptFunction|.
AllowJavascript();
}
void VersionHandler::HandleRequestVariationInfo(const base::ListValue* args) {
AllowJavascript();
std::string callback_id;
bool include_variations_cmd;
CHECK_EQ(2U, args->GetSize());
CHECK(args->GetString(0, &callback_id));
CHECK(args->GetBoolean(1, &include_variations_cmd));
base::Value response(base::Value::Type::DICTIONARY);
response.SetKey(version_ui::kKeyVariationsList,
std::move(*version_ui::GetVariationsList()));
if (include_variations_cmd) {
response.SetKey(version_ui::kKeyVariationsCmd,
version_ui::GetVariationsCommandLineAsValue());
}
ResolveJavascriptCallback(base::Value(callback_id), response);
}
void VersionHandler::HandleRequestPluginInfo(const base::ListValue* args) {
AllowJavascript(); AllowJavascript();
std::string callback_id;
CHECK_EQ(1U, args->GetSize());
CHECK(args->GetString(0, &callback_id));
#if BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS)
// The Flash version information is needed in the response, so make sure // The Flash version information is needed in the response, so make sure
// the plugins are loaded. // the plugins are loaded.
content::PluginService::GetInstance()->GetPlugins( content::PluginService::GetInstance()->GetPlugins(
base::Bind(&VersionHandler::OnGotPlugins, base::Bind(&VersionHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr(),
weak_ptr_factory_.GetWeakPtr())); callback_id));
#else
RejectJavascriptCallback(base::Value(callback_id), base::Value());
#endif #endif
}
void VersionHandler::HandleRequestPathInfo(const base::ListValue* args) {
AllowJavascript();
std::string callback_id;
CHECK_EQ(1U, args->GetSize());
CHECK(args->GetString(0, &callback_id));
// Grab the executable path on the FILE thread. It is returned in // Grab the executable path on the FILE thread. It is returned in
// OnGotFilePaths. // OnGotFilePaths.
...@@ -87,32 +144,25 @@ void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { ...@@ -87,32 +144,25 @@ void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) {
base::BindOnce(&GetFilePaths, Profile::FromWebUI(web_ui())->GetPath(), base::BindOnce(&GetFilePaths, Profile::FromWebUI(web_ui())->GetPath(),
base::Unretained(exec_path_buffer), base::Unretained(exec_path_buffer),
base::Unretained(profile_path_buffer)), base::Unretained(profile_path_buffer)),
base::BindOnce( base::BindOnce(&VersionHandler::OnGotFilePaths,
&VersionHandler::OnGotFilePaths, weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(), callback_id,
base::Owned(exec_path_buffer), base::Owned(profile_path_buffer))); base::Owned(exec_path_buffer),
base::Owned(profile_path_buffer)));
// Respond with the variations info immediately.
CallJavascriptFunction(version_ui::kReturnVariationInfo,
*version_ui::GetVariationsList());
GURL current_url = web_ui()->GetWebContents()->GetVisibleURL();
if (current_url.query().find(version_ui::kVariationsShowCmdQuery) !=
std::string::npos) {
CallJavascriptFunction(version_ui::kReturnVariationCmd,
version_ui::GetVariationsCommandLineAsValue());
}
} }
void VersionHandler::OnGotFilePaths(base::string16* executable_path_data, void VersionHandler::OnGotFilePaths(std::string callback_id,
base::string16* executable_path_data,
base::string16* profile_path_data) { base::string16* profile_path_data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
base::Value response(base::Value::Type::DICTIONARY);
base::Value exec_path(*executable_path_data); response.SetKey(version_ui::kKeyExecPath, base::Value(*executable_path_data));
base::Value profile_path(*profile_path_data); response.SetKey(version_ui::kKeyProfilePath, base::Value(*profile_path_data));
CallJavascriptFunction(version_ui::kReturnFilePaths, exec_path, profile_path); ResolveJavascriptCallback(base::Value(callback_id), response);
} }
#if BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS)
void VersionHandler::OnGotPlugins( void VersionHandler::OnGotPlugins(
std::string callback_id,
const std::vector<content::WebPluginInfo>& plugins) { const std::vector<content::WebPluginInfo>& plugins) {
// Obtain the version of the first enabled Flash plugin. // Obtain the version of the first enabled Flash plugin.
std::vector<content::WebPluginInfo> info_array; std::vector<content::WebPluginInfo> info_array;
...@@ -132,9 +182,7 @@ void VersionHandler::OnGotPlugins( ...@@ -132,9 +182,7 @@ void VersionHandler::OnGotPlugins(
} }
} }
} }
ResolveJavascriptCallback(base::Value(callback_id),
base::Value arg(flash_version_and_path); base::Value(flash_version_and_path));
CallJavascriptFunction(version_ui::kReturnFlashVersion, arg);
} }
#endif // BUILDFLAG(ENABLE_PLUGINS) #endif // BUILDFLAG(ENABLE_PLUGINS)
...@@ -22,20 +22,36 @@ class VersionHandler : public content::WebUIMessageHandler { ...@@ -22,20 +22,36 @@ class VersionHandler : public content::WebUIMessageHandler {
// content::WebUIMessageHandler implementation. // content::WebUIMessageHandler implementation.
void RegisterMessages() override; void RegisterMessages() override;
// Callback for the "requestVersionInfo" message. This asynchronously requests // Callback for the "requestVersionInfo" message sent by |chrome.send| in JS.
// the flash version and eventually returns it to the front end along with the // This is still supported for platform-specific asynchronous calls (see
// list of variations using OnGotPlugins. // derived classes) but the main version information is now retrieved with
// below messages using |cr.sendWithPromise|.
virtual void HandleRequestVersionInfo(const base::ListValue* args); virtual void HandleRequestVersionInfo(const base::ListValue* args);
// Callback for the "requestVariationInfo" message. This resolves immediately
// with variations list as well as command variations if requested.
virtual void HandleRequestVariationInfo(const base::ListValue* args);
// Callback for the "requestPluginInfo" message. This asynchronously requests
// the flash version and eventually returns it to the front end along with the
// list of variations using |OnGotPlugins|.
virtual void HandleRequestPluginInfo(const base::ListValue* args);
// Callback for the "requestPathInfo" message. This resolves asynchronously
// with |OnGotFilePaths|.
virtual void HandleRequestPathInfo(const base::ListValue* args);
private: private:
// Callback which handles returning the executable and profile paths to the // Callback which handles returning the executable and profile paths to the
// front end. // front end.
void OnGotFilePaths(base::string16* executable_path_data, void OnGotFilePaths(std::string callback_id,
base::string16* executable_path_data,
base::string16* profile_path_data); base::string16* profile_path_data);
// Callback for GetPlugins which responds to the page with the Flash version. // Callback for GetPlugins which responds to the page with the Flash version.
// This also initiates the OS Version load on ChromeOS. // This also initiates the OS Version load on ChromeOS.
void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins); void OnGotPlugins(std::string callback_id,
const std::vector<content::WebPluginInfo>& plugins);
// Factory for the creating refs in callbacks. // Factory for the creating refs in callbacks.
base::WeakPtrFactory<VersionHandler> weak_ptr_factory_{this}; base::WeakPtrFactory<VersionHandler> weak_ptr_factory_{this};
......
...@@ -16,6 +16,8 @@ VersionHandlerChromeOS::~VersionHandlerChromeOS() {} ...@@ -16,6 +16,8 @@ VersionHandlerChromeOS::~VersionHandlerChromeOS() {}
void VersionHandlerChromeOS::HandleRequestVersionInfo( void VersionHandlerChromeOS::HandleRequestVersionInfo(
const base::ListValue* args) { const base::ListValue* args) {
VersionHandler::HandleRequestVersionInfo(args);
// Start the asynchronous load of the versions. // Start the asynchronous load of the versions.
base::PostTaskWithTraitsAndReplyWithResult( base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
...@@ -33,9 +35,6 @@ void VersionHandlerChromeOS::HandleRequestVersionInfo( ...@@ -33,9 +35,6 @@ void VersionHandlerChromeOS::HandleRequestVersionInfo(
base::Bind(&chromeos::version_loader::GetARCVersion), base::Bind(&chromeos::version_loader::GetARCVersion),
base::Bind(&VersionHandlerChromeOS::OnARCVersion, base::Bind(&VersionHandlerChromeOS::OnARCVersion,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
// Parent class takes care of the rest.
VersionHandler::HandleRequestVersionInfo(args);
} }
void VersionHandlerChromeOS::OnVersion(const std::string& version) { void VersionHandlerChromeOS::OnVersion(const std::string& version) {
......
...@@ -17,15 +17,14 @@ VersionHandlerWindows::~VersionHandlerWindows() {} ...@@ -17,15 +17,14 @@ VersionHandlerWindows::~VersionHandlerWindows() {}
void VersionHandlerWindows::HandleRequestVersionInfo( void VersionHandlerWindows::HandleRequestVersionInfo(
const base::ListValue* args) { const base::ListValue* args) {
VersionHandler::HandleRequestVersionInfo(args);
// Start the asynchronous load of the versions. // Start the asynchronous load of the versions.
base::PostTaskWithTraitsAndReplyWithResult( base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&version_utils::win::GetFullWindowsVersion), base::BindOnce(&version_utils::win::GetFullWindowsVersion),
base::BindOnce(&VersionHandlerWindows::OnVersion, base::BindOnce(&VersionHandlerWindows::OnVersion,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
// Parent class takes care of the rest.
VersionHandler::HandleRequestVersionInfo(args);
} }
void VersionHandlerWindows::OnVersion(const std::string& version) { void VersionHandlerWindows::OnVersion(const std::string& version) {
......
...@@ -22,6 +22,7 @@ about:version template page ...@@ -22,6 +22,7 @@ about:version template page
<script src="chrome://resources/js/ios/web_ui.js"></script> <script src="chrome://resources/js/ios/web_ui.js"></script>
</if> </if>
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/cr.js"></script> <script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/parse_html_subset.js"></script> <script src="chrome://resources/js/parse_html_subset.js"></script>
......
...@@ -2,44 +2,40 @@ ...@@ -2,44 +2,40 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Note: The handle* functions below are called internally on promise
// resolution, unlike the other return* functions, which are called
// asynchronously by the host.
/** /**
* Callback from the backend with the list of variations to display. * Promise resolution handler for variations list and command line equivalent.
* This call will build the variations section of the version page, or hide that * @param {{variationsList: !Array<string>, variationsCmd: string=}}
* section if there are none to display.
* @param {!Array<string>} variationsList The list of variations.
*/ */
function returnVariationInfo(variationsList) { function handleVariationInfo({variationsList, variationsCmd}) {
$('variations-section').hidden = !variationsList.length; $('variations-section').hidden = !variationsList.length;
$('variations-list').appendChild( $('variations-list').appendChild(
parseHtmlSubset(variationsList.join('<br>'), ['BR'])); parseHtmlSubset(variationsList.join('<br>'), ['BR']));
}
/** if (variationsCmd) {
* Callback from the backend with the variations formatted as command line $('variations-cmd-section').hidden = !variationsCmd;
* input. This call will build the variations-cmd section of the version page $('variations-cmd').textContent = variationsCmd;
* if needed. }
* @param {string} variationsCmd The variations info in command line format.
*/
function returnVariationCmd(variationsCmd) {
$('variations-cmd-section').hidden = !variationsCmd;
$('variations-cmd').textContent = variationsCmd;
} }
/** /**
* Callback from the backend with the executable and profile paths to display. * Promise resolution handler for the executable and profile paths to display.
* @param {string} execPath The executable path to display. * @param {string} execPath The executable path to display.
* @param {string} profilePath The profile path to display. * @param {string} profilePath The profile path to display.
*/ */
function returnFilePaths(execPath, profilePath) { function handlePathInfo({execPath, profilePath}) {
$('executable_path').textContent = execPath; $('executable_path').textContent = execPath;
$('profile_path').textContent = profilePath; $('profile_path').textContent = profilePath;
} }
/** /**
* Callback from the backend with the Flash version to display. * Promise resolution handler for the Flash version to display.
* @param {string} flashVersion The Flash version to display. * @param {string} flashVersion The Flash version to display.
*/ */
function returnFlashVersion(flashVersion) { function handlePluginInfo(flashVersion) {
$('flash_version').textContent = flashVersion; $('flash_version').textContent = flashVersion;
} }
...@@ -83,6 +79,12 @@ function returnCustomizationId(response) { ...@@ -83,6 +79,12 @@ function returnCustomizationId(response) {
/* All the work we do onload. */ /* All the work we do onload. */
function onLoadWork() { function onLoadWork() {
chrome.send('requestVersionInfo'); chrome.send('requestVersionInfo');
const includeVariationsCmd = location.search.includes("show-variations-cmd");
cr.sendWithPromise('requestVariationInfo', includeVariationsCmd)
.then(handleVariationInfo);
cr.sendWithPromise('requestPluginInfo').then(handlePluginInfo);
cr.sendWithPromise('requestPathInfo').then(handlePathInfo);
if (cr.isChromeOS) { if (cr.isChromeOS) {
$('arc_holder').hidden = true; $('arc_holder').hidden = true;
chrome.chromeosInfoPrivate.get(['customizationId'], returnCustomizationId); chrome.chromeosInfoPrivate.get(['customizationId'], returnCustomizationId);
......
...@@ -12,10 +12,15 @@ const char kVersionJS[] = "version.js"; ...@@ -12,10 +12,15 @@ const char kVersionJS[] = "version.js";
// Message handlers. // Message handlers.
const char kRequestVersionInfo[] = "requestVersionInfo"; const char kRequestVersionInfo[] = "requestVersionInfo";
const char kReturnFilePaths[] = "returnFilePaths"; const char kRequestVariationInfo[] = "requestVariationInfo";
const char kReturnFlashVersion[] = "returnFlashVersion"; const char kRequestPluginInfo[] = "requestPluginInfo";
const char kReturnVariationInfo[] = "returnVariationInfo"; const char kRequestPathInfo[] = "requestPathInfo";
const char kReturnVariationCmd[] = "returnVariationCmd";
// Named keys used in message handler responses.
const char kKeyVariationsList[] = "variationsList";
const char kKeyVariationsCmd[] = "variationsCmd";
const char kKeyExecPath[] = "execPath";
const char kKeyProfilePath[] = "profilePath";
// Strings. // Strings.
const char kApplicationLabel[] = "application_label"; const char kApplicationLabel[] = "application_label";
...@@ -75,7 +80,6 @@ const char kUserAgent[] = "useragent"; ...@@ -75,7 +80,6 @@ const char kUserAgent[] = "useragent";
const char kUserAgentName[] = "user_agent_name"; const char kUserAgentName[] = "user_agent_name";
const char kVariationsCmdName[] = "variations_cmd_name"; const char kVariationsCmdName[] = "variations_cmd_name";
const char kVariationsName[] = "variations_name"; const char kVariationsName[] = "variations_name";
const char kVariationsShowCmdQuery[] = "show-variations-cmd";
const char kVersion[] = "version"; const char kVersion[] = "version";
const char kVersionBitSize[] = "version_bitsize"; const char kVersionBitSize[] = "version_bitsize";
const char kVersionModifier[] = "version_modifier"; const char kVersionModifier[] = "version_modifier";
......
...@@ -17,10 +17,14 @@ extern const char kVersionJS[]; ...@@ -17,10 +17,14 @@ extern const char kVersionJS[];
// Message handlers. // Message handlers.
// Must match the constants used in the resource files. // Must match the constants used in the resource files.
extern const char kRequestVersionInfo[]; extern const char kRequestVersionInfo[];
extern const char kReturnFilePaths[]; extern const char kRequestVariationInfo[];
extern const char kReturnFlashVersion[]; extern const char kRequestPluginInfo[];
extern const char kReturnVariationInfo[]; extern const char kRequestPathInfo[];
extern const char kReturnVariationCmd[];
extern const char kKeyVariationsList[];
extern const char kKeyVariationsCmd[];
extern const char kKeyExecPath[];
extern const char kKeyProfilePath[];
// Strings. // Strings.
// Must match the constants used in the resource files. // Must match the constants used in the resource files.
...@@ -81,7 +85,6 @@ extern const char kUserAgent[]; ...@@ -81,7 +85,6 @@ extern const char kUserAgent[];
extern const char kUserAgentName[]; extern const char kUserAgentName[];
extern const char kVariationsCmdName[]; extern const char kVariationsCmdName[];
extern const char kVariationsName[]; extern const char kVariationsName[];
extern const char kVariationsShowCmdQuery[];
extern const char kVersion[]; extern const char kVersion[];
extern const char kVersionBitSize[]; extern const char kVersionBitSize[];
extern const char kVersionModifier[]; extern const char kVersionModifier[];
......
...@@ -18,14 +18,19 @@ VersionHandler::~VersionHandler() {} ...@@ -18,14 +18,19 @@ VersionHandler::~VersionHandler() {}
void VersionHandler::RegisterMessages() { void VersionHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback( web_ui()->RegisterMessageCallback(
version_ui::kRequestVersionInfo, version_ui::kRequestVariationInfo,
base::BindRepeating(&VersionHandler::HandleRequestVersionInfo, base::BindRepeating(&VersionHandler::HandleRequestVariationInfo,
base::Unretained(this))); base::Unretained(this)));
} }
void VersionHandler::HandleRequestVersionInfo(const base::ListValue* args) { void VersionHandler::HandleRequestVariationInfo(const base::ListValue* args) {
// Respond with the variations info immediately. // Respond with the variations info immediately.
base::Value variations_list = version_ui::GetVariationsList()->Clone(); std::string callback_id;
std::vector<const base::Value*> params{&variations_list}; CHECK_EQ(2U, args->GetSize());
web_ui()->CallJavascriptFunction(version_ui::kReturnVariationInfo, params); CHECK(args->GetString(0, &callback_id));
base::Value response(base::Value::Type::DICTIONARY);
response.SetKey(version_ui::kKeyVariationsList,
std::move(*version_ui::GetVariationsList()));
web_ui()->ResolveJavascriptCallback(base::Value(callback_id), response);
} }
...@@ -21,9 +21,9 @@ class VersionHandler : public web::WebUIIOSMessageHandler { ...@@ -21,9 +21,9 @@ class VersionHandler : public web::WebUIIOSMessageHandler {
// content::WebUIMessageHandler implementation. // content::WebUIMessageHandler implementation.
void RegisterMessages() override; void RegisterMessages() override;
// Callback for the "requestVersionInfo" message. This asynchronously requests // Callback for the "requestVariationInfo" message. This responds immediately
// the list of variations. // with the list of variations.
void HandleRequestVersionInfo(const base::ListValue* args); void HandleRequestVariationInfo(const base::ListValue* args);
private: private:
DISALLOW_COPY_AND_ASSIGN(VersionHandler); DISALLOW_COPY_AND_ASSIGN(VersionHandler);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment