From 6a3922d330608b20445899a53af46b25b3033212 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Thu, 22 Aug 2019 17:03:28 -0700 Subject: [PATCH] refactor: make util::Promise type safe when chaining in native (#19809) * refactor: make util::Promise type safe when chaining in native * fixup! refactor: make util::Promise type safe when chaining in native * chore: remove spare brackets --- shell/browser/api/atom_api_app.cc | 6 +- shell/browser/api/atom_api_content_tracing.cc | 27 ++-- shell/browser/api/atom_api_cookies.cc | 22 +-- shell/browser/api/atom_api_debugger.cc | 5 +- shell/browser/api/atom_api_debugger.h | 3 +- shell/browser/api/atom_api_dialog.cc | 10 +- shell/browser/api/atom_api_in_app_purchase.cc | 14 +- shell/browser/api/atom_api_net_log.cc | 8 +- shell/browser/api/atom_api_net_log.h | 2 +- shell/browser/api/atom_api_protocol_ns.cc | 23 ++- shell/browser/api/atom_api_session.cc | 61 +++---- .../api/atom_api_system_preferences_mac.mm | 16 +- shell/browser/api/atom_api_web_contents.cc | 15 +- shell/browser/api/gpuinfo_manager.cc | 9 +- shell/browser/api/gpuinfo_manager.h | 8 +- shell/browser/api/save_page_handler.cc | 2 +- shell/browser/api/save_page_handler.h | 4 +- shell/browser/atom_blob_reader.cc | 10 +- shell/browser/atom_blob_reader.h | 3 +- .../browser/atom_download_manager_delegate.cc | 2 +- shell/browser/browser.cc | 4 +- shell/browser/browser.h | 4 +- shell/browser/browser_mac.mm | 4 +- .../printing/print_preview_message_handler.cc | 11 +- .../printing/print_preview_message_handler.h | 8 +- shell/browser/ui/certificate_trust_mac.mm | 10 +- shell/browser/ui/certificate_trust_win.cc | 2 +- shell/browser/ui/file_dialog.h | 4 +- shell/browser/ui/file_dialog_gtk.cc | 22 +-- shell/browser/ui/file_dialog_mac.mm | 18 +-- shell/browser/ui/file_dialog_win.cc | 30 ++-- shell/browser/web_dialog_helper.cc | 4 +- shell/common/api/atom_api_shell.cc | 4 +- shell/common/api/electron_bindings.cc | 6 +- shell/common/api/electron_bindings.h | 2 +- shell/common/promise_util.cc | 70 ++------ shell/common/promise_util.h | 152 +++++++----------- shell/renderer/api/atom_api_renderer_ipc.cc | 4 +- shell/renderer/api/atom_api_web_frame.cc | 9 +- 39 files changed, 275 insertions(+), 343 deletions(-) diff --git a/shell/browser/api/atom_api_app.cc b/shell/browser/api/atom_api_app.cc index 062631e89b..f20818729d 100644 --- a/shell/browser/api/atom_api_app.cc +++ b/shell/browser/api/atom_api_app.cc @@ -532,7 +532,7 @@ int ImportIntoCertStore(CertificateManagerModel* model, } #endif -void OnIconDataAvailable(util::Promise promise, gfx::Image icon) { +void OnIconDataAvailable(util::Promise promise, gfx::Image icon) { if (!icon.IsEmpty()) { promise.Resolve(icon); } else { @@ -1167,7 +1167,7 @@ JumpListResult App::SetJumpList(v8::Local val, v8::Local App::GetFileIcon(const base::FilePath& path, mate::Arguments* args) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); base::FilePath normalized_path = path.NormalizePathSeparators(); @@ -1272,7 +1272,7 @@ v8::Local App::GetGPUFeatureStatus(v8::Isolate* isolate) { v8::Local App::GetGPUInfo(v8::Isolate* isolate, const std::string& info_type) { auto* const gpu_data_manager = content::GpuDataManagerImpl::GetInstance(); - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); if (info_type != "basic" && info_type != "complete") { promise.RejectWithErrorMessage( diff --git a/shell/browser/api/atom_api_content_tracing.cc b/shell/browser/api/atom_api_content_tracing.cc index 62f603de04..b2c3ffef21 100644 --- a/shell/browser/api/atom_api_content_tracing.cc +++ b/shell/browser/api/atom_api_content_tracing.cc @@ -64,13 +64,13 @@ base::Optional CreateTemporaryFileOnIO() { return base::make_optional(std::move(temp_file_path)); } -void StopTracing(electron::util::Promise promise, +void StopTracing(electron::util::Promise promise, base::Optional file_path) { if (file_path) { auto endpoint = TracingController::CreateFileEndpoint( *file_path, base::AdaptCallbackForRepeating(base::BindOnce( - &electron::util::Promise::ResolvePromise, + &electron::util::Promise::ResolvePromise, std::move(promise), *file_path))); TracingController::GetInstance()->StopTracing(endpoint); } else { @@ -80,7 +80,7 @@ void StopTracing(electron::util::Promise promise, } v8::Local StopRecording(mate::Arguments* args) { - electron::util::Promise promise(args->isolate()); + electron::util::Promise promise(args->isolate()); v8::Local handle = promise.GetHandle(); base::FilePath path; @@ -98,12 +98,12 @@ v8::Local StopRecording(mate::Arguments* args) { } v8::Local GetCategories(v8::Isolate* isolate) { - electron::util::Promise promise(isolate); + electron::util::Promise&> promise(isolate); v8::Local handle = promise.GetHandle(); // Note: This method always succeeds. TracingController::GetInstance()->GetCategories(base::BindOnce( - electron::util::Promise::ResolvePromise&>, + electron::util::Promise&>::ResolvePromise, std::move(promise))); return handle; @@ -112,34 +112,35 @@ v8::Local GetCategories(v8::Isolate* isolate) { v8::Local StartTracing( v8::Isolate* isolate, const base::trace_event::TraceConfig& trace_config) { - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); if (!TracingController::GetInstance()->StartTracing( trace_config, - base::BindOnce(electron::util::Promise::ResolveEmptyPromise, + base::BindOnce(electron::util::Promise::ResolveEmptyPromise, std::move(promise)))) { // If StartTracing returns false, that means it didn't invoke its callback. // Return an already-resolved promise and abandon the previous promise (it // was std::move()d into the StartTracing callback and has been deleted by // this point). - return electron::util::Promise::ResolvedPromise(isolate); + return electron::util::Promise::ResolvedPromise(isolate); } return handle; } -void OnTraceBufferUsageAvailable(electron::util::Promise promise, - float percent_full, - size_t approximate_count) { +void OnTraceBufferUsageAvailable( + electron::util::Promise promise, + float percent_full, + size_t approximate_count) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); dict.Set("percentage", percent_full); dict.Set("value", approximate_count); - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } v8::Local GetTraceBufferUsage(v8::Isolate* isolate) { - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); // Note: This method always succeeds. diff --git a/shell/browser/api/atom_api_cookies.cc b/shell/browser/api/atom_api_cookies.cc index 5a88b59b5b..74ddaa31cd 100644 --- a/shell/browser/api/atom_api_cookies.cc +++ b/shell/browser/api/atom_api_cookies.cc @@ -121,7 +121,7 @@ bool MatchesCookie(const base::Value& filter, // Remove cookies from |list| not matching |filter|, and pass it to |callback|. void FilterCookies(const base::Value& filter, - util::Promise promise, + util::Promise promise, const net::CookieList& list, const net::CookieStatusList& excluded_list) { net::CookieList result; @@ -130,7 +130,7 @@ void FilterCookies(const base::Value& filter, result.push_back(cookie); } - promise.Resolve(gin::ConvertToV8(promise.isolate(), result)); + promise.ResolveWithGin(result); } std::string InclusionStatusToString( @@ -170,7 +170,7 @@ Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context) Cookies::~Cookies() {} v8::Local Cookies::Get(const base::DictionaryValue& filter) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); std::string url_string; @@ -206,7 +206,7 @@ v8::Local Cookies::Get(const base::DictionaryValue& filter) { v8::Local Cookies::Remove(const GURL& url, const std::string& name) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); auto cookie_deletion_filter = network::mojom::CookieDeletionFilter::New(); @@ -220,8 +220,8 @@ v8::Local Cookies::Remove(const GURL& url, manager->DeleteCookies( std::move(cookie_deletion_filter), base::BindOnce( - [](util::Promise promise, uint32_t num_deleted) { - util::Promise::ResolveEmptyPromise(std::move(promise)); + [](util::Promise promise, uint32_t num_deleted) { + util::Promise::ResolveEmptyPromise(std::move(promise)); }, std::move(promise))); @@ -229,7 +229,7 @@ v8::Local Cookies::Remove(const GURL& url, } v8::Local Cookies::Set(const base::DictionaryValue& details) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); const std::string* url_string = details.FindStringKey("url"); @@ -288,7 +288,7 @@ v8::Local Cookies::Set(const base::DictionaryValue& details) { manager->SetCanonicalCookie( *canonical_cookie, url.scheme(), options, base::BindOnce( - [](util::Promise promise, + [](util::Promise promise, net::CanonicalCookie::CookieInclusionStatus status) { auto errmsg = InclusionStatusToString(status); if (errmsg.empty()) { @@ -303,15 +303,15 @@ v8::Local Cookies::Set(const base::DictionaryValue& details) { } v8::Local Cookies::FlushStore() { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); auto* storage_partition = content::BrowserContext::GetDefaultStoragePartition( browser_context_.get()); auto* manager = storage_partition->GetCookieManagerForBrowserProcess(); - manager->FlushCookieStore( - base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise))); + manager->FlushCookieStore(base::BindOnce( + util::Promise::ResolveEmptyPromise, std::move(promise))); return handle; } diff --git a/shell/browser/api/atom_api_debugger.cc b/shell/browser/api/atom_api_debugger.cc index e8f3d4fdef..cd612329ee 100644 --- a/shell/browser/api/atom_api_debugger.cc +++ b/shell/browser/api/atom_api_debugger.cc @@ -65,7 +65,8 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, if (it == pending_requests_.end()) return; - electron::util::Promise promise = std::move(it->second); + electron::util::Promise promise = + std::move(it->second); pending_requests_.erase(it); base::DictionaryValue* error = nullptr; @@ -129,7 +130,7 @@ void Debugger::Detach() { } v8::Local Debugger::SendCommand(mate::Arguments* args) { - electron::util::Promise promise(isolate()); + electron::util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); if (!agent_host_) { diff --git a/shell/browser/api/atom_api_debugger.h b/shell/browser/api/atom_api_debugger.h index 1d921cf2cb..4bf882ea2c 100644 --- a/shell/browser/api/atom_api_debugger.h +++ b/shell/browser/api/atom_api_debugger.h @@ -54,7 +54,8 @@ class Debugger : public mate::TrackableObject, content::RenderFrameHost* new_rfh) override; private: - using PendingRequestMap = std::map; + using PendingRequestMap = + std::map>; void Attach(mate::Arguments* args); bool IsAttached(); diff --git a/shell/browser/api/atom_api_dialog.cc b/shell/browser/api/atom_api_dialog.cc index 6c3a194936..ee8c668639 100644 --- a/shell/browser/api/atom_api_dialog.cc +++ b/shell/browser/api/atom_api_dialog.cc @@ -24,7 +24,7 @@ int ShowMessageBoxSync(const electron::MessageBoxSettings& settings) { return electron::ShowMessageBoxSync(settings); } -void ResolvePromiseObject(electron::util::Promise promise, +void ResolvePromiseObject(electron::util::Promise promise, int result, bool checkbox_checked) { v8::Isolate* isolate = promise.isolate(); @@ -33,14 +33,14 @@ void ResolvePromiseObject(electron::util::Promise promise, dict.Set("response", result); dict.Set("checkboxChecked", checkbox_checked); - promise.Resolve(gin::ConvertToV8(isolate, dict)); + promise.ResolveWithGin(dict); } v8::Local ShowMessageBox( const electron::MessageBoxSettings& settings, gin::Arguments* args) { v8::Isolate* isolate = args->isolate(); - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); electron::ShowMessageBox( @@ -59,7 +59,7 @@ void ShowOpenDialogSync(const file_dialog::DialogSettings& settings, v8::Local ShowOpenDialog( const file_dialog::DialogSettings& settings, gin::Arguments* args) { - electron::util::Promise promise(args->isolate()); + electron::util::Promise promise(args->isolate()); v8::Local handle = promise.GetHandle(); file_dialog::ShowOpenDialog(settings, std::move(promise)); return handle; @@ -75,7 +75,7 @@ void ShowSaveDialogSync(const file_dialog::DialogSettings& settings, v8::Local ShowSaveDialog( const file_dialog::DialogSettings& settings, gin::Arguments* args) { - electron::util::Promise promise(args->isolate()); + electron::util::Promise promise(args->isolate()); v8::Local handle = promise.GetHandle(); file_dialog::ShowSaveDialog(settings, std::move(promise)); diff --git a/shell/browser/api/atom_api_in_app_purchase.cc b/shell/browser/api/atom_api_in_app_purchase.cc index 914a1bb722..a90dc00252 100644 --- a/shell/browser/api/atom_api_in_app_purchase.cc +++ b/shell/browser/api/atom_api_in_app_purchase.cc @@ -104,7 +104,7 @@ v8::Local InAppPurchase::PurchaseProduct( const std::string& product_id, mate::Arguments* args) { v8::Isolate* isolate = args->isolate(); - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); int quantity = 1; @@ -112,7 +112,7 @@ v8::Local InAppPurchase::PurchaseProduct( in_app_purchase::PurchaseProduct( product_id, quantity, - base::BindOnce(electron::util::Promise::ResolvePromise, + base::BindOnce(electron::util::Promise::ResolvePromise, std::move(promise))); return handle; @@ -122,13 +122,15 @@ v8::Local InAppPurchase::GetProducts( const std::vector& productIDs, mate::Arguments* args) { v8::Isolate* isolate = args->isolate(); - electron::util::Promise promise(isolate); + electron::util::Promise> promise( + isolate); v8::Local handle = promise.GetHandle(); in_app_purchase::GetProducts( - productIDs, base::BindOnce(electron::util::Promise::ResolvePromise< - std::vector>, - std::move(promise))); + productIDs, + base::BindOnce(electron::util::Promise< + std::vector>::ResolvePromise, + std::move(promise))); return handle; } diff --git a/shell/browser/api/atom_api_net_log.cc b/shell/browser/api/atom_api_net_log.cc index b5d7191b70..77b10e22ff 100644 --- a/shell/browser/api/atom_api_net_log.cc +++ b/shell/browser/api/atom_api_net_log.cc @@ -64,7 +64,7 @@ base::File OpenFileForWriting(base::FilePath path) { base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); } -void ResolvePromiseWithNetError(util::Promise promise, int32_t error) { +void ResolvePromiseWithNetError(util::Promise promise, int32_t error) { if (error == net::OK) { promise.Resolve(); } else { @@ -119,7 +119,7 @@ v8::Local NetLog::StartLogging(base::FilePath log_path, return v8::Local(); } - pending_start_promise_ = base::make_optional(isolate()); + pending_start_promise_ = base::make_optional>(isolate()); v8::Local handle = pending_start_promise_->GetHandle(); auto command_line_string = @@ -189,7 +189,7 @@ bool NetLog::IsCurrentlyLogging() const { } v8::Local NetLog::StopLogging(mate::Arguments* args) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); if (net_log_exporter_) { @@ -199,7 +199,7 @@ v8::Local NetLog::StopLogging(mate::Arguments* args) { net_log_exporter_->Stop( base::Value(base::Value::Type::DICTIONARY), base::BindOnce( - [](network::mojom::NetLogExporterPtr, util::Promise promise, + [](network::mojom::NetLogExporterPtr, util::Promise promise, int32_t error) { ResolvePromiseWithNetError(std::move(promise), error); }, diff --git a/shell/browser/api/atom_api_net_log.h b/shell/browser/api/atom_api_net_log.h index 421b65f5de..3618a3a6dd 100644 --- a/shell/browser/api/atom_api_net_log.h +++ b/shell/browser/api/atom_api_net_log.h @@ -53,7 +53,7 @@ class NetLog : public mate::TrackableObject { network::mojom::NetLogExporterPtr net_log_exporter_; - base::Optional pending_start_promise_; + base::Optional> pending_start_promise_; scoped_refptr file_task_runner_; diff --git a/shell/browser/api/atom_api_protocol_ns.cc b/shell/browser/api/atom_api_protocol_ns.cc index 54db403972..4a74fad386 100644 --- a/shell/browser/api/atom_api_protocol_ns.cc +++ b/shell/browser/api/atom_api_protocol_ns.cc @@ -232,18 +232,17 @@ v8::Local ProtocolNS::IsProtocolHandled(const std::string& scheme, "protocol.isProtocolRegistered or protocol.isProtocolIntercepted " "instead.", "ProtocolDeprecateIsProtocolHandled"); - util::Promise promise(isolate()); - promise.Resolve(IsProtocolRegistered(scheme) || - IsProtocolIntercepted(scheme) || - // The |isProtocolHandled| should return true for builtin - // schemes, however with NetworkService it is impossible to - // know which schemes are registered until a real network - // request is sent. - // So we have to test against a hard-coded builtin schemes - // list make it work with old code. We should deprecate this - // API with the new |isProtocolRegistered| API. - base::Contains(kBuiltinSchemes, scheme)); - return promise.GetHandle(); + return util::Promise::ResolvedPromise( + isolate(), IsProtocolRegistered(scheme) || + IsProtocolIntercepted(scheme) || + // The |isProtocolHandled| should return true for builtin + // schemes, however with NetworkService it is impossible to + // know which schemes are registered until a real network + // request is sent. + // So we have to test against a hard-coded builtin schemes + // list make it work with old code. We should deprecate + // this API with the new |isProtocolRegistered| API. + base::Contains(kBuiltinSchemes, scheme)); } void ProtocolNS::HandleOptionalCallback(mate::Arguments* args, diff --git a/shell/browser/api/atom_api_session.cc b/shell/browser/api/atom_api_session.cc index 19cae79881..d8339808e9 100644 --- a/shell/browser/api/atom_api_session.cc +++ b/shell/browser/api/atom_api_session.cc @@ -236,14 +236,14 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, v8::Local Session::ResolveProxy(mate::Arguments* args) { v8::Isolate* isolate = args->isolate(); - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); GURL url; args->GetNext(&url); browser_context_->GetResolveProxyHelper()->ResolveProxy( - url, base::BindOnce(util::Promise::ResolvePromise, + url, base::BindOnce(util::Promise::ResolvePromise, std::move(promise))); return handle; @@ -251,36 +251,37 @@ v8::Local Session::ResolveProxy(mate::Arguments* args) { v8::Local Session::GetCacheSize() { auto* isolate = v8::Isolate::GetCurrent(); - auto promise = util::Promise(isolate); + util::Promise promise(isolate); auto handle = promise.GetHandle(); content::BrowserContext::GetDefaultStoragePartition(browser_context_.get()) ->GetNetworkContext() - ->ComputeHttpCacheSize(base::Time(), base::Time::Max(), - base::BindOnce( - [](util::Promise promise, bool is_upper_bound, - int64_t size_or_error) { - if (size_or_error < 0) { - promise.RejectWithErrorMessage( - net::ErrorToString(size_or_error)); - } else { - promise.Resolve(size_or_error); - } - }, - std::move(promise))); + ->ComputeHttpCacheSize( + base::Time(), base::Time::Max(), + base::BindOnce( + [](util::Promise promise, bool is_upper_bound, + int64_t size_or_error) { + if (size_or_error < 0) { + promise.RejectWithErrorMessage( + net::ErrorToString(size_or_error)); + } else { + promise.Resolve(size_or_error); + } + }, + std::move(promise))); return handle; } v8::Local Session::ClearCache() { auto* isolate = v8::Isolate::GetCurrent(); - auto promise = util::Promise(isolate); + util::Promise promise(isolate); auto handle = promise.GetHandle(); content::BrowserContext::GetDefaultStoragePartition(browser_context_.get()) ->GetNetworkContext() ->ClearHttpCache(base::Time(), base::Time::Max(), nullptr, - base::BindOnce(util::Promise::ResolveEmptyPromise, + base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise))); return handle; @@ -288,7 +289,7 @@ v8::Local Session::ClearCache() { v8::Local Session::ClearStorageData(mate::Arguments* args) { v8::Isolate* isolate = args->isolate(); - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); ClearStorageDataOptions options; @@ -305,7 +306,8 @@ v8::Local Session::ClearStorageData(mate::Arguments* args) { storage_partition->ClearData( options.storage_types, options.quota_types, options.origin, base::Time(), base::Time::Max(), - base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise))); + base::BindOnce(util::Promise::ResolveEmptyPromise, + std::move(promise))); return handle; } @@ -317,7 +319,7 @@ void Session::FlushStorageData() { v8::Local Session::SetProxy(mate::Arguments* args) { v8::Isolate* isolate = args->isolate(); - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); mate::Dictionary options; @@ -350,8 +352,8 @@ v8::Local Session::SetProxy(mate::Arguments* args) { } base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise))); + FROM_HERE, base::BindOnce(util::Promise::ResolveEmptyPromise, + std::move(promise))); return handle; } @@ -449,13 +451,13 @@ void Session::SetPermissionCheckHandler(v8::Local val, v8::Local Session::ClearHostResolverCache(mate::Arguments* args) { v8::Isolate* isolate = args->isolate(); - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); content::BrowserContext::GetDefaultStoragePartition(browser_context_.get()) ->GetNetworkContext() ->ClearHostCache(nullptr, - base::BindOnce(util::Promise::ResolveEmptyPromise, + base::BindOnce(util::Promise::ResolveEmptyPromise, std::move(promise))); return handle; @@ -463,14 +465,15 @@ v8::Local Session::ClearHostResolverCache(mate::Arguments* args) { v8::Local Session::ClearAuthCache() { auto* isolate = v8::Isolate::GetCurrent(); - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); content::BrowserContext::GetDefaultStoragePartition(browser_context_.get()) ->GetNetworkContext() - ->ClearHttpAuthCache(base::Time(), - base::BindOnce(util::Promise::ResolveEmptyPromise, - std::move(promise))); + ->ClearHttpAuthCache( + base::Time(), + base::BindOnce(util::Promise::ResolveEmptyPromise, + std::move(promise))); return handle; } @@ -495,7 +498,7 @@ std::string Session::GetUserAgent() { v8::Local Session::GetBlobData(v8::Isolate* isolate, const std::string& uuid) { - util::Promise promise(isolate); + util::Promise> promise(isolate); v8::Local handle = promise.GetHandle(); AtomBlobReader* blob_reader = browser_context()->GetBlobReader(); diff --git a/shell/browser/api/atom_api_system_preferences_mac.mm b/shell/browser/api/atom_api_system_preferences_mac.mm index 4d5ac423a1..38f0504349 100644 --- a/shell/browser/api/atom_api_system_preferences_mac.mm +++ b/shell/browser/api/atom_api_system_preferences_mac.mm @@ -451,7 +451,7 @@ bool SystemPreferences::CanPromptTouchID() { v8::Local SystemPreferences::PromptTouchID( v8::Isolate* isolate, const std::string& reason) { - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); if (@available(macOS 10.12.2, *)) { @@ -468,7 +468,7 @@ v8::Local SystemPreferences::PromptTouchID( scoped_refptr runner = base::SequencedTaskRunnerHandle::Get(); - __block util::Promise p = std::move(promise); + __block util::Promise p = std::move(promise); [context evaluateAccessControl:access_control operation:LAAccessControlOperationUseKeySign @@ -479,14 +479,14 @@ v8::Local SystemPreferences::PromptTouchID( [error.localizedDescription UTF8String]); runner->PostTask( FROM_HERE, - base::BindOnce(util::Promise::RejectPromise, - std::move(p), - std::move(err_msg))); + base::BindOnce( + util::Promise::RejectPromise, + std::move(p), std::move(err_msg))); } else { runner->PostTask( FROM_HERE, base::BindOnce( - util::Promise::ResolveEmptyPromise, + util::Promise::ResolveEmptyPromise, std::move(p))); } }]; @@ -607,12 +607,12 @@ std::string SystemPreferences::GetMediaAccessStatus( v8::Local SystemPreferences::AskForMediaAccess( v8::Isolate* isolate, const std::string& media_type) { - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); if (auto type = ParseMediaType(media_type)) { if (@available(macOS 10.14, *)) { - __block util::Promise p = std::move(promise); + __block util::Promise p = std::move(promise); [AVCaptureDevice requestAccessForMediaType:type completionHandler:^(BOOL granted) { dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/shell/browser/api/atom_api_web_contents.cc b/shell/browser/api/atom_api_web_contents.cc index 91c501eb24..ed3df93c89 100644 --- a/shell/browser/api/atom_api_web_contents.cc +++ b/shell/browser/api/atom_api_web_contents.cc @@ -302,7 +302,8 @@ namespace api { namespace { // Called when CapturePage is done. -void OnCapturePageDone(util::Promise promise, const SkBitmap& bitmap) { +void OnCapturePageDone(util::Promise promise, + const SkBitmap& bitmap) { // Hack to enable transparency in captured image promise.Resolve(gfx::Image::CreateFrom1xBitmap(bitmap)); } @@ -1417,7 +1418,7 @@ std::string WebContents::GetUserAgent() { v8::Local WebContents::SavePage( const base::FilePath& full_file_path, const content::SavePageType& save_type) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); auto* handler = new SavePageHandler(web_contents(), std::move(promise)); @@ -1749,7 +1750,7 @@ std::vector WebContents::GetPrinterList() { v8::Local WebContents::PrintToPDF( const base::DictionaryValue& settings) { - util::Promise promise(isolate()); + util::Promise> promise(isolate()); v8::Local handle = promise.GetHandle(); PrintPreviewMessageHandler::FromWebContents(web_contents()) ->PrintToPDF(settings, std::move(promise)); @@ -2052,7 +2053,7 @@ void WebContents::StartDrag(const mate::Dictionary& item, v8::Local WebContents::CapturePage(mate::Arguments* args) { gfx::Rect rect; - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); // get rect arguments if they exist @@ -2319,7 +2320,7 @@ void WebContents::GrantOriginAccess(const GURL& url) { v8::Local WebContents::TakeHeapSnapshot( const base::FilePath& file_path) { - util::Promise promise(isolate()); + util::Promise promise(isolate()); v8::Local handle = promise.GetHandle(); base::ThreadRestrictions::ScopedAllowIO allow_io; @@ -2346,8 +2347,8 @@ v8::Local WebContents::TakeHeapSnapshot( (*raw_ptr)->TakeHeapSnapshot( mojo::WrapPlatformFile(file.TakePlatformFile()), base::BindOnce( - [](mojom::ElectronRendererAssociatedPtr* ep, util::Promise promise, - bool success) { + [](mojom::ElectronRendererAssociatedPtr* ep, + util::Promise promise, bool success) { if (success) { promise.Resolve(); } else { diff --git a/shell/browser/api/gpuinfo_manager.cc b/shell/browser/api/gpuinfo_manager.cc index 20401af5fa..714fc6d395 100644 --- a/shell/browser/api/gpuinfo_manager.cc +++ b/shell/browser/api/gpuinfo_manager.cc @@ -61,7 +61,8 @@ void GPUInfoManager::OnGpuInfoUpdate() { } // Should be posted to the task runner -void GPUInfoManager::CompleteInfoFetcher(util::Promise promise) { +void GPUInfoManager::CompleteInfoFetcher( + util::Promise promise) { complete_info_promise_set_.emplace_back(std::move(promise)); if (NeedsCompleteGpuInfoCollection()) { @@ -71,7 +72,8 @@ void GPUInfoManager::CompleteInfoFetcher(util::Promise promise) { } } -void GPUInfoManager::FetchCompleteInfo(util::Promise promise) { +void GPUInfoManager::FetchCompleteInfo( + util::Promise promise) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&GPUInfoManager::CompleteInfoFetcher, base::Unretained(this), std::move(promise))); @@ -79,7 +81,8 @@ void GPUInfoManager::FetchCompleteInfo(util::Promise promise) { // This fetches the info synchronously, so no need to post to the task queue. // There cannot be multiple promises as they are resolved synchronously. -void GPUInfoManager::FetchBasicInfo(util::Promise promise) { +void GPUInfoManager::FetchBasicInfo( + util::Promise promise) { gpu::GPUInfo gpu_info; CollectBasicGraphicsInfo(&gpu_info); promise.Resolve(*EnumerateGPUInfo(gpu_info)); diff --git a/shell/browser/api/gpuinfo_manager.h b/shell/browser/api/gpuinfo_manager.h index cb7ee9f6ae..8495951e75 100644 --- a/shell/browser/api/gpuinfo_manager.h +++ b/shell/browser/api/gpuinfo_manager.h @@ -25,8 +25,8 @@ class GPUInfoManager : public content::GpuDataManagerObserver { GPUInfoManager(); ~GPUInfoManager() override; bool NeedsCompleteGpuInfoCollection() const; - void FetchCompleteInfo(util::Promise promise); - void FetchBasicInfo(util::Promise promise); + void FetchCompleteInfo(util::Promise promise); + void FetchBasicInfo(util::Promise promise); void OnGpuInfoUpdate() override; private: @@ -34,12 +34,12 @@ class GPUInfoManager : public content::GpuDataManagerObserver { gpu::GPUInfo gpu_info) const; // These should be posted to the task queue - void CompleteInfoFetcher(util::Promise promise); + void CompleteInfoFetcher(util::Promise promise); void ProcessCompleteInfo(); // This set maintains all the promises that should be fulfilled // once we have the complete information data - std::vector complete_info_promise_set_; + std::vector> complete_info_promise_set_; content::GpuDataManager* gpu_data_manager_; DISALLOW_COPY_AND_ASSIGN(GPUInfoManager); diff --git a/shell/browser/api/save_page_handler.cc b/shell/browser/api/save_page_handler.cc index 3de2c62756..d9e850f111 100644 --- a/shell/browser/api/save_page_handler.cc +++ b/shell/browser/api/save_page_handler.cc @@ -17,7 +17,7 @@ namespace electron { namespace api { SavePageHandler::SavePageHandler(content::WebContents* web_contents, - util::Promise promise) + util::Promise promise) : web_contents_(web_contents), promise_(std::move(promise)) {} SavePageHandler::~SavePageHandler() {} diff --git a/shell/browser/api/save_page_handler.h b/shell/browser/api/save_page_handler.h index 13f4d55e67..f0e685f771 100644 --- a/shell/browser/api/save_page_handler.h +++ b/shell/browser/api/save_page_handler.h @@ -30,7 +30,7 @@ class SavePageHandler : public content::DownloadManager::Observer, public download::DownloadItem::Observer { public: SavePageHandler(content::WebContents* web_contents, - electron::util::Promise promise); + electron::util::Promise promise); ~SavePageHandler() override; bool Handle(const base::FilePath& full_path, @@ -47,7 +47,7 @@ class SavePageHandler : public content::DownloadManager::Observer, void OnDownloadUpdated(download::DownloadItem* item) override; content::WebContents* web_contents_; // weak - electron::util::Promise promise_; + electron::util::Promise promise_; }; } // namespace api diff --git a/shell/browser/atom_blob_reader.cc b/shell/browser/atom_blob_reader.cc index ebb38c9874..cb5525d145 100644 --- a/shell/browser/atom_blob_reader.cc +++ b/shell/browser/atom_blob_reader.cc @@ -27,7 +27,9 @@ void FreeNodeBufferData(char* data, void* hint) { delete[] data; } -void RunPromiseInUI(util::Promise promise, char* blob_data, int size) { +void RunPromiseInUI(util::Promise> promise, + char* blob_data, + int size) { DCHECK_CURRENTLY_ON(BrowserThread::UI); v8::Isolate* isolate = promise.isolate(); @@ -52,13 +54,13 @@ AtomBlobReader::AtomBlobReader(content::ChromeBlobStorageContext* blob_context) AtomBlobReader::~AtomBlobReader() {} void AtomBlobReader::StartReading(const std::string& uuid, - util::Promise promise) { + util::Promise> promise) { DCHECK_CURRENTLY_ON(BrowserThread::IO); auto blob_data_handle = blob_context_->context()->GetBlobDataFromUUID(uuid); if (!blob_data_handle) { - util::Promise::RejectPromise(std::move(promise), - "Could not get blob data handle"); + util::Promise>::RejectPromise( + std::move(promise), "Could not get blob data handle"); return; } diff --git a/shell/browser/atom_blob_reader.h b/shell/browser/atom_blob_reader.h index 5015fd8fa0..06e792b1e1 100644 --- a/shell/browser/atom_blob_reader.h +++ b/shell/browser/atom_blob_reader.h @@ -39,7 +39,8 @@ class AtomBlobReader { explicit AtomBlobReader(content::ChromeBlobStorageContext* blob_context); ~AtomBlobReader(); - void StartReading(const std::string& uuid, electron::util::Promise promise); + void StartReading(const std::string& uuid, + electron::util::Promise> promise); private: // A self-destroyed helper class to read the blob data. diff --git a/shell/browser/atom_download_manager_delegate.cc b/shell/browser/atom_download_manager_delegate.cc index 9c8f0abdd8..7218d3294f 100644 --- a/shell/browser/atom_download_manager_delegate.cc +++ b/shell/browser/atom_download_manager_delegate.cc @@ -122,7 +122,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated( settings.force_detached = offscreen; v8::Isolate* isolate = v8::Isolate::GetCurrent(); - electron::util::Promise dialog_promise(isolate); + electron::util::Promise dialog_promise(isolate); auto dialog_callback = base::BindOnce(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone, base::Unretained(this), download_id, callback); diff --git a/shell/browser/browser.cc b/shell/browser/browser.cc index feee108a8e..48dcbb0d0b 100644 --- a/shell/browser/browser.cc +++ b/shell/browser/browser.cc @@ -165,9 +165,9 @@ void Browser::DidFinishLaunching(const base::DictionaryValue& launch_info) { observer.OnFinishLaunching(launch_info); } -const util::Promise& Browser::WhenReady(v8::Isolate* isolate) { +const util::Promise& Browser::WhenReady(v8::Isolate* isolate) { if (!ready_promise_) { - ready_promise_.reset(new util::Promise(isolate)); + ready_promise_.reset(new util::Promise(isolate)); if (is_ready()) { ready_promise_->Resolve(); } diff --git a/shell/browser/browser.h b/shell/browser/browser.h index 3a6c7aff60..9c160cc37e 100644 --- a/shell/browser/browser.h +++ b/shell/browser/browser.h @@ -262,7 +262,7 @@ class Browser : public WindowListObserver { bool is_shutting_down() const { return is_shutdown_; } bool is_quiting() const { return is_quiting_; } bool is_ready() const { return is_ready_; } - const util::Promise& WhenReady(v8::Isolate* isolate); + const util::Promise& WhenReady(v8::Isolate* isolate); protected: // Returns the version of application bundle or executable file. @@ -301,7 +301,7 @@ class Browser : public WindowListObserver { int badge_count_ = 0; - std::unique_ptr ready_promise_; + std::unique_ptr> ready_promise_; #if defined(OS_LINUX) || defined(OS_WIN) base::Value about_panel_options_; diff --git a/shell/browser/browser_mac.mm b/shell/browser/browser_mac.mm index 8730d9a22b..ebf8255490 100644 --- a/shell/browser/browser_mac.mm +++ b/shell/browser/browser_mac.mm @@ -313,7 +313,7 @@ bool Browser::DockIsVisible() { } v8::Local Browser::DockShow(v8::Isolate* isolate) { - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); BOOL active = [[NSRunningApplication currentApplication] isActive]; @@ -327,7 +327,7 @@ v8::Local Browser::DockShow(v8::Isolate* isolate) { [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; break; } - __block util::Promise p = std::move(promise); + __block util::Promise p = std::move(promise); dispatch_time_t one_ms = dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC); dispatch_after(one_ms, dispatch_get_main_queue(), ^{ TransformProcessType(&psn, kProcessTransformToForegroundApplication); diff --git a/shell/browser/printing/print_preview_message_handler.cc b/shell/browser/printing/print_preview_message_handler.cc index 31df5cea40..79e3cd3e8a 100644 --- a/shell/browser/printing/print_preview_message_handler.cc +++ b/shell/browser/printing/print_preview_message_handler.cc @@ -142,7 +142,7 @@ void PrintPreviewMessageHandler::OnPrintPreviewCancelled( void PrintPreviewMessageHandler::PrintToPDF( const base::DictionaryValue& options, - electron::util::Promise promise) { + electron::util::Promise> promise) { int request_id; options.GetInteger(printing::kPreviewRequestID, &request_id); promise_map_.emplace(request_id, std::move(promise)); @@ -154,11 +154,12 @@ void PrintPreviewMessageHandler::PrintToPDF( rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options)); } -util::Promise PrintPreviewMessageHandler::GetPromise(int request_id) { +util::Promise> PrintPreviewMessageHandler::GetPromise( + int request_id) { auto it = promise_map_.find(request_id); DCHECK(it != promise_map_.end()); - util::Promise promise = std::move(it->second); + util::Promise> promise = std::move(it->second); promise_map_.erase(it); return promise; @@ -169,7 +170,7 @@ void PrintPreviewMessageHandler::ResolvePromise( scoped_refptr data_bytes) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - util::Promise promise = GetPromise(request_id); + util::Promise> promise = GetPromise(request_id); v8::Isolate* isolate = promise.isolate(); mate::Locker locker(isolate); @@ -189,7 +190,7 @@ void PrintPreviewMessageHandler::ResolvePromise( void PrintPreviewMessageHandler::RejectPromise(int request_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - util::Promise promise = GetPromise(request_id); + util::Promise> promise = GetPromise(request_id); promise.RejectWithErrorMessage("Failed to generate PDF"); } diff --git a/shell/browser/printing/print_preview_message_handler.h b/shell/browser/printing/print_preview_message_handler.h index 93d21b630e..bc59a1a9b5 100644 --- a/shell/browser/printing/print_preview_message_handler.h +++ b/shell/browser/printing/print_preview_message_handler.h @@ -31,7 +31,8 @@ class PrintPreviewMessageHandler public: ~PrintPreviewMessageHandler() override; - void PrintToPDF(const base::DictionaryValue& options, util::Promise promise); + void PrintToPDF(const base::DictionaryValue& options, + util::Promise> promise); protected: // content::WebContentsObserver implementation. @@ -55,13 +56,14 @@ class PrintPreviewMessageHandler void OnPrintPreviewCancelled(int document_cookie, const PrintHostMsg_PreviewIds& ids); - util::Promise GetPromise(int request_id); + util::Promise> GetPromise(int request_id); void ResolvePromise(int request_id, scoped_refptr data_bytes); void RejectPromise(int request_id); - using PromiseMap = std::map; + using PromiseMap = + std::map>>; PromiseMap promise_map_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/shell/browser/ui/certificate_trust_mac.mm b/shell/browser/ui/certificate_trust_mac.mm index eabfaf5005..890a2d410d 100644 --- a/shell/browser/ui/certificate_trust_mac.mm +++ b/shell/browser/ui/certificate_trust_mac.mm @@ -19,7 +19,7 @@ @interface TrustDelegate : NSObject { @private - std::unique_ptr promise_; + std::unique_ptr> promise_; SFCertificateTrustPanel* panel_; scoped_refptr cert_; SecTrustRef trust_; @@ -27,7 +27,7 @@ SecPolicyRef sec_policy_; } -- (id)initWithPromise:(electron::util::Promise)promise +- (id)initWithPromise:(electron::util::Promise)promise panel:(SFCertificateTrustPanel*)panel cert:(const scoped_refptr&)cert trust:(SecTrustRef)trust @@ -51,14 +51,14 @@ [super dealloc]; } -- (id)initWithPromise:(electron::util::Promise)promise +- (id)initWithPromise:(electron::util::Promise)promise panel:(SFCertificateTrustPanel*)panel cert:(const scoped_refptr&)cert trust:(SecTrustRef)trust certChain:(CFArrayRef)certChain secPolicy:(SecPolicyRef)secPolicy { if ((self = [super init])) { - promise_.reset(new electron::util::Promise(std::move(promise))); + promise_.reset(new electron::util::Promise(std::move(promise))); panel_ = panel; cert_ = cert; trust_ = trust; @@ -90,7 +90,7 @@ v8::Local ShowCertificateTrust( const scoped_refptr& cert, const std::string& message) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); auto* sec_policy = SecPolicyCreateBasicX509(); diff --git a/shell/browser/ui/certificate_trust_win.cc b/shell/browser/ui/certificate_trust_win.cc index ba3d0963a5..acd110b87c 100644 --- a/shell/browser/ui/certificate_trust_win.cc +++ b/shell/browser/ui/certificate_trust_win.cc @@ -61,7 +61,7 @@ v8::Local ShowCertificateTrust( const scoped_refptr& cert, const std::string& message) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); PCCERT_CHAIN_CONTEXT chain_context; diff --git a/shell/browser/ui/file_dialog.h b/shell/browser/ui/file_dialog.h index 56876243d1..1063183010 100644 --- a/shell/browser/ui/file_dialog.h +++ b/shell/browser/ui/file_dialog.h @@ -66,12 +66,12 @@ bool ShowOpenDialogSync(const DialogSettings& settings, std::vector* paths); void ShowOpenDialog(const DialogSettings& settings, - electron::util::Promise promise); + electron::util::Promise promise); bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path); void ShowSaveDialog(const DialogSettings& settings, - electron::util::Promise promise); + electron::util::Promise promise); } // namespace file_dialog diff --git a/shell/browser/ui/file_dialog_gtk.cc b/shell/browser/ui/file_dialog_gtk.cc index a7074cf1fa..5f9d8bbe28 100644 --- a/shell/browser/ui/file_dialog_gtk.cc +++ b/shell/browser/ui/file_dialog_gtk.cc @@ -157,13 +157,15 @@ class FileChooserDialog { gtk_window_present_with_time(GTK_WINDOW(dialog_), time); } - void RunSaveAsynchronous(electron::util::Promise promise) { - save_promise_.reset(new electron::util::Promise(std::move(promise))); + void RunSaveAsynchronous(electron::util::Promise promise) { + save_promise_.reset( + new electron::util::Promise(std::move(promise))); RunAsynchronous(); } - void RunOpenAsynchronous(electron::util::Promise promise) { - open_promise_.reset(new electron::util::Promise(std::move(promise))); + void RunOpenAsynchronous(electron::util::Promise promise) { + open_promise_.reset( + new electron::util::Promise(std::move(promise))); RunAsynchronous(); } @@ -204,8 +206,8 @@ class FileChooserDialog { GtkWidget* preview_; Filters filters_; - std::unique_ptr save_promise_; - std::unique_ptr open_promise_; + std::unique_ptr> save_promise_; + std::unique_ptr> open_promise_; // Callback for when we update the preview for the selection. CHROMEG_CALLBACK_0(FileChooserDialog, void, OnUpdatePreview, GtkWidget*); @@ -225,7 +227,7 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) { dict.Set("canceled", true); dict.Set("filePath", base::FilePath()); } - save_promise_->Resolve(dict.GetHandle()); + save_promise_->Resolve(dict); } else if (open_promise_) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(open_promise_->isolate()); @@ -236,7 +238,7 @@ void FileChooserDialog::OnFileDialogResponse(GtkWidget* widget, int response) { dict.Set("canceled", true); dict.Set("filePaths", std::vector()); } - open_promise_->Resolve(dict.GetHandle()); + open_promise_->Resolve(dict); } delete this; } @@ -312,7 +314,7 @@ bool ShowOpenDialogSync(const DialogSettings& settings, } void ShowOpenDialog(const DialogSettings& settings, - electron::util::Promise promise) { + electron::util::Promise promise) { GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; if (settings.properties & OPEN_DIALOG_OPEN_DIRECTORY) action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; @@ -335,7 +337,7 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) { } void ShowSaveDialog(const DialogSettings& settings, - electron::util::Promise promise) { + electron::util::Promise promise) { FileChooserDialog* save_dialog = new FileChooserDialog(GTK_FILE_CHOOSER_ACTION_SAVE, settings); save_dialog->RunSaveAsynchronous(std::move(promise)); diff --git a/shell/browser/ui/file_dialog_mac.mm b/shell/browser/ui/file_dialog_mac.mm index aafd02fc5c..ce7ca65c50 100644 --- a/shell/browser/ui/file_dialog_mac.mm +++ b/shell/browser/ui/file_dialog_mac.mm @@ -300,7 +300,7 @@ bool ShowOpenDialogSync(const DialogSettings& settings, void OpenDialogCompletion(int chosen, NSOpenPanel* dialog, bool security_scoped_bookmarks, - electron::util::Promise promise) { + electron::util::Promise promise) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); if (chosen == NSFileHandlingPanelCancelButton) { dict.Set("canceled", true); @@ -308,7 +308,7 @@ void OpenDialogCompletion(int chosen, #if defined(MAS_BUILD) dict.Set("bookmarks", std::vector()); #endif - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } else { std::vector paths; dict.Set("canceled", false); @@ -324,12 +324,12 @@ void OpenDialogCompletion(int chosen, ReadDialogPaths(dialog, &paths); dict.Set("filePaths", paths); #endif - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } } void ShowOpenDialog(const DialogSettings& settings, - electron::util::Promise promise) { + electron::util::Promise promise) { NSOpenPanel* dialog = [NSOpenPanel openPanel]; SetupDialog(dialog, settings); @@ -339,7 +339,7 @@ void ShowOpenDialog(const DialogSettings& settings, // and pass it to the completion handler. bool security_scoped_bookmarks = settings.security_scoped_bookmarks; - __block electron::util::Promise p = std::move(promise); + __block electron::util::Promise p = std::move(promise); if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || settings.force_detached) { @@ -377,7 +377,7 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) { void SaveDialogCompletion(int chosen, NSSavePanel* dialog, bool security_scoped_bookmarks, - electron::util::Promise promise) { + electron::util::Promise promise) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); if (chosen == NSFileHandlingPanelCancelButton) { dict.Set("canceled", true); @@ -397,11 +397,11 @@ void SaveDialogCompletion(int chosen, } #endif } - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } void ShowSaveDialog(const DialogSettings& settings, - electron::util::Promise promise) { + electron::util::Promise promise) { NSSavePanel* dialog = [NSSavePanel savePanel]; SetupDialog(dialog, settings); @@ -412,7 +412,7 @@ void ShowSaveDialog(const DialogSettings& settings, // and pass it to the completion handler. bool security_scoped_bookmarks = settings.security_scoped_bookmarks; - __block electron::util::Promise p = std::move(promise); + __block electron::util::Promise p = std::move(promise); if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || settings.force_detached) { diff --git a/shell/browser/ui/file_dialog_win.cc b/shell/browser/ui/file_dialog_win.cc index d8ab7910f2..1b009d0b1f 100644 --- a/shell/browser/ui/file_dialog_win.cc +++ b/shell/browser/ui/file_dialog_win.cc @@ -81,18 +81,19 @@ bool CreateDialogThread(RunState* run_state) { return true; } -void OnDialogOpened(electron::util::Promise promise, +void OnDialogOpened(electron::util::Promise promise, bool canceled, std::vector paths) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); dict.Set("canceled", canceled); dict.Set("filePaths", paths); - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } -void RunOpenDialogInNewThread(const RunState& run_state, - const DialogSettings& settings, - electron::util::Promise promise) { +void RunOpenDialogInNewThread( + const RunState& run_state, + const DialogSettings& settings, + electron::util::Promise promise) { std::vector paths; bool result = ShowOpenDialogSync(settings, &paths); run_state.ui_task_runner->PostTask( @@ -101,18 +102,19 @@ void RunOpenDialogInNewThread(const RunState& run_state, run_state.ui_task_runner->DeleteSoon(FROM_HERE, run_state.dialog_thread); } -void OnSaveDialogDone(electron::util::Promise promise, +void OnSaveDialogDone(electron::util::Promise promise, bool canceled, const base::FilePath path) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); dict.Set("canceled", canceled); dict.Set("filePath", path); - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } -void RunSaveDialogInNewThread(const RunState& run_state, - const DialogSettings& settings, - electron::util::Promise promise) { +void RunSaveDialogInNewThread( + const RunState& run_state, + const DialogSettings& settings, + electron::util::Promise promise) { base::FilePath path; bool result = ShowSaveDialogSync(settings, &path); run_state.ui_task_runner->PostTask( @@ -274,13 +276,13 @@ bool ShowOpenDialogSync(const DialogSettings& settings, } void ShowOpenDialog(const DialogSettings& settings, - electron::util::Promise promise) { + electron::util::Promise promise) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); RunState run_state; if (!CreateDialogThread(&run_state)) { dict.Set("canceled", true); dict.Set("filePaths", std::vector()); - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } else { run_state.dialog_thread->task_runner()->PostTask( FROM_HERE, base::BindOnce(&RunOpenDialogInNewThread, run_state, @@ -324,13 +326,13 @@ bool ShowSaveDialogSync(const DialogSettings& settings, base::FilePath* path) { } void ShowSaveDialog(const DialogSettings& settings, - electron::util::Promise promise) { + electron::util::Promise promise) { RunState run_state; if (!CreateDialogThread(&run_state)) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(promise.isolate()); dict.Set("canceled", true); dict.Set("filePath", base::FilePath()); - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); } else { run_state.dialog_thread->task_runner()->PostTask( FROM_HERE, base::BindOnce(&RunSaveDialogInNewThread, run_state, diff --git a/shell/browser/web_dialog_helper.cc b/shell/browser/web_dialog_helper.cc index ef1b2b398c..e959bd046e 100644 --- a/shell/browser/web_dialog_helper.cc +++ b/shell/browser/web_dialog_helper.cc @@ -54,7 +54,7 @@ class FileSelectHelper : public base::RefCounted, void ShowOpenDialog(const file_dialog::DialogSettings& settings) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); auto callback = base::BindOnce(&FileSelectHelper::OnOpenDialogDone, this); ignore_result(promise.Then(std::move(callback))); @@ -65,7 +65,7 @@ class FileSelectHelper : public base::RefCounted, void ShowSaveDialog(const file_dialog::DialogSettings& settings) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Local context = isolate->GetCurrentContext(); - electron::util::Promise promise(isolate); + electron::util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); file_dialog::ShowSaveDialog(settings, std::move(promise)); diff --git a/shell/common/api/atom_api_shell.cc b/shell/common/api/atom_api_shell.cc index 14d9b98d5b..2f2645f53a 100644 --- a/shell/common/api/atom_api_shell.cc +++ b/shell/common/api/atom_api_shell.cc @@ -44,7 +44,7 @@ struct Converter { namespace { -void OnOpenExternalFinished(electron::util::Promise promise, +void OnOpenExternalFinished(electron::util::Promise promise, const std::string& error) { if (error.empty()) promise.Resolve(); @@ -53,7 +53,7 @@ void OnOpenExternalFinished(electron::util::Promise promise, } v8::Local OpenExternal(const GURL& url, mate::Arguments* args) { - electron::util::Promise promise(args->isolate()); + electron::util::Promise promise(args->isolate()); v8::Local handle = promise.GetHandle(); platform_util::OpenExternalOptions options; diff --git a/shell/common/api/electron_bindings.cc b/shell/common/api/electron_bindings.cc index 817e5063bb..9a2a3cff6a 100644 --- a/shell/common/api/electron_bindings.cc +++ b/shell/common/api/electron_bindings.cc @@ -232,7 +232,7 @@ v8::Local ElectronBindings::GetSystemMemoryInfo( // static v8::Local ElectronBindings::GetProcessMemoryInfo( v8::Isolate* isolate) { - util::Promise promise(isolate); + util::Promise promise(isolate); v8::Local handle = promise.GetHandle(); if (mate::Locker::IsBrowserProcess() && !Browser::Get()->is_ready()) { @@ -266,7 +266,7 @@ v8::Local ElectronBindings::GetBlinkMemoryInfo( // static void ElectronBindings::DidReceiveMemoryDump( v8::Global context, - util::Promise promise, + util::Promise promise, bool success, std::unique_ptr global_dump) { v8::Isolate* isolate = promise.isolate(); @@ -293,7 +293,7 @@ void ElectronBindings::DidReceiveMemoryDump( #endif dict.Set("private", osdump.private_footprint_kb); dict.Set("shared", osdump.shared_footprint_kb); - promise.Resolve(dict.GetHandle()); + promise.Resolve(dict); resolved = true; break; } diff --git a/shell/common/api/electron_bindings.h b/shell/common/api/electron_bindings.h index f6af18b109..98e0d2f182 100644 --- a/shell/common/api/electron_bindings.h +++ b/shell/common/api/electron_bindings.h @@ -71,7 +71,7 @@ class ElectronBindings { static void DidReceiveMemoryDump( v8::Global context, - util::Promise promise, + util::Promise promise, bool success, std::unique_ptr dump); diff --git a/shell/common/promise_util.cc b/shell/common/promise_util.cc index da87f6c0b4..38d32c4885 100644 --- a/shell/common/promise_util.cc +++ b/shell/common/promise_util.cc @@ -2,71 +2,21 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include - -#include "shell/common/api/locker.h" #include "shell/common/promise_util.h" -namespace electron { - -namespace util { - -Promise::Promise(v8::Isolate* isolate) - : Promise(isolate, - v8::Promise::Resolver::New(isolate->GetCurrentContext()) - .ToLocalChecked()) {} - -Promise::Promise(v8::Isolate* isolate, v8::Local handle) - : isolate_(isolate), - context_(isolate, isolate->GetCurrentContext()), - resolver_(isolate, handle) {} - -Promise::~Promise() = default; - -Promise::Promise(Promise&&) = default; -Promise& Promise::operator=(Promise&&) = default; - -v8::Maybe Promise::RejectWithErrorMessage(const std::string& string) { - v8::HandleScope handle_scope(isolate()); - v8::MicrotasksScope script_scope(isolate(), - v8::MicrotasksScope::kRunMicrotasks); - v8::Context::Scope context_scope( - v8::Local::New(isolate(), GetContext())); - - v8::Local error_message = - v8::String::NewFromUtf8(isolate(), string.c_str(), - v8::NewStringType::kNormal, - static_cast(string.size())) - .ToLocalChecked(); - v8::Local error = v8::Exception::Error(error_message); - return Reject(error); -} - -v8::Local Promise::GetHandle() const { - return GetInner()->GetPromise(); -} - -CopyablePromise::CopyablePromise(const Promise& promise) - : isolate_(promise.isolate()), handle_(isolate_, promise.GetInner()) {} - -CopyablePromise::CopyablePromise(const CopyablePromise&) = default; - -CopyablePromise::~CopyablePromise() = default; - -Promise CopyablePromise::GetPromise() const { - return Promise(isolate_, - v8::Local::New(isolate_, handle_)); -} - -} // namespace util - -} // namespace electron - namespace mate { -v8::Local mate::Converter::ToV8( +template +v8::Local mate::Converter>::ToV8( v8::Isolate*, - const electron::util::Promise& val) { + const electron::util::Promise& val) { + return val.GetHandle(); +} + +template <> +v8::Local mate::Converter>::ToV8( + v8::Isolate*, + const electron::util::Promise& val) { return val.GetHandle(); } diff --git a/shell/common/promise_util.h b/shell/common/promise_util.h index ec43ab02e2..a73f585b9f 100644 --- a/shell/common/promise_util.h +++ b/shell/common/promise_util.h @@ -6,6 +6,8 @@ #define SHELL_COMMON_PROMISE_UTIL_H_ #include +#include +#include #include #include "base/task/post_task.h" @@ -24,19 +26,26 @@ namespace util { // // This is a move-only type that should always be `std::move`d when passed to // callbacks, and it should be destroyed on the same thread of creation. +template class Promise { public: // Create a new promise. - explicit Promise(v8::Isolate* isolate); + explicit Promise(v8::Isolate* isolate) + : Promise(isolate, + v8::Promise::Resolver::New(isolate->GetCurrentContext()) + .ToLocalChecked()) {} // Wrap an existing v8 promise. - Promise(v8::Isolate* isolate, v8::Local handle); + Promise(v8::Isolate* isolate, v8::Local handle) + : isolate_(isolate), + context_(isolate, isolate->GetCurrentContext()), + resolver_(isolate, handle) {} - ~Promise(); + ~Promise() = default; // Support moving. - Promise(Promise&&); - Promise& operator=(Promise&&); + Promise(Promise&&) = default; + Promise& operator=(Promise&&) = default; v8::Isolate* isolate() const { return isolate_; } v8::Local GetContext() { @@ -45,35 +54,34 @@ class Promise { // helpers for promise resolution and rejection - template - static void ResolvePromise(Promise promise, T result) { + static void ResolvePromise(Promise promise, RT result) { if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { base::PostTaskWithTraits( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( - [](Promise promise, T result) { promise.Resolve(result); }, + [](Promise promise, RT result) { promise.Resolve(result); }, std::move(promise), std::move(result))); } else { promise.Resolve(result); } } - static void ResolveEmptyPromise(Promise promise) { + static void ResolveEmptyPromise(Promise promise) { if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { base::PostTaskWithTraits( FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce([](Promise promise) { promise.Resolve(); }, + base::BindOnce([](Promise promise) { promise.Resolve(); }, std::move(promise))); } else { promise.Resolve(); } } - static void RejectPromise(Promise promise, std::string errmsg) { + static void RejectPromise(Promise promise, std::string errmsg) { if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( - [](Promise promise, std::string errmsg) { + [](Promise promise, std::string errmsg) { promise.RejectWithErrorMessage(errmsg); }, std::move(promise), std::move(errmsg))); @@ -83,23 +91,24 @@ class Promise { } // Returns an already-resolved promise. - template static v8::Local ResolvedPromise(v8::Isolate* isolate, - T result) { - Promise resolved(isolate); + RT result) { + Promise resolved(isolate); resolved.Resolve(result); return resolved.GetHandle(); } static v8::Local ResolvedPromise(v8::Isolate* isolate) { - Promise resolved(isolate); + Promise resolved(isolate); resolved.Resolve(); return resolved.GetHandle(); } - v8::Local GetHandle() const; + v8::Local GetHandle() const { return GetInner()->GetPromise(); } v8::Maybe Resolve() { + static_assert(std::is_same(), + "Can only resolve void* promises with no value"); v8::HandleScope handle_scope(isolate()); v8::MicrotasksScope script_scope(isolate(), v8::MicrotasksScope::kRunMicrotasks); @@ -119,25 +128,16 @@ class Promise { return GetInner()->Reject(GetContext(), v8::Undefined(isolate())); } - // Please note that using Then is effectively the same as calling .then - // in javascript. This means (a) it is not type safe and (b) please note - // it is NOT type safe. - // If the base::Callback you provide here is of type void(boolean) and you - // resolve the promise with a string, Electron will compile successfully and - // then that promise will be rejected as soon as you try to use it as the - // mate converters doing work behind the scenes will throw an error for you. - // This can be really hard to trace so until either - // * This helper becomes typesafe (by templating the class instead of each - // method) - // * or the world goes mad - // Please try your hardest not to use this method - // The world thanks you template v8::MaybeLocal Then( base::OnceCallback cb) { static_assert(sizeof...(ResolveType) <= 1, "A promise's 'Then' callback should only receive at most one " "parameter"); + static_assert( + std::is_same>>(), + "A promises's 'Then' callback must handle the same type as the " + "promises resolve type"); v8::HandleScope handle_scope(isolate()); v8::Context::Scope context_scope( v8::Local::New(isolate(), GetContext())); @@ -150,8 +150,9 @@ class Promise { // Promise resolution is a microtask // We use the MicrotasksRunner to trigger the running of pending microtasks - template - v8::Maybe Resolve(const T& value) { + v8::Maybe Resolve(const RT& value) { + static_assert(!std::is_same(), + "void* promises can not be resolved with a value"); v8::HandleScope handle_scope(isolate()); v8::MicrotasksScope script_scope(isolate(), v8::MicrotasksScope::kRunMicrotasks); @@ -162,23 +163,36 @@ class Promise { mate::ConvertToV8(isolate(), value)); } - template - v8::Maybe Reject(const T& value) { + v8::Maybe ResolveWithGin(const RT& value) { + static_assert(!std::is_same(), + "void* promises can not be resolved with a value"); v8::HandleScope handle_scope(isolate()); v8::MicrotasksScope script_scope(isolate(), v8::MicrotasksScope::kRunMicrotasks); v8::Context::Scope context_scope( v8::Local::New(isolate(), GetContext())); - return GetInner()->Reject(GetContext(), - mate::ConvertToV8(isolate(), value)); + return GetInner()->Resolve(GetContext(), + gin::ConvertToV8(isolate(), value)); } - v8::Maybe RejectWithErrorMessage(const std::string& error); + v8::Maybe RejectWithErrorMessage(const std::string& string) { + v8::HandleScope handle_scope(isolate()); + v8::MicrotasksScope script_scope(isolate(), + v8::MicrotasksScope::kRunMicrotasks); + v8::Context::Scope context_scope( + v8::Local::New(isolate(), GetContext())); + + v8::Local error_message = + v8::String::NewFromUtf8(isolate(), string.c_str(), + v8::NewStringType::kNormal, + static_cast(string.size())) + .ToLocalChecked(); + v8::Local error = v8::Exception::Error(error_message); + return GetInner()->Reject(GetContext(), (error)); + } private: - friend class CopyablePromise; - v8::Local GetInner() const { return resolver_.Get(isolate()); } @@ -190,70 +204,16 @@ class Promise { DISALLOW_COPY_AND_ASSIGN(Promise); }; -// A wrapper of Promise that can be copied. -// -// This class should only be used when we have to pass Promise to a Chromium API -// that does not take OnceCallback. -class CopyablePromise { - public: - explicit CopyablePromise(const Promise& promise); - CopyablePromise(const CopyablePromise&); - ~CopyablePromise(); - - template - static void ResolveCopyablePromise(const CopyablePromise& promise, T result) { - if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(Promise::ResolvePromise, promise.GetPromise(), - std::move(result))); - } else { - promise.GetPromise().Resolve(result); - } - } - - static void ResolveEmptyCopyablePromise(const CopyablePromise& promise) { - if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(Promise::ResolveEmptyPromise, promise.GetPromise())); - } else { - promise.GetPromise().Resolve(); - } - } - - static void RejectCopyablePromise(const CopyablePromise& promise, - std::string errmsg) { - if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(Promise::RejectPromise, promise.GetPromise(), - std::move(errmsg))); - } else { - promise.GetPromise().RejectWithErrorMessage(errmsg); - } - } - - Promise GetPromise() const; - - private: - using CopyablePersistent = - v8::CopyablePersistentTraits::CopyablePersistent; - - v8::Isolate* isolate_; - CopyablePersistent handle_; -}; - } // namespace util } // namespace electron namespace mate { -template <> -struct Converter { +template +struct Converter> { static v8::Local ToV8(v8::Isolate* isolate, - const electron::util::Promise& val); + const electron::util::Promise& val); // TODO(MarshallOfSound): Implement FromV8 to allow promise chaining // in native land // static bool FromV8(v8::Isolate* isolate, diff --git a/shell/renderer/api/atom_api_renderer_ipc.cc b/shell/renderer/api/atom_api_renderer_ipc.cc index f6cf478071..1e3045ab44 100644 --- a/shell/renderer/api/atom_api_renderer_ipc.cc +++ b/shell/renderer/api/atom_api_renderer_ipc.cc @@ -75,12 +75,12 @@ class IPCRenderer : public mate::Wrappable { v8::Local Invoke(mate::Arguments* args, const std::string& channel, const base::Value& arguments) { - electron::util::Promise p(args->isolate()); + electron::util::Promise p(args->isolate()); auto handle = p.GetHandle(); electron_browser_ptr_->get()->Invoke( channel, arguments.Clone(), - base::BindOnce([](electron::util::Promise p, + base::BindOnce([](electron::util::Promise p, base::Value result) { p.Resolve(result); }, std::move(p))); diff --git a/shell/renderer/api/atom_api_web_frame.cc b/shell/renderer/api/atom_api_web_frame.cc index ac6ca330e1..8b00a9d129 100644 --- a/shell/renderer/api/atom_api_web_frame.cc +++ b/shell/renderer/api/atom_api_web_frame.cc @@ -113,7 +113,8 @@ class RenderFrameStatus : public content::RenderFrameObserver { class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { public: - explicit ScriptExecutionCallback(electron::util::Promise promise) + explicit ScriptExecutionCallback( + electron::util::Promise> promise) : promise_(std::move(promise)) {} ~ScriptExecutionCallback() override {} @@ -137,7 +138,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { } private: - electron::util::Promise promise_; + electron::util::Promise> promise_; DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback); }; @@ -376,7 +377,7 @@ v8::Local ExecuteJavaScript(mate::Arguments* args, v8::Local window, const base::string16& code) { v8::Isolate* isolate = args->isolate(); - util::Promise promise(isolate); + util::Promise> promise(isolate); v8::Local handle = promise.GetHandle(); bool has_user_gesture = false; @@ -395,7 +396,7 @@ v8::Local ExecuteJavaScriptInIsolatedWorld( int world_id, const std::vector& scripts) { v8::Isolate* isolate = args->isolate(); - util::Promise promise(isolate); + util::Promise> promise(isolate); v8::Local handle = promise.GetHandle(); std::vector sources;