Commit dd37c53e authored by Anand K. Mistry's avatar Anand K. Mistry Committed by Commit Bot

Introduce LoggedUIThreadExtensionFunction to help migrate to UIThreadExtensionFunction.

Some fileManagerPrivate APIs use a subclass of
ChromeAsyncExtensionFunction to time and log long-running API calls. To
help migrate off ChromeAsyncExtensionFunction, create another subclass
that inherits from UIThreadExtensionFunction directly.

BUG=934541

Change-Id: I1e715ca6a063ac186f73d45ce1eaa1fbf9825263
Reviewed-on: https://chromium-review.googlesource.com/c/1481131
Commit-Queue: Anand Mistry <amistry@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#634447}
parent 7ca448c7
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h" #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
#include "chrome/browser/extensions/chrome_extension_function_details.h"
#include "components/drive/event_logger.h" #include "components/drive/event_logger.h"
namespace extensions { namespace extensions {
...@@ -43,4 +44,32 @@ void LoggedAsyncExtensionFunction::OnResponded() { ...@@ -43,4 +44,32 @@ void LoggedAsyncExtensionFunction::OnResponded() {
ChromeAsyncExtensionFunction::OnResponded(); ChromeAsyncExtensionFunction::OnResponded();
} }
LoggedUIThreadExtensionFunction::LoggedUIThreadExtensionFunction()
: log_on_completion_(false) {
start_time_ = base::Time::Now();
}
LoggedUIThreadExtensionFunction::~LoggedUIThreadExtensionFunction() = default;
void LoggedUIThreadExtensionFunction::OnResponded() {
const ChromeExtensionFunctionDetails chrome_details(this);
drive::EventLogger* logger =
file_manager::util::GetLogger(chrome_details.GetProfile());
if (logger) {
int64_t elapsed = (base::Time::Now() - start_time_).InMilliseconds();
DCHECK(response_type());
bool success = *response_type() == SUCCEEDED;
if (log_on_completion_) {
logger->Log(logging::LOG_INFO, "%s[%d] %s. (elapsed time: %sms)", name(),
request_id(), success ? "succeeded" : "failed",
base::NumberToString(elapsed).c_str());
} else if (elapsed >= kSlowOperationThresholdMs) {
logger->Log(logging::LOG_WARNING,
"PEFORMANCE WARNING: %s[%d] was slow. (elapsed time: %sms)",
name(), request_id(), base::NumberToString(elapsed).c_str());
}
}
UIThreadExtensionFunction::OnResponded();
}
} // namespace extensions } // namespace extensions
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/extensions/chrome_extension_function.h"
#include "extensions/browser/extension_function.h"
namespace extensions { namespace extensions {
...@@ -20,6 +21,8 @@ namespace extensions { ...@@ -20,6 +21,8 @@ namespace extensions {
// set_log_on_completion(true) to enable it, if they want. However, even if // set_log_on_completion(true) to enable it, if they want. However, even if
// the logging is turned off, a warning is emitted when a function call is // the logging is turned off, a warning is emitted when a function call is
// very slow. See the implementation of OnResponded() for details. // very slow. See the implementation of OnResponded() for details.
// TODO(crbug.com/934541): Remove this once all extension functions have been
// migrated to LoggedUIThreadExtensionFunction.
class LoggedAsyncExtensionFunction : public ChromeAsyncExtensionFunction { class LoggedAsyncExtensionFunction : public ChromeAsyncExtensionFunction {
public: public:
LoggedAsyncExtensionFunction(); LoggedAsyncExtensionFunction();
...@@ -40,6 +43,28 @@ class LoggedAsyncExtensionFunction : public ChromeAsyncExtensionFunction { ...@@ -40,6 +43,28 @@ class LoggedAsyncExtensionFunction : public ChromeAsyncExtensionFunction {
bool log_on_completion_; bool log_on_completion_;
}; };
// This is the same class as above, but inheriting directly from
// UIThreadExtensionFunction instead.
class LoggedUIThreadExtensionFunction : public UIThreadExtensionFunction {
public:
LoggedUIThreadExtensionFunction();
protected:
~LoggedUIThreadExtensionFunction() override;
// UIThreadExtensionFunction overrides.
void OnResponded() override;
// Sets the logging on completion flag. By default, logging is turned off.
void set_log_on_completion(bool log_on_completion) {
log_on_completion_ = log_on_completion;
}
private:
base::Time start_time_;
bool log_on_completion_;
};
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_BASE_H_ #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_BASE_H_
...@@ -67,7 +67,12 @@ std::set<std::string> GetUniqueMimeTypes( ...@@ -67,7 +67,12 @@ std::set<std::string> GetUniqueMimeTypes(
} // namespace } // namespace
bool FileManagerPrivateInternalExecuteTaskFunction::RunAsync() { FileManagerPrivateInternalExecuteTaskFunction::
FileManagerPrivateInternalExecuteTaskFunction()
: chrome_details_(this) {}
ExtensionFunction::ResponseAction
FileManagerPrivateInternalExecuteTaskFunction::Run() {
using extensions::api::file_manager_private_internal::ExecuteTask::Params; using extensions::api::file_manager_private_internal::ExecuteTask::Params;
using extensions::api::file_manager_private_internal::ExecuteTask::Results:: using extensions::api::file_manager_private_internal::ExecuteTask::Results::
Create; Create;
...@@ -76,73 +81,76 @@ bool FileManagerPrivateInternalExecuteTaskFunction::RunAsync() { ...@@ -76,73 +81,76 @@ bool FileManagerPrivateInternalExecuteTaskFunction::RunAsync() {
file_manager::file_tasks::TaskDescriptor task; file_manager::file_tasks::TaskDescriptor task;
if (!file_manager::file_tasks::ParseTaskID(params->task_id, &task)) { if (!file_manager::file_tasks::ParseTaskID(params->task_id, &task)) {
SetError(kInvalidTask + params->task_id); // TODO(crbug.com/514135): Stop relying on the result being set on error.
SetResultList( return RespondNow(ErrorWithArguments(
Create(extensions::api::file_manager_private::TASK_RESULT_FAILED)); Create(extensions::api::file_manager_private::TASK_RESULT_FAILED),
return false; kInvalidTask + params->task_id));
} }
if (params->urls.empty()) { if (params->urls.empty()) {
SetResultList( return RespondNow(ArgumentList(
Create(extensions::api::file_manager_private::TASK_RESULT_EMPTY)); Create(extensions::api::file_manager_private::TASK_RESULT_EMPTY)));
SendResponse(true);
return true;
} }
const scoped_refptr<storage::FileSystemContext> file_system_context = const scoped_refptr<storage::FileSystemContext> file_system_context =
file_manager::util::GetFileSystemContextForRenderFrameHost( file_manager::util::GetFileSystemContextForRenderFrameHost(
GetProfile(), render_frame_host()); chrome_details_.GetProfile(), render_frame_host());
std::vector<FileSystemURL> urls; std::vector<FileSystemURL> urls;
for (size_t i = 0; i < params->urls.size(); i++) { for (size_t i = 0; i < params->urls.size(); i++) {
const FileSystemURL url = const FileSystemURL url =
file_system_context->CrackURL(GURL(params->urls[i])); file_system_context->CrackURL(GURL(params->urls[i]));
if (!chromeos::FileSystemBackend::CanHandleURL(url)) { if (!chromeos::FileSystemBackend::CanHandleURL(url)) {
SetError(kInvalidFileUrl); return RespondNow(ErrorWithArguments(
SetResultList( Create(extensions::api::file_manager_private::TASK_RESULT_FAILED),
Create(extensions::api::file_manager_private::TASK_RESULT_FAILED)); kInvalidFileUrl));
return false;
} }
urls.push_back(url); urls.push_back(url);
} }
const bool result = file_manager::file_tasks::ExecuteFileTask( const bool result = file_manager::file_tasks::ExecuteFileTask(
GetProfile(), source_url(), task, urls, chrome_details_.GetProfile(), source_url(), task, urls,
base::BindOnce( base::BindOnce(
&FileManagerPrivateInternalExecuteTaskFunction::OnTaskExecuted, &FileManagerPrivateInternalExecuteTaskFunction::OnTaskExecuted,
this)); this));
if (!result) { if (!result) {
SetResultList( return RespondNow(ErrorWithArguments(
Create(extensions::api::file_manager_private::TASK_RESULT_FAILED)); Create(extensions::api::file_manager_private::TASK_RESULT_FAILED),
"ExecuteFileTask failed"));
} }
return result; return RespondLater();
} }
void FileManagerPrivateInternalExecuteTaskFunction::OnTaskExecuted( void FileManagerPrivateInternalExecuteTaskFunction::OnTaskExecuted(
extensions::api::file_manager_private::TaskResult result) { extensions::api::file_manager_private::TaskResult result) {
SetResultList(extensions::api::file_manager_private_internal::ExecuteTask:: auto result_list = extensions::api::file_manager_private_internal::
Results::Create(result)); ExecuteTask::Results::Create(result);
SendResponse(result != if (result == extensions::api::file_manager_private::TASK_RESULT_FAILED) {
extensions::api::file_manager_private::TASK_RESULT_FAILED); Respond(ErrorWithArguments(std::move(result_list), "Task result failed"));
} else {
Respond(ArgumentList(std::move(result_list)));
}
} }
FileManagerPrivateInternalGetFileTasksFunction:: FileManagerPrivateInternalGetFileTasksFunction::
FileManagerPrivateInternalGetFileTasksFunction() = default; FileManagerPrivateInternalGetFileTasksFunction()
: chrome_details_(this) {}
FileManagerPrivateInternalGetFileTasksFunction:: FileManagerPrivateInternalGetFileTasksFunction::
~FileManagerPrivateInternalGetFileTasksFunction() = default; ~FileManagerPrivateInternalGetFileTasksFunction() = default;
bool FileManagerPrivateInternalGetFileTasksFunction::RunAsync() { ExtensionFunction::ResponseAction
FileManagerPrivateInternalGetFileTasksFunction::Run() {
using extensions::api::file_manager_private_internal::GetFileTasks::Params; using extensions::api::file_manager_private_internal::GetFileTasks::Params;
const std::unique_ptr<Params> params(Params::Create(*args_)); const std::unique_ptr<Params> params(Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(params);
if (params->urls.empty()) if (params->urls.empty())
return false; return RespondNow(Error("No URLs provided"));
const scoped_refptr<storage::FileSystemContext> file_system_context = const scoped_refptr<storage::FileSystemContext> file_system_context =
file_manager::util::GetFileSystemContextForRenderFrameHost( file_manager::util::GetFileSystemContextForRenderFrameHost(
GetProfile(), render_frame_host()); chrome_details_.GetProfile(), render_frame_host());
// Collect all the URLs, convert them to GURLs, and crack all the urls into // Collect all the URLs, convert them to GURLs, and crack all the urls into
// file paths. // file paths.
...@@ -156,21 +164,22 @@ bool FileManagerPrivateInternalGetFileTasksFunction::RunAsync() { ...@@ -156,21 +164,22 @@ bool FileManagerPrivateInternalGetFileTasksFunction::RunAsync() {
} }
mime_type_collector_ = mime_type_collector_ =
std::make_unique<app_file_handler_util::MimeTypeCollector>(GetProfile()); std::make_unique<app_file_handler_util::MimeTypeCollector>(
chrome_details_.GetProfile());
mime_type_collector_->CollectForLocalPaths( mime_type_collector_->CollectForLocalPaths(
local_paths_, local_paths_,
base::Bind( base::Bind(
&FileManagerPrivateInternalGetFileTasksFunction::OnMimeTypesCollected, &FileManagerPrivateInternalGetFileTasksFunction::OnMimeTypesCollected,
this)); this));
return true; return RespondLater();
} }
void FileManagerPrivateInternalGetFileTasksFunction::OnMimeTypesCollected( void FileManagerPrivateInternalGetFileTasksFunction::OnMimeTypesCollected(
std::unique_ptr<std::vector<std::string>> mime_types) { std::unique_ptr<std::vector<std::string>> mime_types) {
is_directory_collector_ = is_directory_collector_ =
std::make_unique<app_file_handler_util::IsDirectoryCollector>( std::make_unique<app_file_handler_util::IsDirectoryCollector>(
GetProfile()); chrome_details_.GetProfile());
is_directory_collector_->CollectForEntriesPaths( is_directory_collector_->CollectForEntriesPaths(
local_paths_, base::Bind(&FileManagerPrivateInternalGetFileTasksFunction:: local_paths_, base::Bind(&FileManagerPrivateInternalGetFileTasksFunction::
OnAreDirectoriesAndMimeTypesCollected, OnAreDirectoriesAndMimeTypesCollected,
...@@ -189,7 +198,7 @@ void FileManagerPrivateInternalGetFileTasksFunction:: ...@@ -189,7 +198,7 @@ void FileManagerPrivateInternalGetFileTasksFunction::
} }
file_manager::file_tasks::FindAllTypesOfTasks( file_manager::file_tasks::FindAllTypesOfTasks(
GetProfile(), entries, urls_, chrome_details_.GetProfile(), entries, urls_,
base::BindOnce( base::BindOnce(
&FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed, &FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed,
this)); this));
...@@ -214,9 +223,8 @@ void FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed( ...@@ -214,9 +223,8 @@ void FileManagerPrivateInternalGetFileTasksFunction::OnFileTasksListed(
results.push_back(std::move(converted)); results.push_back(std::move(converted));
} }
SetResultList(extensions::api::file_manager_private_internal::GetFileTasks:: Respond(ArgumentList(extensions::api::file_manager_private_internal::
Results::Create(results)); GetFileTasks::Results::Create(results)));
SendResponse(true);
} }
ExtensionFunction::ResponseAction ExtensionFunction::ResponseAction
......
...@@ -28,25 +28,29 @@ class MimeTypeCollector; ...@@ -28,25 +28,29 @@ class MimeTypeCollector;
// Implements the chrome.fileManagerPrivateInternal.executeTask method. // Implements the chrome.fileManagerPrivateInternal.executeTask method.
class FileManagerPrivateInternalExecuteTaskFunction class FileManagerPrivateInternalExecuteTaskFunction
: public LoggedAsyncExtensionFunction { : public LoggedUIThreadExtensionFunction {
public: public:
FileManagerPrivateInternalExecuteTaskFunction();
DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.executeTask", DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.executeTask",
FILEMANAGERPRIVATEINTERNAL_EXECUTETASK) FILEMANAGERPRIVATEINTERNAL_EXECUTETASK)
protected: protected:
~FileManagerPrivateInternalExecuteTaskFunction() override = default; ~FileManagerPrivateInternalExecuteTaskFunction() override = default;
// ChromeAsyncExtensionFunction overrides. // UIThreadExtensionFunction overrides.
bool RunAsync() override; ResponseAction Run() override;
private: private:
void OnTaskExecuted( void OnTaskExecuted(
extensions::api::file_manager_private::TaskResult success); extensions::api::file_manager_private::TaskResult success);
const ChromeExtensionFunctionDetails chrome_details_;
}; };
// Implements the chrome.fileManagerPrivateInternal.getFileTasks method. // Implements the chrome.fileManagerPrivateInternal.getFileTasks method.
class FileManagerPrivateInternalGetFileTasksFunction class FileManagerPrivateInternalGetFileTasksFunction
: public LoggedAsyncExtensionFunction { : public LoggedUIThreadExtensionFunction {
public: public:
FileManagerPrivateInternalGetFileTasksFunction(); FileManagerPrivateInternalGetFileTasksFunction();
...@@ -56,8 +60,8 @@ class FileManagerPrivateInternalGetFileTasksFunction ...@@ -56,8 +60,8 @@ class FileManagerPrivateInternalGetFileTasksFunction
protected: protected:
~FileManagerPrivateInternalGetFileTasksFunction() override; ~FileManagerPrivateInternalGetFileTasksFunction() override;
// ChromeAsyncExtensionFunction overrides. // UIThreadExtensionFunction overrides.
bool RunAsync() override; ResponseAction Run() override;
private: private:
void OnMimeTypesCollected( void OnMimeTypesCollected(
...@@ -77,6 +81,7 @@ class FileManagerPrivateInternalGetFileTasksFunction ...@@ -77,6 +81,7 @@ class FileManagerPrivateInternalGetFileTasksFunction
mime_type_collector_; mime_type_collector_;
std::vector<GURL> urls_; std::vector<GURL> urls_;
std::vector<base::FilePath> local_paths_; std::vector<base::FilePath> local_paths_;
const ChromeExtensionFunctionDetails chrome_details_;
}; };
// Implements the chrome.fileManagerPrivateInternal.setDefaultTask method. // Implements the chrome.fileManagerPrivateInternal.setDefaultTask method.
......
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