From 831fe49d8a7ee0a975936d22ac73f3550c454e65 Mon Sep 17 00:00:00 2001 From: Bakka Uday Kiran Date: Sun, 22 Jan 2023 23:24:02 +0530 Subject: [PATCH 01/16] [M108 Migration] Implement ewk_settings_use_system_font_set API Added needed to support to control the font setting for browser. Reference: https://review.tizen.org/gerrit/c/277844 Change-Id: I051d586183dadfa928f97415dfb246e4b32b361a Signed-off-by: Bakka Uday Kiran --- third_party/blink/renderer/platform/fonts/font_cache.h | 9 +++++++++ .../blink/renderer/platform/fonts/skia/font_cache_skia.cc | 11 +++++++++++ tizen_src/ewk/efl_integration/eweb_view.cc | 12 +++++++++--- tizen_src/ewk/efl_integration/public/ewk_settings.cc | 13 +++++++++++-- 4 files changed, 40 insertions(+), 5 deletions(-) mode change 100644 => 100755 third_party/blink/renderer/platform/fonts/font_cache.h diff --git a/third_party/blink/renderer/platform/fonts/font_cache.h b/third_party/blink/renderer/platform/fonts/font_cache.h old mode 100644 new mode 100755 index af9f3af..1d64d43 --- a/third_party/blink/renderer/platform/fonts/font_cache.h +++ b/third_party/blink/renderer/platform/fonts/font_cache.h @@ -290,6 +290,11 @@ class PLATFORM_EXPORT FontCache final { FontCache& operator=(const FontCache&) = delete; ~FontCache(); +#if BUILDFLAG(IS_EFL) + void SetFontFamilyTizenBrowser() { tizen_browser_font_family = true; } + bool IsFontFamilyTizenBrowser() const { return tizen_browser_font_family; } +#endif + private: // BCP47 list used when requesting fallback font for a character. // inlineCapacity is set to 4: the array vector not need to hold more than 4 @@ -404,6 +409,10 @@ class PLATFORM_EXPORT FontCache final { void PurgePlatformFontDataCache(); void PurgeFallbackListShaperCache(); +#if BUILDFLAG(IS_EFL) + bool tizen_browser_font_family = false; +#endif + friend class SimpleFontData; // For fontDataFromFontPlatformData friend class FontFallbackList; friend class FontPlatformDataCache; diff --git a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc index 9a458ca..3bcff7b 100644 --- a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc +++ b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc @@ -53,6 +53,9 @@ #include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkTypeface.h" +#if BUILDFLAG(IS_TIZEN) +#include "tizen_src/chromium_impl/tizen/system_info.h" +#endif namespace blink { @@ -226,6 +229,14 @@ sk_sp FontCache::CreateTypeface( } #endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_TIZEN) + if (IsMobileProfile() && Get().IsFontFamilyTizenBrowser()) + name = "SamsungOneUI"; + else if (!name.length() || (DeprecatedEqualIgnoringCase( + String(name.data()), "standardFontFamily"))) + name = "Tizen"; +#endif + #if BUILDFLAG(IS_WIN) // TODO(vmpstr): Deal with paint typeface here. if (sideloaded_fonts_) { diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index 015f775..a9f9686 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -2057,9 +2057,15 @@ bool EWebView::RestoreFromSessionData(const char* data, unsigned length) { void EWebView::SetBrowserFont() { #if !defined(EWK_BRINGUP) // FIXME: m94 bringup RenderViewHost* render_view_host = web_contents_->GetRenderViewHost(); - if (render_view_host) - render_view_host->Send( - new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID())); + if (render_view_host) { + IPC::Message* message = + new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID()); + + if (render_view_host->IsRenderViewLive()) + render_view_host->Send(message); + else + delayed_messages_.push_back(message); + } #endif } diff --git a/tizen_src/ewk/efl_integration/public/ewk_settings.cc b/tizen_src/ewk/efl_integration/public/ewk_settings.cc index 8ce40cd..1a8b3e8 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_settings.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_settings.cc @@ -865,8 +865,17 @@ Eina_Bool ewk_settings_legacy_font_size_enabled_get(Ewk_Settings* settings) Eina_Bool ewk_settings_use_system_font_set(Ewk_Settings* settings, Eina_Bool use) { - LOG_EWK_API_MOCKUP(); - return false; + if (IsMobileProfile()) { + EWebView* impl = EWebView::FromEvasObject(settings->getEvasObject()); + if (impl) { + if (use) + impl->UseSettingsFont(); + else + impl->SetBrowserFont(); + return EINA_TRUE; + } + } + return EINA_FALSE; } Eina_Bool ewk_settings_use_system_font_get(Ewk_Settings* settings) -- 2.7.4 From 9fd673f36281ac23d6a0122c19ce7ad37606f82f Mon Sep 17 00:00:00 2001 From: Bakka Uday Kiran Date: Tue, 17 Jan 2023 13:53:20 +0530 Subject: [PATCH 02/16] [M108 Migration] Patch migration for BrowsingDataRemoverEfl This patch -Migrates Session storage related changes from M94. -Fixes build error caused by accessing StoragePartition -Migrates the below patch for BrowsingDataRemoverEfl. -Removes EWK_BRINGUP caused by M94 upversion by changing to use QuotaManager instead of AppCacheService References: https://review.tizen.org/gerrit/c/273503 https://review.tizen.org/gerrit/c/283349 Change-Id: Ibaa832abd99f41f2bbb1f6ec98fe26dab4ba3fc7 Signed-off-by: Bakka Uday Kiran --- .../browser/browsing_data_remover_efl.cc | 340 ++++++--------------- .../browser/browsing_data_remover_efl.h | 116 ++++--- tizen_src/ewk/efl_integration/eweb_context.cc | 9 +- 3 files changed, 146 insertions(+), 319 deletions(-) diff --git a/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.cc b/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.cc index 5f14fec..17b2a62 100644 --- a/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.cc @@ -18,39 +18,39 @@ #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/session_storage_usage_info.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_usage_info.h" -#include "net/base/completion_repeating_callback.h" -#include "net/base/net_errors.h" -#include "net/disk_cache/disk_cache.h" -#include "net/http/http_cache.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" #include "storage/browser/quota/quota_manager.h" using content::BrowserThread; -// Static. -BrowsingDataRemoverEfl* BrowsingDataRemoverEfl::CreateForUnboundedRange(content::BrowserContext* profile) { - return new BrowsingDataRemoverEfl(profile, base::Time(), base::Time::Max()); +// static +BrowsingDataRemoverEfl* BrowsingDataRemoverEfl::CreateForUnboundedRange( + content::BrowserContext* browser_context) { + return new BrowsingDataRemoverEfl(browser_context, base::Time(), + base::Time::Max()); } -BrowsingDataRemoverEfl* BrowsingDataRemoverEfl::CreateForRange(content::BrowserContext* browser_context, - base::Time start, base::Time end) { +// static +BrowsingDataRemoverEfl* BrowsingDataRemoverEfl::CreateForRange( + content::BrowserContext* browser_context, + base::Time start, + base::Time end) { return new BrowsingDataRemoverEfl(browser_context, start, end); } -int BrowsingDataRemoverEfl::GenerateQuotaClientMask(int remove_mask) { - int quota_client_mask = 0; -#if !defined(EWK_BRINGUP) // FIXME: m85 bringup +// static +storage::QuotaClientTypes BrowsingDataRemoverEfl::GenerateQuotaClientTypes( + int remove_mask) { + storage::QuotaClientTypes quota_client_types; if (remove_mask & BrowsingDataRemoverEfl::REMOVE_FILE_SYSTEMS) - quota_client_mask |= storage::QuotaClient::kFileSystem; + quota_client_types.insert(storage::QuotaClientType::kFileSystem); if (remove_mask & BrowsingDataRemoverEfl::REMOVE_WEBSQL) - quota_client_mask |= storage::QuotaClient::kDatabase; + quota_client_types.insert(storage::QuotaClientType::kDatabase); if (remove_mask & BrowsingDataRemoverEfl::REMOVE_INDEXEDDB) - quota_client_mask |= storage::QuotaClient::kIndexedDatabase; -#endif - return quota_client_mask; + quota_client_types.insert(storage::QuotaClientType::kIndexedDatabase); + return quota_client_types; } BrowsingDataRemoverEfl::BrowsingDataRemoverEfl( @@ -58,144 +58,22 @@ BrowsingDataRemoverEfl::BrowsingDataRemoverEfl( base::Time delete_begin, base::Time delete_end) : browser_context_(browser_context), - app_cache_service_(nullptr), - quota_manager_(nullptr), - dom_storage_context_(nullptr), delete_begin_(delete_begin), - delete_end_(delete_end), - next_cache_state_(STATE_NONE), - cache_(nullptr), - main_context_getter_(nullptr), - media_context_getter_(nullptr), - waiting_for_clear_cache_(false), - waiting_for_clear_local_storage_(false), - waiting_for_clear_quota_managed_data_(false), - quota_managed_origins_to_delete_count_(0), - quota_managed_storage_types_to_delete_count_(0), - remove_mask_(0) { -#if !defined(EWK_BRINGUP) // FIXME: m94 bringup - if (browser_context_) { - app_cache_service_ = browser_context->GetStoragePartition(browser_context_, NULL)->GetAppCacheService(); - main_context_getter_ = - content::BrowserContext::GetDefaultStoragePartition(browser_context_)->GetURLRequestContext(); - media_context_getter_ = browser_context->CreateMediaRequestContext(); - } -#endif -} + delete_end_(delete_end) {} BrowsingDataRemoverEfl::~BrowsingDataRemoverEfl() { DCHECK(AllDone()); } void BrowsingDataRemoverEfl::ClearNetworkCache() { - waiting_for_clear_cache_ = true; DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - - base::ThreadPool::PostTask( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&BrowsingDataRemoverEfl::ClearNetworkCacheOnIOThread, - base::Unretained(this))); -} - -void BrowsingDataRemoverEfl::ClearNetworkCacheOnIOThread() { - // This function should be called on the IO thread. - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - DCHECK_EQ(STATE_NONE, next_cache_state_); - DCHECK(main_context_getter_.get()); - DCHECK(media_context_getter_.get()); - - next_cache_state_ = STATE_CREATE_MAIN; - DoClearCache(net::OK); -} - -// The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN --> -// STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA --> -// STATE_DONE, and any errors are ignored. -void BrowsingDataRemoverEfl::DoClearCache(int rv) { - DCHECK_NE(STATE_NONE, next_cache_state_); - - while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) { - switch (next_cache_state_) { - case STATE_CREATE_MAIN: - case STATE_CREATE_MEDIA: { - // Get a pointer to the cache. - net::URLRequestContextGetter* getter = nullptr; - if (next_cache_state_ == STATE_CREATE_MAIN) { - if (main_context_getter_) - getter = main_context_getter_.get(); - } else { - if (media_context_getter_) - getter = media_context_getter_.get(); - } - if (getter && getter->GetURLRequestContext()) { - net::HttpTransactionFactory* factory = - getter->GetURLRequestContext()->http_transaction_factory(); - if (factory) { - next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) - ? STATE_DELETE_MAIN - : STATE_DELETE_MEDIA; - rv = factory->GetCache()->GetBackend( - &cache_, base::BindOnce(&BrowsingDataRemoverEfl::DoClearCache, - base::Unretained(this))); - } else { - LOG(ERROR) << "Could not get HttpTransactionFactory."; - next_cache_state_ = STATE_NONE; - } - } else { - LOG(ERROR) << "Could not get URLRequestContext."; - next_cache_state_ = STATE_NONE; - } - break; - } - case STATE_DELETE_MAIN: - case STATE_DELETE_MEDIA: { - next_cache_state_ = (next_cache_state_ == STATE_DELETE_MAIN) ? - STATE_CREATE_MEDIA : STATE_DONE; - - // |cache_| can be null if it cannot be initialized. - if (cache_) { - if (delete_begin_.is_null()) { - rv = cache_->DoomAllEntries(base::BindOnce( - &BrowsingDataRemoverEfl::DoClearCache, base::Unretained(this))); - } else { - rv = cache_->DoomEntriesBetween( - delete_begin_, delete_end_, - base::BindOnce(&BrowsingDataRemoverEfl::DoClearCache, - base::Unretained(this))); - } - cache_ = NULL; - } - break; - } - case STATE_DONE: { - cache_ = NULL; - next_cache_state_ = STATE_NONE; - - // Notify the UI thread that we are done. - base::ThreadPool::PostTask( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&BrowsingDataRemoverEfl::ClearedCache, - base::Unretained(this))); - return; - } - default: { - NOTREACHED() << "bad state"; - next_cache_state_ = STATE_NONE; // Stop looping. - return; - } - } - } -} - -void BrowsingDataRemoverEfl::ClearedCache() { - waiting_for_clear_cache_ = false; DeleteIfDone(); } // just to keep same overall structure of Chrome::BrowsingDataRemover bool BrowsingDataRemoverEfl::AllDone() { - return !waiting_for_clear_cache_ && - !waiting_for_clear_local_storage_ && + return !waiting_for_clear_local_storage_ && + !waiting_for_clear_session_storage_ && !waiting_for_clear_quota_managed_data_; } @@ -207,90 +85,42 @@ void BrowsingDataRemoverEfl::DeleteIfDone() { base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); } -typedef void (*Application_Cache_Origins_Get_Callback)(void* origins, void* user_data); -#if !defined(EWK_BRINGUP) // FIXME: m108 bringup -void OnGotOriginsWithApplicationCache(Application_Cache_Origins_Get_Callback callback, - void* user_data, - scoped_refptr collection, - int result){ - BrowsingDataRemoverEfl* bdre = - static_cast(user_data); - // information about end of process is not needed so cb left empty - net::CompletionRepeatingCallback cb; - if (collection.get()) { - for (const auto& origin : collection->infos_by_origin) - bdre->DeleteAppCachesForOrigin(origin.first); - } -} -#endif void BrowsingDataRemoverEfl::RemoveImpl(int remove_mask, const GURL& origin) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); remove_mask_ = remove_mask; - remove_origin_ = origin; + remove_origin_ = url::Origin::Create(origin); if (remove_mask & REMOVE_LOCAL_STORAGE) { waiting_for_clear_local_storage_ = true; -#if !defined(EWK_BRINGUP) // FIXME: m94 bringup if (!dom_storage_context_) { - dom_storage_context_ = content::BrowserContext::GetStoragePartition(browser_context_, NULL)->GetDOMStorageContext(); + dom_storage_context_ = + browser_context_->GetStoragePartition(NULL)->GetDOMStorageContext(); } -#endif ClearLocalStorageOnUIThread(); } + if (remove_mask & REMOVE_SESSION_STORAGE) { + waiting_for_clear_session_storage_ = true; + if (!dom_storage_context_) { + dom_storage_context_ = + browser_context_->GetStoragePartition(NULL)->GetDOMStorageContext(); + } + ClearSessionStorageOnUIThread(); + } + if (remove_mask & REMOVE_INDEXEDDB || remove_mask & REMOVE_WEBSQL || - remove_mask & REMOVE_FILE_SYSTEMS) { -#if !defined(EWK_BRINGUP) // FIXME: m94 bringup + remove_mask & REMOVE_FILE_SYSTEMS || remove_mask & REMOVE_APPCACHE) { if (!quota_manager_) { - quota_manager_ = content::BrowserContext::GetStoragePartition(browser_context_, NULL)->GetQuotaManager(); + quota_manager_ = + browser_context_->GetStoragePartition(NULL)->GetQuotaManager(); } -#endif waiting_for_clear_quota_managed_data_ = true; base::ThreadPool::PostTask( FROM_HERE, {BrowserThread::IO}, base::BindOnce(&BrowsingDataRemoverEfl::ClearQuotaManagedDataOnIOThread, base::Unretained(this))); } - if (remove_mask & REMOVE_APPCACHE) { - DCHECK(app_cache_service_); - if (!app_cache_service_) { - return; - } - - if (origin.is_valid()) { - DeleteAppCachesForOrigin(url::Origin::Create(origin)); - } - else { -#if !defined(EWK_BRINGUP) // FIXME: m108 bringup - //if origin is empty delete all app cache (actual deletion in OnGotOriginsWithApplicationCache) - Application_Cache_Origins_Get_Callback cb = NULL; - scoped_refptr collection(new content::AppCacheInfoCollection()); - app_cache_service_->GetAllAppCacheInfo( - collection.get(), base::BindOnce(&OnGotOriginsWithApplicationCache, - cb, this, collection)); -#endif - } - } -} - -void BrowsingDataRemoverEfl::DeleteAppCachesForOrigin( - const url::Origin& origin) { - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - // TODO: Using base::Unretained is not thread safe - // It may happen that on IO thread this ptr will be already deleted - base::ThreadPool::PostTask( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&BrowsingDataRemoverEfl::DeleteAppCachesForOrigin, - base::Unretained(this), origin)); - return; - } - - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); -#if !defined(EWK_BRINGUP) // FIXME: m108 bringup - net::CompletionRepeatingCallback rm_app_catche_cb; - static_cast(app_cache_service_)->DeleteAppCachesForOrigin(origin, rm_app_catche_cb); -#endif } void BrowsingDataRemoverEfl::ClearLocalStorageOnUIThread() { @@ -316,78 +146,92 @@ void BrowsingDataRemoverEfl::OnGotLocalStorageUsageInfo( DeleteIfDone(); } +void BrowsingDataRemoverEfl::ClearSessionStorageOnUIThread() { + DCHECK(waiting_for_clear_session_storage_); + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + dom_storage_context_->GetSessionStorageUsage( + base::BindOnce(&BrowsingDataRemoverEfl::OnGotSessionStorageUsageInfo, + base::Unretained(this))); +} + +void BrowsingDataRemoverEfl::OnGotSessionStorageUsageInfo( + const std::vector& infos) { + DCHECK(waiting_for_clear_session_storage_); + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + for (size_t i = 0; i < infos.size(); ++i) + dom_storage_context_->DeleteSessionStorage(infos[i], base::DoNothing()); + waiting_for_clear_session_storage_ = false; + DeleteIfDone(); +} + void BrowsingDataRemoverEfl::ClearQuotaManagedDataOnIOThread() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup // Ask the QuotaManager for all origins with temporary quota modified within // the user-specified timeframe, and deal with the resulting set in // OnGotQuotaManagedOrigins(). quota_managed_origins_to_delete_count_ = 0; quota_managed_storage_types_to_delete_count_ = 0; - if (delete_begin_ == base::Time()) { - ++quota_managed_storage_types_to_delete_count_; - quota_manager_->GetOriginsModifiedSince( - storage::kStorageTypePersistent, delete_begin_, - base::BindOnce(&BrowsingDataRemoverEfl::OnGotQuotaManagedOrigins, - base::Unretained(this))); - } + if (delete_begin_.is_null()) + ClearQuotaManagedDataInternal(blink::mojom::StorageType::kPersistent); // Do the same for temporary quota. - ++quota_managed_storage_types_to_delete_count_; - quota_manager_->GetOriginsModifiedSince( - storage::kStorageTypeTemporary, delete_begin_, - base::BindOnce(&BrowsingDataRemoverEfl::OnGotQuotaManagedOrigins, - base::Unretained(this))); + ClearQuotaManagedDataInternal(blink::mojom::StorageType::kTemporary); // Do the same for syncable quota. + ClearQuotaManagedDataInternal(blink::mojom::StorageType::kSyncable); +} + +void BrowsingDataRemoverEfl::ClearQuotaManagedDataInternal( + blink::mojom::StorageType type) { ++quota_managed_storage_types_to_delete_count_; - quota_manager_->GetOriginsModifiedSince( - storage::kStorageTypeSyncable, delete_begin_, - base::BindOnce(&BrowsingDataRemoverEfl::OnGotQuotaManagedOrigins, + quota_manager_->GetBucketsModifiedBetween( + type, delete_begin_, delete_end_, + base::BindOnce(&BrowsingDataRemoverEfl::OnGotQuotaManagedBuckets, base::Unretained(this))); -#endif } -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup -void BrowsingDataRemoverEfl::OnGotQuotaManagedOrigins( - const std::set& origins, storage::StorageType type) { +void BrowsingDataRemoverEfl::OnGotQuotaManagedBuckets( + const std::set& buckets, + blink::mojom::StorageType type) { DCHECK_GT(quota_managed_storage_types_to_delete_count_, 0); - // Walk through the origins passed in, delete quota of |type| from each that - // matches the |origin_set_mask_|. - std::set::const_iterator origin; - for (origin = origins.begin(); origin != origins.end(); ++origin) { - if (!remove_origin_.is_empty()) { // delete all origins if remove_origin is empty - if (remove_origin_ != origin->GetOrigin()) - continue; - } + storage::QuotaClientTypes quota_client_types = + BrowsingDataRemoverEfl::GenerateQuotaClientTypes(remove_mask_); + + for (const auto& bucket : buckets) { + // delete all origins if |remove_origin_| is opaque. + if (!remove_origin_.opaque() && + remove_origin_ != bucket.storage_key.origin()) + continue; ++quota_managed_origins_to_delete_count_; - quota_manager_->DeleteOriginData( - origin->GetOrigin(), type, - BrowsingDataRemoverEfl::GenerateQuotaClientMask(remove_mask_), - base::BindOnce(&BrowsingDataRemoverEfl::OnQuotaManagedOriginDeletion, - base::Unretained(this), origin->GetOrigin(), type)); + quota_manager_->DeleteBucketData( + bucket, quota_client_types, + base::BindOnce(&BrowsingDataRemoverEfl::OnQuotaManagedBucketDeleted, + base::Unretained(this), bucket)); } --quota_managed_storage_types_to_delete_count_; CheckQuotaManagedDataDeletionStatus(); } -void BrowsingDataRemoverEfl::OnQuotaManagedOriginDeletion( - const GURL& origin, - storage::StorageType type, - storage::QuotaStatusCode status) { +void BrowsingDataRemoverEfl::OnQuotaManagedBucketDeleted( // LCOV_EXCL_LINE + const storage::BucketLocator& bucket, + blink::mojom::QuotaStatusCode status) { DCHECK_GT(quota_managed_origins_to_delete_count_, 0); - if (status != storage::kQuotaStatusOk) - DLOG(ERROR) << "Couldn't remove data of type " << type << " for origin " - << origin << ". Status: " << status; + if (status != blink::mojom::QuotaStatusCode::kOk) { + DLOG(ERROR) << "Couldn't remove data type " << static_cast(bucket.type) + << " with storage key " << bucket.storage_key.GetDebugString() + << " and bucket id " << bucket.id + << ". Status: " << static_cast(status); + } --quota_managed_origins_to_delete_count_; CheckQuotaManagedDataDeletionStatus(); } -#endif void BrowsingDataRemoverEfl::CheckQuotaManagedDataDeletionStatus() { if (quota_managed_storage_types_to_delete_count_ != 0 || diff --git a/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.h b/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.h index c30d2be..6c8885a 100644 --- a/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.h +++ b/tizen_src/ewk/efl_integration/browser/browsing_data_remover_efl.h @@ -10,81 +10,89 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "storage/browser/quota/quota_client_type.h" +#include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #include "url/gurl.h" #include "url/origin.h" -namespace net { -class URLRequestContextGetter; -} namespace content { -class AppCacheService; class BrowserContext; class DOMStorageContext; +struct SessionStorageUsageInfo; struct StorageUsageInfo; -class StoragePartition; -} -namespace disk_cache { -class Backend; -} +} // namespace content + namespace storage { class QuotaManager; +struct BucketLocator; } class BrowsingDataRemoverEfl { public: // Mask used for Remove. enum RemoveDataMask { - REMOVE_LOCAL_STORAGE = 1 << 0, - REMOVE_INDEXEDDB = 1 << 1, - REMOVE_WEBSQL = 1 << 2, - REMOVE_FILE_SYSTEMS = 1 << 3, - REMOVE_APPCACHE = 1 << 4, + REMOVE_LOCAL_STORAGE = 1 << 0, + REMOVE_INDEXEDDB = 1 << 1, + REMOVE_WEBSQL = 1 << 2, + REMOVE_FILE_SYSTEMS = 1 << 3, + REMOVE_APPCACHE = 1 << 4, + REMOVE_SESSION_STORAGE = 1 << 5, }; - static BrowsingDataRemoverEfl* CreateForUnboundedRange(content::BrowserContext*); - static BrowsingDataRemoverEfl* CreateForRange(content::BrowserContext*, base::Time, base::Time); - void RemoveImpl(int, const GURL&); + static BrowsingDataRemoverEfl* CreateForUnboundedRange( + content::BrowserContext* browser_context); + static BrowsingDataRemoverEfl* CreateForRange( + content::BrowserContext* browser_context, + base::Time start, + base::Time end); + void RemoveImpl(int remove_mask, const GURL& origin); virtual ~BrowsingDataRemoverEfl(); void ClearNetworkCache(); - // deletes app cache for given origin - void DeleteAppCachesForOrigin(const url::Origin& origin); + BrowsingDataRemoverEfl(const BrowsingDataRemoverEfl&) = delete; + BrowsingDataRemoverEfl& operator=(const BrowsingDataRemoverEfl&) = delete; protected: - BrowsingDataRemoverEfl(content::BrowserContext*, base::Time start, base::Time end); + BrowsingDataRemoverEfl(content::BrowserContext* browser_context, + base::Time start, + base::Time end); - // Quota managed data uses a different bitmask for types than - // BrowsingDataRemover uses. This method generates that mask. - static int GenerateQuotaClientMask(int); + // Quota managed data uses a different representation for storage types than + // BrowsingDataRemover uses. This method generates that representation. + static storage::QuotaClientTypes GenerateQuotaClientTypes(int remove_mask); private: - void ClearNetworkCacheOnIOThread(); - - // Callback when the cache has been cleared. - void DoClearCache(int); - // Invoked on the UI thread to delete local storage. void ClearLocalStorageOnUIThread(); // Callback to deal with the list gathered in ClearLocalStorageOnUIThread. void OnGotLocalStorageUsageInfo( - const std::vector&); + const std::vector& infos); + + // Invoked on the UI thread to delete session storage. + void ClearSessionStorageOnUIThread(); + + // Callback to deal with the list gathered in ClearSessionStorageOnUIThread. + void OnGotSessionStorageUsageInfo( + const std::vector& infos); // Invoked on the IO thread to delete all storage types managed by the quota // system: AppCache, Databases, FileSystems. void ClearQuotaManagedDataOnIOThread(); - // Callback to respond to QuotaManager::GetOriginsModifiedSince, which is the - // core of 'ClearQuotaManagedDataOnIOThread'. -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup - void OnGotQuotaManagedOrigins(const std::set&, storage::StorageType); + void ClearQuotaManagedDataInternal(blink::mojom::StorageType type); + // Callback to respond to QuotaManager::GetBucketsModifiedBetween, + // which is the core of 'ClearQuotaManagedDataOnIOThread'. + void OnGotQuotaManagedBuckets(const std::set& buckets, + blink::mojom::StorageType type); // Callback responding to deletion of a single quota managed origin's // persistent data - void OnQuotaManagedOriginDeletion(const GURL&, storage::StorageType, storage::QuotaStatusCode); -#endif + void OnQuotaManagedBucketDeleted(const storage::BucketLocator& bucket, + blink::mojom::QuotaStatusCode status); // Called to check whether all temporary and persistent origin data that // should be deleted has been deleted. If everything's good to go, invokes // OnQuotaManagedDataDeleted on the UI thread. @@ -94,19 +102,17 @@ class BrowsingDataRemoverEfl { // deleted. Updates the waiting flag and invokes NotifyAndDeleteIfDone. void OnQuotaManagedDataDeleted(); - void ClearedCache(); bool AllDone(); void DeleteIfDone(); content::BrowserContext* browser_context_; - content::AppCacheService* app_cache_service_; // The QuotaManager is owned by the profile; we can use a raw pointer here, // and rely on the profile to destroy the object whenever it's reasonable. - storage::QuotaManager* quota_manager_; + storage::QuotaManager* quota_manager_ = nullptr; // The DOMStorageContext is owned by the profile; we'll store a raw pointer. - content::DOMStorageContext* dom_storage_context_; + content::DOMStorageContext* dom_storage_context_ = nullptr; // Start time to delete from. base::Time delete_begin_; @@ -114,37 +120,19 @@ class BrowsingDataRemoverEfl { // End time to delete to. base::Time delete_end_; - enum CacheState { - STATE_NONE, - STATE_CREATE_MAIN, - STATE_CREATE_MEDIA, - STATE_DELETE_MAIN, - STATE_DELETE_MEDIA, - STATE_DONE - }; - CacheState next_cache_state_; - disk_cache::Backend* cache_; - - content::NotificationRegistrar registrar_; - std::set renderers_; - - // Used to delete data from HTTP cache. - scoped_refptr main_context_getter_; - scoped_refptr media_context_getter_; - - bool waiting_for_clear_cache_; - bool waiting_for_clear_local_storage_; - bool waiting_for_clear_quota_managed_data_; + bool waiting_for_clear_local_storage_ = false; + bool waiting_for_clear_session_storage_ = false; + bool waiting_for_clear_quota_managed_data_ = false; // Tracking how many origins need to be deleted, and whether we're finished // gathering origins. - int quota_managed_origins_to_delete_count_; - int quota_managed_storage_types_to_delete_count_; + int quota_managed_origins_to_delete_count_ = 0; + int quota_managed_storage_types_to_delete_count_ = 0; // The removal mask for the current removal operation. - int remove_mask_; + int remove_mask_ = 0; // The origin for the current removal operation. - GURL remove_origin_; + url::Origin remove_origin_; }; #endif diff --git a/tizen_src/ewk/efl_integration/eweb_context.cc b/tizen_src/ewk/efl_integration/eweb_context.cc index 8951e30..e74e8a3 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.cc +++ b/tizen_src/ewk/efl_integration/eweb_context.cc @@ -519,16 +519,11 @@ Ewk_Cookie_Manager* EWebContext::ewkCookieManager() { } void EWebContext::DeleteAllApplicationCache() { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - base::ThreadPool::PostTask( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&EWebContext::DeleteAllApplicationCache, - base::Unretained(this))); - return; - } + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get()); remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_APPCACHE, GURL()); + remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_SESSION_STORAGE, GURL()); } void EWebContext::DeleteApplicationCacheForSite(const GURL& site) { -- 2.7.4 From ec2996083e51a9e3874fe71eaae59e2b2a7ab4c3 Mon Sep 17 00:00:00 2001 From: "ayush.k123" Date: Mon, 23 Jan 2023 15:46:57 +0530 Subject: [PATCH 03/16] [M108 Migration] Enable ScreenOrientationDelegate for EFL ScreenOrientationDelegate is needed for fixing tct-screenorientation-w3c-tests failures on M108. Reference: https://review.tizen.org/gerrit/c/274262/ Change-Id: I08d37b9c5c40a551971a79df6b0938300d38d25e Signed-off-by: Ayush Kumar --- content/browser/browser_main_loop.cc | 14 ++++++++++++++ content/browser/browser_main_loop.h | 6 +++--- content/public/common/content_switches.cc | 5 +++++ content/public/common/content_switches.h | 4 ++++ .../screen_orientation/screen_orientation_delegate_efl.cc | 8 +++----- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 28a7e2b..eedf4ba 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -242,6 +242,10 @@ #include "mojo/public/cpp/bindings/lib/test_random_mojo_delays.h" #endif +#if BUILDFLAG(IS_EFL) +#include "content/browser/screen_orientation/screen_orientation_delegate_efl.h" +#endif + // One of the linux specific headers defines this as a macro. #ifdef DestroyAll #undef DestroyAll @@ -713,6 +717,16 @@ void BrowserMainLoop::PostCreateMainMessageLoop() { base::trace_event::CPUFreqMonitor::GetInstance()); #endif +#if BUILDFLAG(IS_EFL) + if (!parsed_command_line_.HasSwitch( + switches::kDisableScreenOrientationLock)) { + TRACE_EVENT0("startup", + "BrowserMainLoop::Subsystem:ScreenOrientationProvider"); + screen_orientation_delegate_ = + std::make_unique(); + } +#endif + if (UsingInProcessGpu()) { // Make sure to limits for skia font cache are applied for in process // gpu setup (crbug.com/1183230). diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index b2660cd..5e2ef10 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -102,7 +102,7 @@ namespace responsiveness { class Watcher; } // namespace responsiveness -#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_EFL) class ScreenOrientationDelegate; #endif @@ -326,8 +326,8 @@ class CONTENT_EXPORT BrowserMainLoop { std::unique_ptr screenlock_monitor_; // Per-process listener for online state changes. std::unique_ptr online_state_observer_; -#if BUILDFLAG(IS_ANDROID) - // Android implementation of ScreenOrientationDelegate +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_EFL) + // Android/EFL implementation of ScreenOrientationDelegate std::unique_ptr screen_orientation_delegate_; #endif diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index f42b7c2..310961b 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -985,6 +985,11 @@ const char kRendererWaitForJavaDebugger[] = "renderer-wait-for-java-debugger"; const char kDisableOoprDebugCrashDump[] = "disable-oopr-debug-crash-dump"; #endif +#if BUILDFLAG(IS_EFL) +// Disable the locking feature of the screen orientation API. +const char kDisableScreenOrientationLock[] = "disable-screen-orientation-lock"; +#endif + // Enable the aggressive flushing of DOM Storage to minimize data loss. const char kEnableAggressiveDOMStorageFlushing[] = "enable-aggressive-domstorage-flushing"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 6f44b6a..e3e3ddf 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -267,6 +267,10 @@ CONTENT_EXPORT extern const char kRemoteDebuggingSocketName[]; CONTENT_EXPORT extern const char kRendererWaitForJavaDebugger[]; #endif +#if BUILDFLAG(IS_EFL) +CONTENT_EXPORT extern const char kDisableScreenOrientationLock[]; +#endif + // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) diff --git a/tizen_src/chromium_impl/content/browser/screen_orientation/screen_orientation_delegate_efl.cc b/tizen_src/chromium_impl/content/browser/screen_orientation/screen_orientation_delegate_efl.cc index 4fcddbf..a1dabf7 100644 --- a/tizen_src/chromium_impl/content/browser/screen_orientation/screen_orientation_delegate_efl.cc +++ b/tizen_src/chromium_impl/content/browser/screen_orientation/screen_orientation_delegate_efl.cc @@ -5,18 +5,16 @@ #include "content/browser/screen_orientation/screen_orientation_delegate_efl.h" -#include "chromium_impl/content/browser/web_contents/web_contents_impl_efl.h" +#include "content/browser/web_contents/web_contents_impl_efl.h" +#include "content/browser/screen_orientation/screen_orientation_provider.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "ewk/efl_integration/web_contents_efl_delegate_ewk.h" namespace content { -ScreenOrientationDelegate* CreateScreenOrientationDelegateEfl() { - return new ScreenOrientationDelegateEfl(); -} - ScreenOrientationDelegateEfl::ScreenOrientationDelegateEfl() { + ScreenOrientationProvider::SetDelegate(this); } ScreenOrientationDelegateEfl::~ScreenOrientationDelegateEfl() { -- 2.7.4 From 01df9be73211ec524e18da880199503f7411a1eb Mon Sep 17 00:00:00 2001 From: v-saha Date: Mon, 23 Jan 2023 19:37:42 +0530 Subject: [PATCH 04/16] [M108 Migration][Canvas2D][TCT] Do not accelerate small size canvas. Accelerating canvas with smaller size causes TCT issues since M76, it is known in upstream and reported too. Hence disabling acceleration for smaller canvases for EFL port. References: https://review.tizen.org/gerrit/274897 https://bugs.chromium.org/p/chromium/issues/detail?id=1051392 Change-Id: Ie7642016d3d66b8290c9e3a0d170b5f8e16311fa Signed-off-by: v-saha --- content/child/runtime_features.cc | 4 ++++ third_party/blink/public/platform/web_runtime_features.h | 1 + third_party/blink/renderer/platform/exported/web_runtime_features.cc | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 208ace0..3afa697 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc @@ -122,6 +122,10 @@ void SetRuntimeFeatureDefaultsForPlatform( #if BUILDFLAG(IS_EFL) // No plan to support complex UI for date/time INPUT types. WebRuntimeFeatures::EnableInputMultipleFieldsUI(false); + + // Small accelerated 2d canvas has tct issues, which are known in + // upstream version also. + WebRuntimeFeatures::EnableAcceleratedSmallCanvases(false); #endif } diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 5897b64b..62b3f1f 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h @@ -69,6 +69,7 @@ class BLINK_PLATFORM_EXPORT WebRuntimeFeatures : public WebRuntimeFeaturesBase { static void EnableFluentScrollbars(bool); #if BUILDFLAG(IS_EFL) static void EnableInputMultipleFieldsUI(bool); + static void EnableAcceleratedSmallCanvases(bool); #endif WebRuntimeFeatures() = delete; diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index 5dd2b16..263302a 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc @@ -69,6 +69,10 @@ void WebRuntimeFeatures::EnableFluentScrollbars(bool enable) { void WebRuntimeFeatures::EnableInputMultipleFieldsUI(bool enable) { RuntimeEnabledFeatures::SetInputMultipleFieldsUIEnabled(enable); } + +void WebRuntimeFeatures::EnableAcceleratedSmallCanvases(bool enable) { + RuntimeEnabledFeatures::SetAcceleratedSmallCanvasesEnabled(enable); +} #endif } // namespace blink -- 2.7.4 From d3644c0193273f708634389d6b47e18c1c8a0c24 Mon Sep 17 00:00:00 2001 From: uzair Date: Thu, 5 Jan 2023 13:31:55 +0530 Subject: [PATCH 05/16] [PDNCF] Backport ImageManager class and its dependencies Zero copy video rendering path is dependent on chromium GL_CHROMIUM_image extension but open source plans to deprecate it in future and hence some part of code is removed before 108 branch was forked for tizen and the new CHROMIUM_shared_image extension path is not completely present in 108 version. For now we partially backport [1] and [2] to bringup TBM path. [1] https://chromium-review.googlesource.com/c/chromium/src/+/3582497 [2] https://chromium-review.googlesource.com/c/chromium/src/+/3743320 Change-Id: If3d8eff200650113bd5b4893bb1636cd9895cb03 Signed-off-by: uzair --- gpu/GLES2/gl2chromium_autogen.h | 4 + gpu/GLES2/gl2extchromium.h | 37 +++++++ gpu/command_buffer/build_gles2_cmd_buffer.py | 15 +++ gpu/command_buffer/client/gles2_c_lib_autogen.h | 26 +++++ .../client/gles2_cmd_helper_autogen.h | 26 +++++ .../client/gles2_implementation_autogen.h | 8 ++ .../client/gles2_implementation_impl_autogen.h | 34 ++++++ .../client/gles2_implementation_unittest_autogen.h | 33 ++++++ .../client/gles2_interface_autogen.h | 5 + .../client/gles2_interface_stub_autogen.h | 5 + .../client/gles2_interface_stub_impl_autogen.h | 8 ++ .../client/gles2_trace_implementation_autogen.h | 5 + .../gles2_trace_implementation_impl_autogen.h | 22 ++++ .../common/gles2_cmd_format_autogen.h | 120 ++++++++++++++++++++ .../common/gles2_cmd_format_test_autogen.h | 41 +++++++ gpu/command_buffer/common/gles2_cmd_ids_autogen.h | 73 ++++++------ gpu/command_buffer/gles2_cmd_buffer_functions.txt | 3 + gpu/command_buffer/service/BUILD.gn | 2 + .../service/command_buffer_task_executor.h | 4 + gpu/command_buffer/service/context_group.cc | 2 + gpu/command_buffer/service/context_group.h | 6 + gpu/command_buffer/service/gles2_cmd_decoder.cc | 122 +++++++++++++++++++++ gpu/command_buffer/service/gles2_cmd_decoder.h | 1 + .../service/gles2_cmd_decoder_autogen.h | 58 ++++++++++ .../service/gles2_cmd_decoder_passthrough.cc | 46 ++++++++ .../service/gles2_cmd_decoder_passthrough.h | 5 + ...gles2_cmd_decoder_passthrough_doer_prototypes.h | 5 + .../service/gles2_cmd_decoder_passthrough_doers.cc | 49 +++++++++ ...es2_cmd_decoder_passthrough_handlers_autogen.cc | 48 ++++++++ gpu/command_buffer/service/image_manager.cc | 38 +++++++ gpu/command_buffer/service/image_manager.h | 42 +++++++ gpu/gles2_conform_support/egl/context.cc | 4 +- gpu/gles2_conform_support/egl/context.h | 2 + gpu/ipc/common/gpu_channel.mojom | 20 ++++ gpu/ipc/in_process_command_buffer.cc | 6 +- gpu/ipc/service/command_buffer_stub.cc | 8 ++ gpu/ipc/service/command_buffer_stub.h | 2 + gpu/ipc/service/gles2_command_buffer_stub.cc | 65 ++++++++++- gpu/ipc/service/gles2_command_buffer_stub.h | 3 + gpu/ipc/service/gpu_channel.cc | 21 ++++ gpu/ipc/service/gpu_channel.h | 11 ++ ui/gl/gl_image.cc | 6 + ui/gl/gl_image.h | 7 ++ 43 files changed, 1007 insertions(+), 41 deletions(-) create mode 100644 gpu/command_buffer/service/image_manager.cc create mode 100644 gpu/command_buffer/service/image_manager.h diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index f0b3a3d..efcb0d37 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -330,6 +330,10 @@ #define glCreateAndConsumeTextureCHROMIUM \ GLES2_GET_FUN(CreateAndConsumeTextureCHROMIUM) #define glBindUniformLocationCHROMIUM GLES2_GET_FUN(BindUniformLocationCHROMIUM) +#define glBindTexImage2DCHROMIUM GLES2_GET_FUN(BindTexImage2DCHROMIUM) +#define glBindTexImage2DWithInternalformatCHROMIUM \ + GLES2_GET_FUN(BindTexImage2DWithInternalformatCHROMIUM) +#define glReleaseTexImage2DCHROMIUM GLES2_GET_FUN(ReleaseTexImage2DCHROMIUM) #define glTraceBeginCHROMIUM GLES2_GET_FUN(TraceBeginCHROMIUM) #define glTraceEndCHROMIUM GLES2_GET_FUN(TraceEndCHROMIUM) #define glDiscardFramebufferEXT GLES2_GET_FUN(DiscardFramebufferEXT) diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index da4583a..44036b8 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h @@ -63,6 +63,43 @@ typedef GLboolean (GL_APIENTRY PFNGLUNMAPBUFFERCHROMIUM) (GLuint target); #endif #endif /* GL_CHROMIUM_pixel_transfer_buffer_object */ +/* GL_CHROMIUM_image */ +#ifndef GL_CHROMIUM_image +#define GL_CHROMIUM_image 1 + +typedef struct _ClientBuffer* ClientBuffer; + +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM(ClientBuffer buffer, + GLsizei width, + GLsizei height, + GLenum internalformat); +GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM(GLuint image_id); +GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM(GLenum target, + GLint imageId); +GL_APICALL void GL_APIENTRY +glBindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId); +GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM(GLenum target, + GLint imageId); +#endif +typedef GLuint(GL_APIENTRYP PFNGLCREATEIMAGECHROMIUMPROC)( + ClientBuffer buffer, + GLsizei width, + GLsizei height, + GLenum internalformat); +typedef void(GL_APIENTRYP PFNGLDESTROYIMAGECHROMIUMPROC)(GLuint image_id); +typedef void(GL_APIENTRYP PFNGLBINDTEXIMAGE2DCHROMIUMPROC)(GLenum target, + GLint imageId); +typedef void(GL_APIENTRYP PFNGLBINDTEXIMAGE2DWITHINTERNALFORMATCHROMIUMPROC)( + GLenum target, + GLenum internalformat, + GLint imageId); +typedef void(GL_APIENTRYP PFNGLRELEASETEXIMAGE2DCHROMIUMPROC)(GLenum target, + GLint imageId); +#endif /* GL_CHROMIUM_image */ + #ifndef GL_RGB_YCRCB_420_CHROMIUM #define GL_RGB_YCRCB_420_CHROMIUM 0x78FA #endif diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 453d713..b8bef5e 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -3885,6 +3885,21 @@ _FUNCTION_INFO = { 'unit_test': False, 'pepper_interface': 'VertexArrayObject', }, + 'BindTexImage2DCHROMIUM': { + 'decoder_func': 'DoBindTexImage2DCHROMIUM', + 'unit_test': False, + 'extension': "CHROMIUM_image", + }, + 'BindTexImage2DWithInternalformatCHROMIUM': { + 'decoder_func': 'DoBindTexImage2DWithInternalformatCHROMIUM', + 'unit_test': False, + 'extension': "CHROMIUM_image", + }, + 'ReleaseTexImage2DCHROMIUM': { + 'decoder_func': 'DoReleaseTexImage2DCHROMIUM', + 'unit_test': False, + 'extension': "CHROMIUM_image", + }, 'IsVertexArrayOES': { 'type': 'Is', 'extension': 'OES_vertex_array_object', diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 161c43e..7114150 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -1546,6 +1546,19 @@ void GL_APIENTRY GLES2BindUniformLocationCHROMIUM(GLuint program, const char* name) { gles2::GetGLContext()->BindUniformLocationCHROMIUM(program, location, name); } +void GL_APIENTRY GLES2BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { + gles2::GetGLContext()->BindTexImage2DCHROMIUM(target, imageId); +} +void GL_APIENTRY +GLES2BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) { + gles2::GetGLContext()->BindTexImage2DWithInternalformatCHROMIUM( + target, internalformat, imageId); +} +void GL_APIENTRY GLES2ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { + gles2::GetGLContext()->ReleaseTexImage2DCHROMIUM(target, imageId); +} void GL_APIENTRY GLES2TraceBeginCHROMIUM(const char* category_name, const char* trace_name) { gles2::GetGLContext()->TraceBeginCHROMIUM(category_name, trace_name); @@ -2908,6 +2921,19 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast(glBindUniformLocationCHROMIUM), }, { + "glBindTexImage2DCHROMIUM", + reinterpret_cast(glBindTexImage2DCHROMIUM), + }, + { + "glBindTexImage2DWithInternalformatCHROMIUM", + reinterpret_cast( + glBindTexImage2DWithInternalformatCHROMIUM), + }, + { + "glReleaseTexImage2DCHROMIUM", + reinterpret_cast(glReleaseTexImage2DCHROMIUM), + }, + { "glTraceBeginCHROMIUM", reinterpret_cast(glTraceBeginCHROMIUM), }, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 7676f76..1de1be1 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -2923,6 +2923,32 @@ void BindUniformLocationCHROMIUMBucket(GLuint program, } } +void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { + gles2::cmds::BindTexImage2DCHROMIUM* c = + GetCmdSpace(); + if (c) { + c->Init(target, imageId); + } +} + +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) { + gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM* c = + GetCmdSpace(); + if (c) { + c->Init(target, internalformat, imageId); + } +} + +void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { + gles2::cmds::ReleaseTexImage2DCHROMIUM* c = + GetCmdSpace(); + if (c) { + c->Init(target, imageId); + } +} + void TraceBeginCHROMIUM(GLuint category_bucket_id, GLuint name_bucket_id) { gles2::cmds::TraceBeginCHROMIUM* c = GetCmdSpace(); diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index b556b23..f1c6a51 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -1090,6 +1090,14 @@ void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) override; +void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; + +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) override; + +void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; + void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override; diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index a8586eb..1b945f0 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -3326,6 +3326,40 @@ void GLES2Implementation::CopySubTextureCHROMIUM( CheckGLError(); } +void GLES2Implementation::BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTexImage2DCHROMIUM(" + << GLES2Util::GetStringTextureBindTarget(target) << ", " + << imageId << ")"); + helper_->BindTexImage2DCHROMIUM(target, imageId); + CheckGLError(); +} + +void GLES2Implementation::BindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint imageId) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG( + "[" << GetLogPrefix() << "] glBindTexImage2DWithInternalformatCHROMIUM(" + << GLES2Util::GetStringTextureBindTarget(target) << ", " + << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " + << imageId << ")"); + helper_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat, + imageId); + CheckGLError(); +} + +void GLES2Implementation::ReleaseTexImage2DCHROMIUM(GLenum target, + GLint imageId) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReleaseTexImage2DCHROMIUM(" + << GLES2Util::GetStringTextureBindTarget(target) << ", " + << imageId << ")"); + helper_->ReleaseTexImage2DCHROMIUM(target, imageId); + CheckGLError(); +} + void GLES2Implementation::DiscardFramebufferEXT(GLenum target, GLsizei count, const GLenum* attachments) { diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 6f17bb34..c2d65f1 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -2874,6 +2874,39 @@ TEST_F(GLES2ImplementationTest, VertexAttribDivisorANGLE) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, BindTexImage2DCHROMIUM) { + struct Cmds { + cmds::BindTexImage2DCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TEXTURE_2D, 2); + + gl_->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, 2); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, BindTexImage2DWithInternalformatCHROMIUM) { + struct Cmds { + cmds::BindTexImage2DWithInternalformatCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TEXTURE_2D, GL_ALPHA, 3); + + gl_->BindTexImage2DWithInternalformatCHROMIUM(GL_TEXTURE_2D, GL_ALPHA, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, ReleaseTexImage2DCHROMIUM) { + struct Cmds { + cmds::ReleaseTexImage2DCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(GL_TEXTURE_2D, 2); + + gl_->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, 2); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, DiscardFramebufferEXT) { GLenum data[2][1] = {{0}}; struct Cmds { diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 9867b5d..d24bf67 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -814,6 +814,11 @@ virtual GLuint CreateAndConsumeTextureCHROMIUM(const GLbyte* mailbox) = 0; virtual void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) = 0; +virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; +virtual void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) = 0; +virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; virtual void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) = 0; virtual void TraceEndCHROMIUM() = 0; diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 0127a24..c799d22 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -790,6 +790,11 @@ GLuint CreateAndConsumeTextureCHROMIUM(const GLbyte* mailbox) override; void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) override; +void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) override; +void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override; void TraceEndCHROMIUM() override; diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 7d3af70..0dc071a 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -1056,6 +1056,14 @@ GLuint GLES2InterfaceStub::CreateAndConsumeTextureCHROMIUM( void GLES2InterfaceStub::BindUniformLocationCHROMIUM(GLuint /* program */, GLint /* location */, const char* /* name */) {} +void GLES2InterfaceStub::BindTexImage2DCHROMIUM(GLenum /* target */, + GLint /* imageId */) {} +void GLES2InterfaceStub::BindTexImage2DWithInternalformatCHROMIUM( + GLenum /* target */, + GLenum /* internalformat */, + GLint /* imageId */) {} +void GLES2InterfaceStub::ReleaseTexImage2DCHROMIUM(GLenum /* target */, + GLint /* imageId */) {} void GLES2InterfaceStub::TraceBeginCHROMIUM(const char* /* category_name */, const char* /* trace_name */) {} void GLES2InterfaceStub::TraceEndCHROMIUM() {} diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 9c075c5..2103e9e 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -790,6 +790,11 @@ GLuint CreateAndConsumeTextureCHROMIUM(const GLbyte* mailbox) override; void BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) override; +void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override; +void BindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId) override; +void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override; void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override; void TraceEndCHROMIUM() override; diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 071fc7c..e22cb21 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -2217,6 +2217,28 @@ void GLES2TraceImplementation::BindUniformLocationCHROMIUM(GLuint program, gl_->BindUniformLocationCHROMIUM(program, location, name); } +void GLES2TraceImplementation::BindTexImage2DCHROMIUM(GLenum target, + GLint imageId) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BindTexImage2DCHROMIUM"); + gl_->BindTexImage2DCHROMIUM(target, imageId); +} + +void GLES2TraceImplementation::BindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint imageId) { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::BindTexImage2DWithInternalformatCHROMIUM"); + gl_->BindTexImage2DWithInternalformatCHROMIUM(target, internalformat, + imageId); +} + +void GLES2TraceImplementation::ReleaseTexImage2DCHROMIUM(GLenum target, + GLint imageId) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ReleaseTexImage2DCHROMIUM"); + gl_->ReleaseTexImage2DCHROMIUM(target, imageId); +} + void GLES2TraceImplementation::TraceBeginCHROMIUM(const char* category_name, const char* trace_name) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::TraceBeginCHROMIUM"); diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 0c8b458..c6e3715 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -14537,6 +14537,126 @@ static_assert( offsetof(BindUniformLocationCHROMIUMBucket, name_bucket_id) == 12, "offset of BindUniformLocationCHROMIUMBucket name_bucket_id should be 12"); +struct BindTexImage2DCHROMIUM { + typedef BindTexImage2DCHROMIUM ValueType; + static const CommandId kCmdId = kBindTexImage2DCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd(); } + + void Init(GLenum _target, GLint _imageId) { + SetHeader(); + target = _target; + imageId = _imageId; + } + + void* Set(void* cmd, GLenum _target, GLint _imageId) { + static_cast(cmd)->Init(_target, _imageId); + return NextCmdAddress(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t imageId; +}; + +static_assert(sizeof(BindTexImage2DCHROMIUM) == 12, + "size of BindTexImage2DCHROMIUM should be 12"); +static_assert(offsetof(BindTexImage2DCHROMIUM, header) == 0, + "offset of BindTexImage2DCHROMIUM header should be 0"); +static_assert(offsetof(BindTexImage2DCHROMIUM, target) == 4, + "offset of BindTexImage2DCHROMIUM target should be 4"); +static_assert(offsetof(BindTexImage2DCHROMIUM, imageId) == 8, + "offset of BindTexImage2DCHROMIUM imageId should be 8"); + +struct BindTexImage2DWithInternalformatCHROMIUM { + typedef BindTexImage2DWithInternalformatCHROMIUM ValueType; + static const CommandId kCmdId = kBindTexImage2DWithInternalformatCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd(); } + + void Init(GLenum _target, GLenum _internalformat, GLint _imageId) { + SetHeader(); + target = _target; + internalformat = _internalformat; + imageId = _imageId; + } + + void* Set(void* cmd, GLenum _target, GLenum _internalformat, GLint _imageId) { + static_cast(cmd)->Init(_target, _internalformat, _imageId); + return NextCmdAddress(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + uint32_t internalformat; + int32_t imageId; +}; + +static_assert(sizeof(BindTexImage2DWithInternalformatCHROMIUM) == 16, + "size of BindTexImage2DWithInternalformatCHROMIUM should be 16"); +static_assert( + offsetof(BindTexImage2DWithInternalformatCHROMIUM, header) == 0, + "offset of BindTexImage2DWithInternalformatCHROMIUM header should be 0"); +static_assert( + offsetof(BindTexImage2DWithInternalformatCHROMIUM, target) == 4, + "offset of BindTexImage2DWithInternalformatCHROMIUM target should be 4"); +static_assert(offsetof(BindTexImage2DWithInternalformatCHROMIUM, + internalformat) == 8, + "offset of BindTexImage2DWithInternalformatCHROMIUM " + "internalformat should be 8"); +static_assert( + offsetof(BindTexImage2DWithInternalformatCHROMIUM, imageId) == 12, + "offset of BindTexImage2DWithInternalformatCHROMIUM imageId should be 12"); + +struct ReleaseTexImage2DCHROMIUM { + typedef ReleaseTexImage2DCHROMIUM ValueType; + static const CommandId kCmdId = kReleaseTexImage2DCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd(); } + + void Init(GLenum _target, GLint _imageId) { + SetHeader(); + target = _target; + imageId = _imageId; + } + + void* Set(void* cmd, GLenum _target, GLint _imageId) { + static_cast(cmd)->Init(_target, _imageId); + return NextCmdAddress(cmd); + } + + gpu::CommandHeader header; + uint32_t target; + int32_t imageId; +}; + +static_assert(sizeof(ReleaseTexImage2DCHROMIUM) == 12, + "size of ReleaseTexImage2DCHROMIUM should be 12"); +static_assert(offsetof(ReleaseTexImage2DCHROMIUM, header) == 0, + "offset of ReleaseTexImage2DCHROMIUM header should be 0"); +static_assert(offsetof(ReleaseTexImage2DCHROMIUM, target) == 4, + "offset of ReleaseTexImage2DCHROMIUM target should be 4"); +static_assert(offsetof(ReleaseTexImage2DCHROMIUM, imageId) == 8, + "offset of ReleaseTexImage2DCHROMIUM imageId should be 8"); + struct TraceBeginCHROMIUM { typedef TraceBeginCHROMIUM ValueType; static const CommandId kCmdId = kTraceBeginCHROMIUM; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 5f45c44..d4b335c 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -4795,6 +4795,47 @@ TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUMBucket) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, BindTexImage2DCHROMIUM) { + cmds::BindTexImage2DCHROMIUM& cmd = + *GetBufferAs(); + void* next_cmd = + cmd.Set(&cmd, static_cast(11), static_cast(12)); + EXPECT_EQ(static_cast(cmds::BindTexImage2DCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast(11), cmd.target); + EXPECT_EQ(static_cast(12), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, BindTexImage2DWithInternalformatCHROMIUM) { + cmds::BindTexImage2DWithInternalformatCHROMIUM& cmd = + *GetBufferAs(); + void* next_cmd = cmd.Set(&cmd, static_cast(11), + static_cast(12), static_cast(13)); + EXPECT_EQ(static_cast( + cmds::BindTexImage2DWithInternalformatCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast(11), cmd.target); + EXPECT_EQ(static_cast(12), cmd.internalformat); + EXPECT_EQ(static_cast(13), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, ReleaseTexImage2DCHROMIUM) { + cmds::ReleaseTexImage2DCHROMIUM& cmd = + *GetBufferAs(); + void* next_cmd = + cmd.Set(&cmd, static_cast(11), static_cast(12)); + EXPECT_EQ(static_cast(cmds::ReleaseTexImage2DCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast(11), cmd.target); + EXPECT_EQ(static_cast(12), cmd.imageId); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, TraceBeginCHROMIUM) { cmds::TraceBeginCHROMIUM& cmd = *GetBufferAs(); void* next_cmd = diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 4a47970..430f843 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -301,41 +301,44 @@ OP(ProduceTextureDirectCHROMIUMImmediate) /* 542 */ \ OP(CreateAndConsumeTextureINTERNALImmediate) /* 543 */ \ OP(BindUniformLocationCHROMIUMBucket) /* 544 */ \ - OP(TraceBeginCHROMIUM) /* 545 */ \ - OP(TraceEndCHROMIUM) /* 546 */ \ - OP(DiscardFramebufferEXTImmediate) /* 547 */ \ - OP(LoseContextCHROMIUM) /* 548 */ \ - OP(DrawBuffersEXTImmediate) /* 549 */ \ - OP(DiscardBackbufferCHROMIUM) /* 550 */ \ - OP(FlushDriverCachesCHROMIUM) /* 551 */ \ - OP(SetActiveURLCHROMIUM) /* 552 */ \ - OP(ContextVisibilityHintCHROMIUM) /* 553 */ \ - OP(CoverageModulationCHROMIUM) /* 554 */ \ - OP(BlendBarrierKHR) /* 555 */ \ - OP(BindFragDataLocationIndexedEXTBucket) /* 556 */ \ - OP(BindFragDataLocationEXTBucket) /* 557 */ \ - OP(GetFragDataIndexEXT) /* 558 */ \ - OP(InitializeDiscardableTextureCHROMIUM) /* 559 */ \ - OP(UnlockDiscardableTextureCHROMIUM) /* 560 */ \ - OP(LockDiscardableTextureCHROMIUM) /* 561 */ \ - OP(WindowRectanglesEXTImmediate) /* 562 */ \ - OP(CreateGpuFenceINTERNAL) /* 563 */ \ - OP(WaitGpuFenceCHROMIUM) /* 564 */ \ - OP(DestroyGpuFenceCHROMIUM) /* 565 */ \ - OP(SetReadbackBufferShadowAllocationINTERNAL) /* 566 */ \ - OP(FramebufferTextureMultiviewOVR) /* 567 */ \ - OP(MaxShaderCompilerThreadsKHR) /* 568 */ \ - OP(CreateAndTexStorage2DSharedImageINTERNALImmediate) /* 569 */ \ - OP(BeginSharedImageAccessDirectCHROMIUM) /* 570 */ \ - OP(EndSharedImageAccessDirectCHROMIUM) /* 571 */ \ - OP(EnableiOES) /* 572 */ \ - OP(DisableiOES) /* 573 */ \ - OP(BlendEquationiOES) /* 574 */ \ - OP(BlendEquationSeparateiOES) /* 575 */ \ - OP(BlendFunciOES) /* 576 */ \ - OP(BlendFuncSeparateiOES) /* 577 */ \ - OP(ColorMaskiOES) /* 578 */ \ - OP(IsEnablediOES) /* 579 */ + OP(BindTexImage2DCHROMIUM) /* 545 */ \ + OP(BindTexImage2DWithInternalformatCHROMIUM) /* 546 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 547 */ \ + OP(TraceBeginCHROMIUM) /* 548 */ \ + OP(TraceEndCHROMIUM) /* 549 */ \ + OP(DiscardFramebufferEXTImmediate) /* 550 */ \ + OP(LoseContextCHROMIUM) /* 551 */ \ + OP(DrawBuffersEXTImmediate) /* 552 */ \ + OP(DiscardBackbufferCHROMIUM) /* 553 */ \ + OP(FlushDriverCachesCHROMIUM) /* 554 */ \ + OP(SetActiveURLCHROMIUM) /* 555 */ \ + OP(ContextVisibilityHintCHROMIUM) /* 556 */ \ + OP(CoverageModulationCHROMIUM) /* 557 */ \ + OP(BlendBarrierKHR) /* 558 */ \ + OP(BindFragDataLocationIndexedEXTBucket) /* 559 */ \ + OP(BindFragDataLocationEXTBucket) /* 560 */ \ + OP(GetFragDataIndexEXT) /* 561 */ \ + OP(InitializeDiscardableTextureCHROMIUM) /* 562 */ \ + OP(UnlockDiscardableTextureCHROMIUM) /* 563 */ \ + OP(LockDiscardableTextureCHROMIUM) /* 564 */ \ + OP(WindowRectanglesEXTImmediate) /* 565 */ \ + OP(CreateGpuFenceINTERNAL) /* 566 */ \ + OP(WaitGpuFenceCHROMIUM) /* 567 */ \ + OP(DestroyGpuFenceCHROMIUM) /* 568 */ \ + OP(SetReadbackBufferShadowAllocationINTERNAL) /* 569 */ \ + OP(FramebufferTextureMultiviewOVR) /* 570 */ \ + OP(MaxShaderCompilerThreadsKHR) /* 571 */ \ + OP(CreateAndTexStorage2DSharedImageINTERNALImmediate) /* 572 */ \ + OP(BeginSharedImageAccessDirectCHROMIUM) /* 573 */ \ + OP(EndSharedImageAccessDirectCHROMIUM) /* 574 */ \ + OP(EnableiOES) /* 575 */ \ + OP(DisableiOES) /* 576 */ \ + OP(BlendEquationiOES) /* 577 */ \ + OP(BlendEquationSeparateiOES) /* 578 */ \ + OP(BlendFunciOES) /* 579 */ \ + OP(BlendFuncSeparateiOES) /* 580 */ \ + OP(ColorMaskiOES) /* 581 */ \ + OP(IsEnablediOES) /* 582 */ enum CommandId { kOneBeforeStartPoint = diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index 590507a..a2801cd 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt @@ -323,6 +323,9 @@ GL_APICALL void GL_APIENTRY glProduceTextureDirectCHROMIUM (GLidBindText GL_APICALL GLuint GL_APIENTRY glCreateAndConsumeTextureCHROMIUM (const GLbyte* mailbox); GL_APICALL void GL_APIENTRY glCreateAndConsumeTextureINTERNAL (GLuint texture, const GLbyte* mailbox); GL_APICALL void GL_APIENTRY glBindUniformLocationCHROMIUM (GLidProgram program, GLint location, const char* name); +GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); +GL_APICALL void GL_APIENTRY glBindTexImage2DWithInternalformatCHROMIUM (GLenumTextureBindTarget target, GLenumTextureInternalFormat internalformat, GLint imageId); +GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); GL_APICALL void GL_APIENTRY glTraceBeginCHROMIUM (const char* category_name, const char* trace_name); GL_APICALL void GL_APIENTRY glTraceEndCHROMIUM (void); GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenumFramebufferTarget target, GLsizei count, const GLenum* attachments); diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 4632c26..a03eceb 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn @@ -48,6 +48,8 @@ target(link_target_type, "service_sources") { "gpu_switches.h", "image_factory.cc", "image_factory.h", + "image_manager.cc", + "image_manager.h", "mailbox_manager.h", "memory_tracking.cc", "memory_tracking.h", diff --git a/gpu/command_buffer/service/command_buffer_task_executor.h b/gpu/command_buffer/service/command_buffer_task_executor.h index 56f94e7..b01d55f 100644 --- a/gpu/command_buffer/service/command_buffer_task_executor.h +++ b/gpu/command_buffer/service/command_buffer_task_executor.h @@ -13,6 +13,7 @@ #include "gpu/command_buffer/common/activity_flags.h" #include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/framebuffer_completeness_cache.h" +#include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/passthrough_discardable_manager.h" #include "gpu/command_buffer/service/sequence_id.h" #include "gpu/command_buffer/service/service_discardable_manager.h" @@ -91,6 +92,8 @@ class GPU_GLES2_EXPORT CommandBufferTaskExecutor { MailboxManager* mailbox_manager() const { return mailbox_manager_; } // Not const because these return inner pointers. + + gles2::ImageManager* image_manager() { return &image_manager_; } ServiceDiscardableManager* discardable_manager() { return &discardable_manager_; } @@ -118,6 +121,7 @@ class GPU_GLES2_EXPORT CommandBufferTaskExecutor { gl::GLSurfaceFormat share_group_surface_format_; std::unique_ptr owned_program_cache_; raw_ptr program_cache_; + gles2::ImageManager image_manager_; ServiceDiscardableManager discardable_manager_; PassthroughDiscardableManager passthrough_discardable_manager_; gles2::ShaderTranslatorCache shader_translator_cache_; diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 0638760..b714271 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -76,6 +76,7 @@ ContextGroup::ContextGroup( FramebufferCompletenessCache* framebuffer_completeness_cache, const scoped_refptr& feature_info, bool bind_generates_resource, + ImageManager* image_manager, gpu::ImageFactory* image_factory, gl::ProgressReporter* progress_reporter, const GpuFeatureInfo& gpu_feature_info, @@ -118,6 +119,7 @@ ContextGroup::ContextGroup( uniform_buffer_offset_alignment_(1u), program_cache_(nullptr), feature_info_(feature_info), + image_manager_(image_manager), image_factory_(image_factory), use_passthrough_cmd_decoder_(false), passthrough_resources_(new PassthroughResources), diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 0aaaf27..6760a38 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -44,6 +44,7 @@ namespace gles2 { class ProgramCache; class BufferManager; +class ImageManager; class RenderbufferManager; class ProgramManager; class SamplerManager; @@ -68,6 +69,7 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted { FramebufferCompletenessCache* framebuffer_completeness_cache, const scoped_refptr& feature_info, bool bind_generates_resource, + ImageManager* image_manager, gpu::ImageFactory* image_factory, gl::ProgressReporter* progress_reporter, const GpuFeatureInfo& gpu_feature_info, @@ -164,6 +166,8 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted { return feature_info_.get(); } + ImageManager* image_manager() const { return image_manager_; } + gpu::ImageFactory* image_factory() const { return image_factory_; } const GpuPreferences& gpu_preferences() const { @@ -309,6 +313,8 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted { scoped_refptr feature_info_; + raw_ptr image_manager_; + raw_ptr image_factory_; std::vector> decoders_; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0f2c253..43e00a8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -65,6 +65,7 @@ #include "gpu/command_buffer/service/gpu_state_tracer.h" #include "gpu/command_buffer/service/gpu_tracer.h" #include "gpu/command_buffer/service/image_factory.h" +#include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" @@ -963,6 +964,8 @@ class GLES2DecoderImpl : public GLES2Decoder, return vertex_array_manager_.get(); } + ImageManager* image_manager() { return group_->image_manager(); } + MemoryTracker* memory_tracker() { return group_->memory_tracker(); } @@ -1221,6 +1224,16 @@ class GLES2DecoderImpl : public GLES2Decoder, uint32_t texture_target, gl::GLImage* image, bool can_bind_to_sampler) override; + void DoBindTexImage2DCHROMIUM(GLenum target, GLint image_id); + void DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint image_id); + // Common implementation of DoBindTexImage2DCHROMIUM entry points. + void BindTexImage2DCHROMIUMImpl(const char* function_name, + GLenum target, + GLenum internalformat, + GLint image_id); + void DoReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id); void DoTraceEndCHROMIUM(void); @@ -18586,6 +18599,115 @@ void GLES2DecoderImpl::BindImage(uint32_t client_texture_id, : gpu::gles2::Texture::UNBOUND); } +void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(GLenum target, GLint image_id) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM"); + + BindTexImage2DCHROMIUMImpl("glBindTexImage2DCHROMIUM", target, 0, image_id); +} + +void GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint image_id) { + TRACE_EVENT0("gpu", + "GLES2DecoderImpl::DoBindTexImage2DWithInternalformatCHROMIUM"); + + BindTexImage2DCHROMIUMImpl("glBindTexImage2DWithInternalformatCHROMIUM", + target, internalformat, image_id); +} + +void GLES2DecoderImpl::BindTexImage2DCHROMIUMImpl(const char* function_name, + GLenum target, + GLenum internalformat, + GLint image_id) { + if (target == GL_TEXTURE_CUBE_MAP) { + LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, function_name, "invalid target"); + return; + } + + // Default target might be conceptually valid, but disallow it to avoid + // accidents. + TextureRef* texture_ref = + texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); + if (!texture_ref) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "no texture bound"); + return; + } + + gl::GLImage* image = image_manager()->LookupImage(image_id); + if (!image) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, + "no image found with the given ID"); + return; + } + + Texture::ImageState image_state = Texture::UNBOUND; + + if (image->ShouldBindOrCopy() == gl::GLImage::BIND) { + ScopedGLErrorSuppressor suppressor( + "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", error_state_.get()); + + // Note: We fallback to using CopyTexImage() before the texture is used + // when BindTexImage() fails. + if (internalformat) { + if (image->BindTexImageWithInternalformat(target, internalformat)) + image_state = Texture::BOUND; + } else { + if (image->BindTexImage(target)) + image_state = Texture::BOUND; + } + } + + gfx::Size size = image->GetSize(); + GLenum texture_internalformat = + internalformat ? internalformat : image->GetInternalFormat(); + texture_manager()->SetLevelInfo(texture_ref, target, 0, + texture_internalformat, size.width(), + size.height(), 1, 0, image->GetDataFormat(), + image->GetDataType(), gfx::Rect(size)); + texture_manager()->SetLevelImage(texture_ref, target, 0, image, image_state); +} + +void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(GLenum target, + GLint image_id) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); + + // Default target might be conceptually valid, but disallow it to avoid + // accidents. + TextureRef* texture_ref = + texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target); + if (!texture_ref) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReleaseTexImage2DCHROMIUM", + "no texture bound"); + return; + } + + gl::GLImage* image = image_manager()->LookupImage(image_id); + if (!image) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReleaseTexImage2DCHROMIUM", + "no image found with the given ID"); + return; + } + + Texture::ImageState image_state; + + // Do nothing when image is not currently bound. + if (texture_ref->texture()->GetLevelImage(target, 0, &image_state) != image) + return; + + if (image_state == Texture::BOUND) { + ScopedGLErrorSuppressor suppressor( + "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", error_state_.get()); + + image->ReleaseTexImage(target); + texture_manager()->SetLevelInfo(texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0, + GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect()); + } + + texture_manager()->SetLevelImage(texture_ref, target, 0, nullptr, + Texture::UNBOUND); +} + error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index dc7f727..62bf9e9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -46,6 +46,7 @@ class CopyTexImageResourceManager; class CopyTextureCHROMIUMResourceManager; class FramebufferManager; class GLES2Util; +class ImageManager; class Logger; class Outputter; class ShaderTranslatorInterface; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index c07937b..e45bf73 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -5026,6 +5026,64 @@ error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureINTERNALImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::BindTexImage2DCHROMIUM& c = + *static_cast( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(c.imageId); + if (!validators_->texture_bind_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glBindTexImage2DCHROMIUM", target, + "target"); + return error::kNoError; + } + DoBindTexImage2DCHROMIUM(target, imageId); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleBindTexImage2DWithInternalformatCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM& c = + *static_cast(cmd_data); + GLenum target = static_cast(c.target); + GLenum internalformat = static_cast(c.internalformat); + GLint imageId = static_cast(c.imageId); + if (!validators_->texture_bind_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glBindTexImage2DWithInternalformatCHROMIUM", target, "target"); + return error::kNoError; + } + if (!validators_->texture_internal_format.IsValid(internalformat)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glBindTexImage2DWithInternalformatCHROMIUM", internalformat, + "internalformat"); + return error::kNoError; + } + DoBindTexImage2DWithInternalformatCHROMIUM(target, internalformat, imageId); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::ReleaseTexImage2DCHROMIUM& c = + *static_cast( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(c.imageId); + if (!validators_->texture_bind_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glReleaseTexImage2DCHROMIUM", target, + "target"); + return error::kNoError; + } + DoReleaseTexImage2DCHROMIUM(target, imageId); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleTraceEndCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index ab2f90a..c716981 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc @@ -3012,6 +3012,52 @@ error::Error GLES2DecoderPassthroughImpl::HandleSetActiveURLCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderPassthroughImpl::BindTexImage2DCHROMIUMImpl( + GLenum target, + GLenum internalformat, + GLint imageId) { + TextureTarget target_enum = GLenumToTextureTarget(target); + if (target_enum == TextureTarget::kCubeMap || + target_enum == TextureTarget::kUnkown) { + InsertError(GL_INVALID_ENUM, "Invalid target"); + return error::kNoError; + } + + gl::GLImage* image = group_->image_manager()->LookupImage(imageId); + if (image == nullptr) { + InsertError(GL_INVALID_OPERATION, "No image found with the given ID"); + return error::kNoError; + } + + const BoundTexture& bound_texture = + bound_textures_[static_cast(target_enum)][active_texture_unit_]; + if (bound_texture.texture == nullptr) { + InsertError(GL_INVALID_OPERATION, "No texture bound"); + return error::kNoError; + } + + if (image->ShouldBindOrCopy() == gl::GLImage::BIND) { + if (internalformat) + image->BindTexImageWithInternalformat(target, internalformat); + else + image->BindTexImage(target); + } else { + image->CopyTexImage(target); + } + + // Target is already validated + UpdateTextureSizeFromTarget(target); + + DCHECK(bound_texture.texture != nullptr); + bound_texture.texture->SetLevelImage(target, 0, image); + + // If there was any GLImage bound to |target| on this texture unit, then + // forget it. + RemovePendingBindingTexture(target, active_texture_unit_); + + return error::kNoError; +} + void GLES2DecoderPassthroughImpl::VerifyServiceTextureObjectsExist() { resources_->texture_object_map.ForEach( [this](GLuint client_id, scoped_refptr texture) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index e46b8ae..2e791c8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h @@ -25,6 +25,7 @@ #include "gpu/command_buffer/service/client_service_map.h" #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/passthrough_abstract_texture_impl.h" @@ -465,6 +466,10 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl // up-to-date. void LazilyUpdateCurrentlyBoundElementArrayBuffer(); + error::Error BindTexImage2DCHROMIUMImpl(GLenum target, + GLenum internalformat, + GLint image_id); + void VerifyServiceTextureObjectsExist(); bool IsEmulatedFramebufferBound(GLenum target) const; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 3a96342..cd4a3e0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h @@ -873,6 +873,11 @@ error::Error DoCreateAndConsumeTextureINTERNAL(GLuint texture_client_id, error::Error DoBindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name); +error::Error DoBindTexImage2DCHROMIUM(GLenum target, GLint imageId); +error::Error DoBindTexImage2DWithInternalformatCHROMIUM(GLenum target, + GLenum internalformat, + GLint imageId); +error::Error DoReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId); error::Error DoTraceBeginCHROMIUM(const char* category_name, const char* trace_name); error::Error DoTraceEndCHROMIUM(); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 9b09ddf..9b51b08 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc @@ -4572,6 +4572,55 @@ error::Error GLES2DecoderPassthroughImpl::DoBindUniformLocationCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderPassthroughImpl::DoBindTexImage2DCHROMIUM( + GLenum target, + GLint imageId) { + return BindTexImage2DCHROMIUMImpl(target, 0, imageId); +} + +error::Error +GLES2DecoderPassthroughImpl::DoBindTexImage2DWithInternalformatCHROMIUM( + GLenum target, + GLenum internalformat, + GLint imageId) { + return BindTexImage2DCHROMIUMImpl(target, internalformat, imageId); +} + +error::Error GLES2DecoderPassthroughImpl::DoReleaseTexImage2DCHROMIUM( + GLenum target, + GLint imageId) { + TextureTarget target_enum = GLenumToTextureTarget(target); + if (target_enum == TextureTarget::kCubeMap || + target_enum == TextureTarget::kUnkown) { + InsertError(GL_INVALID_ENUM, "Invalid target"); + return error::kNoError; + } + + const BoundTexture& bound_texture = + bound_textures_[static_cast(target_enum)][active_texture_unit_]; + if (bound_texture.texture == nullptr) { + InsertError(GL_INVALID_OPERATION, "No texture bound"); + return error::kNoError; + } + + gl::GLImage* image = group_->image_manager()->LookupImage(imageId); + if (image == nullptr) { + InsertError(GL_INVALID_OPERATION, "No image found with the given ID"); + return error::kNoError; + } + + // Only release the image if it is currently bound + if (bound_texture.texture->GetLevelImage(target, 0) == image) { + image->ReleaseTexImage(target); + bound_texture.texture->SetLevelImage(target, 0, nullptr); + } + + // Target is already validated + UpdateTextureSizeFromTarget(target); + + return error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl::DoTraceBeginCHROMIUM( const char* category_name, const char* trace_name) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 09295b0..e52e094 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc @@ -4302,6 +4302,54 @@ GLES2DecoderPassthroughImpl::HandleCreateAndConsumeTextureINTERNALImmediate( return error::kNoError; } +error::Error GLES2DecoderPassthroughImpl::HandleBindTexImage2DCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::BindTexImage2DCHROMIUM& c = + *static_cast( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(c.imageId); + error::Error error = DoBindTexImage2DCHROMIUM(target, imageId); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + +error::Error +GLES2DecoderPassthroughImpl::HandleBindTexImage2DWithInternalformatCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::BindTexImage2DWithInternalformatCHROMIUM& c = + *static_cast(cmd_data); + GLenum target = static_cast(c.target); + GLenum internalformat = static_cast(c.internalformat); + GLint imageId = static_cast(c.imageId); + error::Error error = DoBindTexImage2DWithInternalformatCHROMIUM( + target, internalformat, imageId); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + +error::Error GLES2DecoderPassthroughImpl::HandleReleaseTexImage2DCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::ReleaseTexImage2DCHROMIUM& c = + *static_cast( + cmd_data); + GLenum target = static_cast(c.target); + GLint imageId = static_cast(c.imageId); + error::Error error = DoReleaseTexImage2DCHROMIUM(target, imageId); + if (error != error::kNoError) { + return error; + } + return error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl::HandleTraceEndCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) { diff --git a/gpu/command_buffer/service/image_manager.cc b/gpu/command_buffer/service/image_manager.cc new file mode 100644 index 0000000..d7ca6d0 --- /dev/null +++ b/gpu/command_buffer/service/image_manager.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/image_manager.h" + +#include + +#include "base/check.h" +#include "ui/gl/gl_image.h" + +namespace gpu { +namespace gles2 { + +ImageManager::ImageManager() = default; + +ImageManager::~ImageManager() = default; + +void ImageManager::AddImage(gl::GLImage* image, int32_t service_id) { + DCHECK(images_.find(service_id) == images_.end()); + images_[service_id] = image; +} + +void ImageManager::RemoveImage(int32_t service_id) { + DCHECK(images_.find(service_id) != images_.end()); + images_.erase(service_id); +} + +gl::GLImage* ImageManager::LookupImage(int32_t service_id) { + GLImageMap::const_iterator iter = images_.find(service_id); + if (iter != images_.end()) + return iter->second.get(); + + return nullptr; +} + +} // namespace gles2 +} // namespace gpu diff --git a/gpu/command_buffer/service/image_manager.h b/gpu/command_buffer/service/image_manager.h new file mode 100644 index 0000000..8397eee --- /dev/null +++ b/gpu/command_buffer/service/image_manager.h @@ -0,0 +1,42 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_ + +#include + +#include + +#include "base/memory/ref_counted.h" +#include "gpu/gpu_export.h" + +namespace gl { +class GLImage; +} + +namespace gpu { +namespace gles2 { + +// This class keeps track of the images and their state. +class GPU_EXPORT ImageManager { + public: + ImageManager(); + ~ImageManager(); + ImageManager(const ImageManager&) = delete; + ImageManager& operator=(const ImageManager&) = delete; + + void AddImage(gl::GLImage* image, int32_t service_id); + void RemoveImage(int32_t service_id); + gl::GLImage* LookupImage(int32_t service_id); + + private: + typedef std::unordered_map> GLImageMap; + GLImageMap images_; +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_ diff --git a/gpu/gles2_conform_support/egl/context.cc b/gpu/gles2_conform_support/egl/context.cc index 35fe874..9dfd81f 100644 --- a/gpu/gles2_conform_support/egl/context.cc +++ b/gpu/gles2_conform_support/egl/context.cc @@ -255,8 +255,8 @@ bool Context::CreateService(gl::GLSurface* gl_surface) { scoped_refptr group(new gpu::gles2::ContextGroup( gpu_preferences, true, &mailbox_manager_, nullptr /* memory_tracker */, &translator_cache_, &completeness_cache_, feature_info, true, - nullptr /* image_factory */, nullptr /* progress_reporter */, - gpu_feature_info, &discardable_manager_, + &image_manager_, nullptr /* image_factory */, + nullptr /* progress_reporter */, gpu_feature_info, &discardable_manager_, &passthrough_discardable_manager_, &shared_image_manager_)); auto command_buffer = std::make_unique(); diff --git a/gpu/gles2_conform_support/egl/context.h b/gpu/gles2_conform_support/egl/context.h index f8d0b38..54dbc99 100644 --- a/gpu/gles2_conform_support/egl/context.h +++ b/gpu/gles2_conform_support/egl/context.h @@ -15,6 +15,7 @@ #include "gpu/command_buffer/service/command_buffer_direct.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gpu_tracer.h" +#include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager_impl.h" #include "gpu/command_buffer/service/passthrough_discardable_manager.h" #include "gpu/command_buffer/service/service_discardable_manager.h" @@ -116,6 +117,7 @@ class Context : public base::RefCountedThreadSafe, gpu::gles2::MailboxManagerImpl mailbox_manager_; gpu::gles2::TraceOutputter outputter_; + gpu::gles2::ImageManager image_manager_; gpu::ServiceDiscardableManager discardable_manager_; gpu::PassthroughDiscardableManager passthrough_discardable_manager_; gpu::SharedImageManager shared_image_manager_; diff --git a/gpu/ipc/common/gpu_channel.mojom b/gpu/ipc/common/gpu_channel.mojom index 717c9f0..e83f981 100644 --- a/gpu/ipc/common/gpu_channel.mojom +++ b/gpu/ipc/common/gpu_channel.mojom @@ -238,6 +238,15 @@ interface GpuChannel { ReleaseSysmemBufferCollection(mojo_base.mojom.UnguessableToken id); }; +struct CreateImageParams { + int32 id; + gfx.mojom.GpuMemoryBufferHandle gpu_memory_buffer; + gfx.mojom.Size size; + gfx.mojom.BufferFormat format; + gfx.mojom.BufferPlane plane; + uint64 image_release_count; +}; + // Interface used to issue commands to a specific CommandBuffer instance in the // GPU process. interface CommandBuffer { @@ -258,6 +267,17 @@ interface CommandBuffer { // Requests retrieval of a GpuFenceHandle by ID. GetGpuFenceHandle(uint32 id) => (gfx.mojom.GpuFenceHandle? fence_handle); + // Creates an image from an existing gpu memory buffer. The id that can be + // used to identify the image from a command buffer. + // + // TODO(crbug.com/1216120): Remove this once CreateImageCHROMIUM is gone. + CreateImage(CreateImageParams params); + + // Destroys a previously created image identified by `id`. + // + // TODO(crbug.com/1216120): Remove this once CreateImageCHROMIUM is gone. + DestroyImage(int32 id); + // Asynchronously waits until the SyncToken is signaled, then sends a // corresponding SignalAck on the CommandBufferClient interface, using // `signal_id` to identify this request. diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 0d9a6b3..8bf1b65 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc @@ -249,9 +249,9 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread( task_executor_->mailbox_manager(), std::move(memory_tracker), task_executor_->shader_translator_cache(), task_executor_->framebuffer_completeness_cache(), feature_info, - params.attribs.bind_generates_resource, params.image_factory, - nullptr /* progress_reporter */, task_executor_->gpu_feature_info(), - task_executor_->discardable_manager(), + params.attribs.bind_generates_resource, task_executor_->image_manager(), + params.image_factory, nullptr /* progress_reporter */, + task_executor_->gpu_feature_info(), task_executor_->discardable_manager(), task_executor_->passthrough_discardable_manager(), task_executor_->shared_image_manager()); diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index 88de4e9..8c87d63 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc @@ -544,6 +544,14 @@ void CommandBufferStub::GetGpuFenceHandle(uint32_t id, std::move(callback).Run(gfx::GpuFenceHandle()); } +void CommandBufferStub::CreateImage(mojom::CreateImageParamsPtr params) { + DLOG(ERROR) << "CreateImage unsupported."; +} + +void CommandBufferStub::DestroyImage(int32_t id) { + DLOG(ERROR) << "DestroyImage unsupported."; +} + void CommandBufferStub::OnDestroyTransferBuffer(int32_t id) { TRACE_EVENT0("gpu", "CommandBufferStub::OnDestroyTransferBuffer"); diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h index 9089132..2d1b5cd 100644 --- a/gpu/ipc/service/command_buffer_stub.h +++ b/gpu/ipc/service/command_buffer_stub.h @@ -220,6 +220,8 @@ class GPU_IPC_SERVICE_EXPORT CommandBufferStub gfx::GpuFenceHandle handle) override; void GetGpuFenceHandle(uint32_t id, GetGpuFenceHandleCallback callback) override; + void CreateImage(mojom::CreateImageParamsPtr params) override; + void DestroyImage(int32_t id) override; void SignalSyncToken(const SyncToken& sync_token, uint32_t id) override; void SignalQuery(uint32_t query, uint32_t id) override; void BindMediaReceiver(mojo::GenericPendingAssociatedReceiver receiver, diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc index be556d7..cd81adc 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/gpu/ipc/service/gles2_command_buffer_stub.cc @@ -26,6 +26,7 @@ #include "gpu/command_buffer/service/gl_context_virtual.h" #include "gpu/command_buffer/service/gl_state_restorer_impl.h" #include "gpu/command_buffer/service/gpu_fence_manager.h" +#include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" @@ -110,7 +111,7 @@ gpu::ContextResult GLES2CommandBufferStub::Initialize( manager->mailbox_manager(), CreateMemoryTracker(), manager->shader_translator_cache(), manager->framebuffer_completeness_cache(), feature_info, - init_params.attribs.bind_generates_resource, + init_params.attribs.bind_generates_resource, channel_->image_manager(), gmb_factory ? gmb_factory->AsImageFactory() : nullptr, manager->watchdog() /* progress_reporter */, manager->gpu_feature_info(), manager->discardable_manager(), @@ -508,6 +509,68 @@ void GLES2CommandBufferStub::GetGpuFenceHandle( std::move(callback).Run(std::move(handle)); } +void GLES2CommandBufferStub::CreateImage(mojom::CreateImageParamsPtr params) { + TRACE_EVENT0("gpu", "GLES2CommandBufferStub::OnCreateImage"); + const int32_t id = params->id; + const gfx::Size& size = params->size; + const gfx::BufferFormat& format = params->format; + const gfx::BufferPlane& plane = params->plane; + const uint64_t image_release_count = params->image_release_count; + ScopedContextOperation operation(*this); + if (!operation.is_context_current()) + return; + + gles2::ImageManager* image_manager = channel_->image_manager(); + DCHECK(image_manager); + if (image_manager->LookupImage(id)) { + LOG(ERROR) << "Image already exists with same ID."; + return; + } + + if (!gpu::IsImageFromGpuMemoryBufferFormatSupported( + format, gles2_decoder_->GetCapabilities())) { + LOG(ERROR) << "Format is not supported."; + return; + } + + if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, format)) { + LOG(ERROR) << "Invalid image size for format."; + return; + } + + if (!gpu::IsPlaneValidForGpuMemoryBufferFormat(plane, format)) { + LOG(ERROR) << "Invalid plane " << gfx::BufferPlaneToString(plane) << " for " + << gfx::BufferFormatToString(format); + return; + } + + scoped_refptr image = channel()->CreateImageForGpuMemoryBuffer( + std::move(params->gpu_memory_buffer), size, format, plane, + surface_handle_); + if (!image.get()) + return; + + image_manager->AddImage(image.get(), id); + if (image_release_count) + sync_point_client_state_->ReleaseFenceSync(image_release_count); +} + +void GLES2CommandBufferStub::DestroyImage(int32_t id) { + TRACE_EVENT0("gpu", "GLES2CommandBufferStub::OnDestroyImage"); + ScopedContextOperation operation(*this); + if (!operation.is_context_current()) + return; + + gles2::ImageManager* image_manager = channel_->image_manager(); + DCHECK(image_manager); + if (!image_manager->LookupImage(id)) { + LOG(ERROR) << "Image with ID doesn't exist."; + return; + } + + image_manager->RemoveImage(id); +} + void GLES2CommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {} } // namespace gpu diff --git a/gpu/ipc/service/gles2_command_buffer_stub.h b/gpu/ipc/service/gles2_command_buffer_stub.h index 4568fe5..973134f 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.h +++ b/gpu/ipc/service/gles2_command_buffer_stub.h @@ -66,6 +66,9 @@ class GPU_IPC_SERVICE_EXPORT GLES2CommandBufferStub void GetGpuFenceHandle(uint32_t gpu_fence_id, GetGpuFenceHandleCallback callback) override; + void CreateImage(mojom::CreateImageParamsPtr params) override; + void DestroyImage(int32_t id) override; + void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; // The group of contexts that share namespaces with this context. diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index 11b35bf..b00928a 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc @@ -41,6 +41,7 @@ #include "base/unguessable_token.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/service/image_factory.h" +#include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/scheduler.h" @@ -50,6 +51,7 @@ #include "gpu/ipc/service/gles2_command_buffer_stub.h" #include "gpu/ipc/service/gpu_channel_manager.h" #include "gpu/ipc/service/gpu_channel_manager_delegate.h" +#include "gpu/ipc/service/gpu_memory_buffer_factory.h" #include "gpu/ipc/service/image_decode_accelerator_stub.h" #include "gpu/ipc/service/raster_command_buffer_stub.h" #include "gpu/ipc/service/webgpu_command_buffer_stub.h" @@ -541,6 +543,7 @@ GpuChannel::GpuChannel( task_runner_(task_runner), io_task_runner_(io_task_runner), share_group_(share_group), + image_manager_(new gles2::ImageManager()), is_gpu_host_(is_gpu_host), filter_(base::MakeRefCounted( this, @@ -1078,4 +1081,22 @@ uint64_t GpuChannel::GetMemoryUsage() const { return size; } +scoped_refptr GpuChannel::CreateImageForGpuMemoryBuffer( + gfx::GpuMemoryBufferHandle handle, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferPlane plane, + SurfaceHandle surface_handle) { + GpuChannelManager* manager = gpu_channel_manager(); + if (!manager->gpu_memory_buffer_factory()) + return nullptr; + + // TODO(b/220336463): plumb the right color space. + return manager->gpu_memory_buffer_factory() + ->AsImageFactory() + ->CreateImageForGpuMemoryBuffer(std::move(handle), size, format, + gfx::ColorSpace(), plane, client_id_, + surface_handle); +} + } // namespace gpu diff --git a/gpu/ipc/service/gpu_channel.h b/gpu/ipc/service/gpu_channel.h index 49f643b..c877b7b 100644 --- a/gpu/ipc/service/gpu_channel.h +++ b/gpu/ipc/service/gpu_channel.h @@ -36,6 +36,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gl/gl_image.h" #include "ui/gl/gl_share_group.h" #include "ui/gl/gpu_preference.h" @@ -104,6 +105,8 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener, SyncPointManager* sync_point_manager() const { return sync_point_manager_; } + gles2::ImageManager* image_manager() const { return image_manager_.get(); } + const scoped_refptr& task_runner() const { return task_runner_; } @@ -155,6 +158,13 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener, uint64_t GetMemoryUsage() const; + scoped_refptr CreateImageForGpuMemoryBuffer( + gfx::GpuMemoryBufferHandle handle, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferPlane plane, + SurfaceHandle surface_handle); + // Executes a DeferredRequest that was previously received and has now been // scheduled by the scheduler. void ExecuteDeferredRequest(mojom::DeferredRequestParamsPtr params); @@ -285,6 +295,7 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener, // process use. scoped_refptr share_group_; + std::unique_ptr image_manager_; std::unique_ptr shared_image_stub_; const bool is_gpu_host_; diff --git a/ui/gl/gl_image.cc b/ui/gl/gl_image.cc index 18834f4..fca4990 100644 --- a/ui/gl/gl_image.cc +++ b/ui/gl/gl_image.cc @@ -67,6 +67,12 @@ bool GLImage::BindTexImage(unsigned target) { return false; } +bool GLImage::BindTexImageWithInternalformat(unsigned target, + unsigned internalformat) { + NOTREACHED(); + return false; +} + void GLImage::ReleaseTexImage(unsigned target) { NOTREACHED(); } diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index c7b3d98..1c65bcb 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -73,6 +73,13 @@ class GL_EXPORT GLImage : public base::RefCounted { // It is valid for an implementation to always return false. virtual bool BindTexImage(unsigned target); + // Bind image to texture currently bound to |target|, forcing the texture's + // internal format to the specified one. This is a feature not available on + // all platforms. Returns true on success. It is valid for an implementation + // to always return false. + virtual bool BindTexImageWithInternalformat(unsigned target, + unsigned internalformat); + // Release image from texture currently bound to |target|. virtual void ReleaseTexImage(unsigned target); -- 2.7.4 From f5520c6619ee217bbdfe45c0f6ef3b0ae68a0b67 Mon Sep 17 00:00:00 2001 From: Suhaspoornachandra Date: Wed, 11 Jan 2023 10:23:28 +0530 Subject: [PATCH 06/16] [M108 Migration][STT] Speech bring up. Refrence: https://review.tizen.org/gerrit/c/274769/ https://review.tizen.org/gerrit/c/275686/ Change-Id: Ic439f156dc8804d7d2ad7eed59f3bd550153623a Signed-off-by: Suhaspoornachandra --- content/browser/browser_interface_binders.cc | 2 + content/browser/browser_main_loop.cc | 13 +- content/browser/browser_main_loop.h | 8 +- .../speech/speech_recognition_dispatcher_host.cc | 9 + .../speech/speech_recognition_manager_impl.cc | 15 +- .../speech/speech_recognition_manager_impl.h | 12 + content/browser/speech/speech_recognizer.h | 8 + packaging/chromium-efl.spec | 2 + tizen_src/build/BUILD.gn | 32 ++ tizen_src/build/config/BUILD.gn | 3 + tizen_src/build/config/tizen_features.gni | 1 + tizen_src/build/gn_chromiumefl.sh | 1 + .../chromium_impl/content/browser/browser_efl.gni | 22 + .../browser/speech/speech_recognizer_impl_tizen.cc | 533 +++++++++++++++++++++ .../browser/speech/speech_recognizer_impl_tizen.h | 93 ++++ .../tizen_speech_recognition_manager_delegate.cc | 37 ++ .../tizen_speech_recognition_manager_delegate.h | 41 ++ .../efl_integration/content_browser_client_efl.cc | 11 + .../efl_integration/content_browser_client_efl.h | 10 + 19 files changed, 846 insertions(+), 7 deletions(-) create mode 100644 tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc create mode 100644 tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.h create mode 100644 tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.cc create mode 100644 tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.h diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index adac0a4..541cf90 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc @@ -737,10 +737,12 @@ void PopulateFrameBinders(RenderFrameHostImpl* host, mojo::BinderMap* map) { map->Add( base::BindRepeating(&BindSharedWorkerConnector, base::Unretained(host))); +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) map->Add( base::BindRepeating(&SpeechRecognitionDispatcherHost::Create, host->GetProcess()->GetID(), host->GetRoutingID()), GetIOThreadTaskRunner({})); +#endif map->Add(base::BindRepeating( &RenderFrameHostImpl::GetSpeechSynthesis, base::Unretained(host))); diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index eedf4ba..420eca0 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -87,7 +87,6 @@ #include "content/browser/screenlock_monitor/screenlock_monitor.h" #include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h" #include "content/browser/sms/sms_provider.h" -#include "content/browser/speech/speech_recognition_manager_impl.h" #include "content/browser/speech/tts_controller_impl.h" #include "content/browser/startup_data_impl.h" #include "content/browser/startup_task_runner.h" @@ -149,6 +148,10 @@ #include "ui/gfx/font_render_params.h" #include "ui/gfx/switches.h" +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) +#include "content/browser/speech/speech_recognition_manager_impl.h" +#endif + #if defined(USE_AURA) || BUILDFLAG(IS_MAC) #include "content/browser/compositor/image_transport_factory.h" #endif @@ -1111,14 +1114,14 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:MidiService"); midi_service_->Shutdown(); } - +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) { TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:SpeechRecognitionManager"); io_thread_->task_runner()->DeleteSoon( FROM_HERE, speech_recognition_manager_.release()); } - +#endif TtsControllerImpl::GetInstance()->Shutdown(); memory_pressure_monitor_.reset(); @@ -1358,14 +1361,14 @@ void BrowserMainLoop::PostCreateThreadsImpl() { media_stream_manager_ = std::make_unique(audio_system_.get()); } - +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) { TRACE_EVENT0("startup", "BrowserMainLoop::PostCreateThreads:InitSpeechRecognition"); speech_recognition_manager_.reset(new SpeechRecognitionManagerImpl( audio_system_.get(), media_stream_manager_.get())); } - +#endif { TRACE_EVENT0("startup", "BrowserMainLoop::PostCreateThreads::InitUserInputMonitor"); diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 5e2ef10..acc602d 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -93,11 +93,15 @@ class MediaStreamManager; class SaveFileManager; class ScreenlockMonitor; class SmsProvider; -class SpeechRecognitionManagerImpl; + class StartupTaskRunner; class TracingControllerImpl; struct MainFunctionParams; +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) +class SpeechRecognitionManagerImpl; +#endif + namespace responsiveness { class Watcher; } // namespace responsiveness @@ -367,8 +371,10 @@ class CONTENT_EXPORT BrowserMainLoop { std::unique_ptr midi_service_; +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) // Must be deleted on the IO thread. std::unique_ptr speech_recognition_manager_; +#endif #if BUILDFLAG(IS_WIN) std::unique_ptr system_message_window_; diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc index bf5d858..f322ba6 100644 --- a/content/browser/speech/speech_recognition_dispatcher_host.cc +++ b/content/browser/speech/speech_recognition_dispatcher_host.cc @@ -121,6 +121,15 @@ void SpeechRecognitionDispatcherHost::StartRequestOnUI( DCHECK_NE(embedder_render_frame_id, MSG_ROUTING_NONE); } +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + if (SpeechRecognitionManagerImpl::GetInstance()) { + Evas_Object* parent_view = + static_cast(web_contents->GetEflNativeView()); + Evas* evas = evas_object_evas_get(parent_view); + SpeechRecognitionManagerImpl::GetInstance()->SetEvas(evas); + } +#endif + bool filter_profanities = SpeechRecognitionManagerImpl::GetInstance() && SpeechRecognitionManagerImpl::GetInstance()->delegate() && diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc index 0fdb61f..007f645 100644 --- a/content/browser/speech/speech_recognition_manager_impl.cc +++ b/content/browser/speech/speech_recognition_manager_impl.cc @@ -45,6 +45,10 @@ #include "content/browser/speech/speech_recognizer_impl_android.h" #endif +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) && BUILDFLAG(IS_EFL) +#include "content/browser/speech/speech_recognizer_impl_tizen.h" +#endif + namespace content { SpeechRecognitionManager* SpeechRecognitionManager::manager_for_tests_; @@ -180,7 +184,7 @@ int SpeechRecognitionManagerImpl::CreateSession( session->config = config; session->context = config.initial_context; -#if !BUILDFLAG(IS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_EFL) // A SpeechRecognitionEngine (and corresponding Config) is required only // when using SpeechRecognizerImpl, which performs the audio capture and // endpointing in the browser. This is not the case of Android where, not @@ -211,6 +215,15 @@ int SpeechRecognitionManagerImpl::CreateSession( session->recognizer = new SpeechRecognizerImpl( this, audio_system_, session_id, config.continuous, config.interim_results, google_remote_engine); +#elif BUILDFLAG(IS_EFL) +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) + session->recognizer = new SpeechRecognizerImplTizen(this, session_id); +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + session->recognizer->SetEvas(evas_); +#endif +#else + NOTREACHED(); +#endif #else session->recognizer = new SpeechRecognizerImplAndroid(this, session_id); #endif diff --git a/content/browser/speech/speech_recognition_manager_impl.h b/content/browser/speech/speech_recognition_manager_impl.h index 9f26103..6f1b15e 100644 --- a/content/browser/speech/speech_recognition_manager_impl.h +++ b/content/browser/speech/speech_recognition_manager_impl.h @@ -19,6 +19,10 @@ #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-forward.h" #include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h" +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) +#include +#endif + namespace media { class AudioSystem; } @@ -89,6 +93,10 @@ class CONTENT_EXPORT SpeechRecognitionManagerImpl SpeechRecognitionManagerDelegate* delegate() const { return delegate_.get(); } +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + void SetEvas(Evas* evas) { evas_ = evas; } +#endif + protected: // BrowserMainLoop is the only one allowed to instantiate this class. friend class BrowserMainLoop; @@ -185,6 +193,10 @@ class CONTENT_EXPORT SpeechRecognitionManagerImpl std::unique_ptr delegate_; const int requester_id_; +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + Evas* evas_ = nullptr; +#endif + // Used for posting asynchronous tasks (on the IO thread) without worrying // about this class being destroyed in the meanwhile (due to browser shutdown) // since tasks pending on a destroyed WeakPtr are automatically discarded. diff --git a/content/browser/speech/speech_recognizer.h b/content/browser/speech/speech_recognizer.h index 681691d..86822c8 100644 --- a/content/browser/speech/speech_recognizer.h +++ b/content/browser/speech/speech_recognizer.h @@ -10,6 +10,10 @@ #include "base/memory/ref_counted.h" #include "content/common/content_export.h" +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) +#include +#endif + namespace content { class SpeechRecognitionEventListener; @@ -32,6 +36,10 @@ class CONTENT_EXPORT SpeechRecognizer virtual bool IsActive() const = 0; virtual bool IsCapturingAudio() const = 0; +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + virtual void SetEvas(Evas* evas) {} +#endif + protected: friend class base::RefCountedThreadSafe; diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index 01e43e7..baa95b3 100644 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -106,6 +106,7 @@ BuildRequires: pkgconfig(nss) BuildRequires: pkgconfig(scim) BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(stt) BuildRequires: pkgconfig(tts) BuildRequires: pkgconfig(ui-gadget-1) BuildRequires: pkgconfig(vconf) @@ -141,6 +142,7 @@ BuildRequires: pkgconfig(xtst) %endif %if "%{?tizen_profile_name}" == "tv" +BuildRequires: pkgconfig(capi-stt-wrapper-tv) BuildRequires: pkgconfig(vd-win-util) %endif diff --git a/tizen_src/build/BUILD.gn b/tizen_src/build/BUILD.gn index 3fbf271..ce7e0ba 100644 --- a/tizen_src/build/BUILD.gn +++ b/tizen_src/build/BUILD.gn @@ -579,6 +579,38 @@ config("tts-public") { } } +config("capi-stt-wrapper-tv") { + if (tizen_product_tv) { + ldflags = [ "-lcapi-stt-wrapper-tv" ] + } +} + +tizen_pkg_config("libcapi-stt-wrapper-tv") { + packages = [] + if (tizen_product_tv) { + packages = [ "capi-stt-wrapper-tv" ] + } +} + +config("stt") { + if (is_tizen) { + ldflags = [ "-lstt" ] + } +} + +tizen_pkg_config("libstt") { + packages = [] + if (is_tizen) { + packages = [ "stt" ] + } +} + +config("stt-public") { + if (is_tizen) { + cflags = [ "-stt" ] + } +} + config("vconf") { if (is_tizen) { ldflags = [ "-lvconf" ] diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index ed0f2b7..3b4e9c1 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -39,6 +39,9 @@ config("tizen_feature_flags") { "TIZEN_MULTIMEDIA_USE_CAPI_AUDIO_IO", ] } + if (tizen_web_speech_recognition) { + defines += [ "TIZEN_WEB_SPEECH_RECOGNITION" ] + } # TODO: There are X11 dependencies in following condition. # The files need to be implemented based on Wayland. diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index 94b85b2..5e1ec9a 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -46,6 +46,7 @@ declare_args() { tizen_multimedia_support = false tizen_multimedia = false tizen_tbm_support = false + tizen_web_speech_recognition = false } if (is_tizen && tizen_multimedia_support) { diff --git a/tizen_src/build/gn_chromiumefl.sh b/tizen_src/build/gn_chromiumefl.sh index d2e392a..fd9662f 100755 --- a/tizen_src/build/gn_chromiumefl.sh +++ b/tizen_src/build/gn_chromiumefl.sh @@ -221,6 +221,7 @@ add_tizen_flags() { # FIXME: http://165.213.149.170/jira/browse/TWF-610 ADDITIONAL_GN_PARAMETERS+="tizen_multimedia=true proprietary_codecs=true + tizen_web_speech_recognition=true tizen_tbm_support=false " } diff --git a/tizen_src/chromium_impl/content/browser/browser_efl.gni b/tizen_src/chromium_impl/content/browser/browser_efl.gni index b6a1022..2586fa5 100644 --- a/tizen_src/chromium_impl/content/browser/browser_efl.gni +++ b/tizen_src/chromium_impl/content/browser/browser_efl.gni @@ -52,6 +52,19 @@ if (tizen_multimedia_support) { ] } +if (tizen_web_speech_recognition) { + external_content_browser_efl_configs += [ + "//tizen_src/build:stt", + "//tizen_src/build:libstt", + ] + if (tizen_product_tv) { + external_content_browser_efl_configs += [ + "//tizen_src/build:capi-stt-wrapper-tv", + "//tizen_src/build:libcapi-stt-wrapper-tv", + ] + } +} + ############################################################################## # Dependency ############################################################################## @@ -148,3 +161,12 @@ if (tizen_tbm_support) { "//tizen_src/chromium_impl/content/browser/media/browser_mediapacket_manager.h", ] } + +if (tizen_web_speech_recognition) { + external_content_browser_efl_sources += [ + "//tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc", + "//tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.h", + "//tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.cc", + "//tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.h", + ] +} diff --git a/tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc b/tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc new file mode 100644 index 0000000..72e2ac0 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc @@ -0,0 +1,533 @@ +// Copyright 2016 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speech/speech_recognizer_impl_tizen.h" + +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/speech_recognition_event_listener.h" +#include "content/public/browser/speech_recognition_manager.h" +#include "content/public/browser/speech_recognition_session_config.h" +#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h" + +#define RUN_ON_BROWSER_IO_THREAD(METHOD, ...) \ + do { \ + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { \ + GetIOThreadTaskRunner({})->PostTask( \ + FROM_HERE, base::BindOnce(&SpeechRecognizerImplTizen::METHOD, this, \ + ##__VA_ARGS__)); \ + return; \ + } \ + } while (0) + +#define RUN_ON_BROWSER_UI_THREAD(METHOD, ...) \ + do { \ + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { \ + GetUIThreadTaskRunner({})->PostTask( \ + FROM_HERE, base::BindOnce(&SpeechRecognizerImplTizen::METHOD, this, \ + ##__VA_ARGS__)); \ + return; \ + } \ + } while (0) + +#define ENUM_CASE(x) \ + case x: \ + return #x; \ + break + +#if !BUILDFLAG(IS_TIZEN_TV) +#define stt_wrapper_get_error_message stt_get_error_message +#define stt_wrapper_get_state stt_get_state +#define stt_wrapper_destroy stt_destroy +#define stt_wrapper_unset_error_cb stt_unset_error_cb +#define stt_wrapper_unset_state_changed_cb stt_unset_state_changed_cb +#define stt_wrapper_unset_recognition_result_cb stt_unset_recognition_result_cb +#define stt_wrapper_unprepare stt_unprepare +#define stt_wrapper_cancel stt_cancel +#define stt_wrapper_start stt_start +#define stt_wrapper_set_error_cb stt_set_error_cb +#define stt_wrapper_set_state_changed_cb stt_set_state_changed_cb +#define stt_wrapper_set_recognition_result_cb stt_set_recognition_result_cb +#define stt_wrapper_create stt_create +#define stt_wrapper_stop stt_stop +#define stt_wrapper_prepare stt_prepare +#define stt_wrapper_foreach_supported_languages stt_foreach_supported_languages +#endif + +namespace { + +// Replace hyphen "-" in language with underscore "_". CAPI does not +// support language string with hyphen. Example: en-US -> en_US. +// change character case. Example: en_us -> en_US. +std::string GetLanguageString(const std::string& language) { + std::string ret(language); + std::replace(ret.begin(), ret.end(), '-', '_'); + std::transform(ret.begin(), ret.begin() + 2, ret.begin(), ::tolower); + std::transform(ret.end() - 2, ret.end(), ret.end() - 2, ::toupper); + return ret; +} + +const char* GetErrorString(stt_error_e error) { + switch (error) { + ENUM_CASE(STT_ERROR_NONE); + ENUM_CASE(STT_ERROR_OUT_OF_MEMORY); + ENUM_CASE(STT_ERROR_IO_ERROR); + ENUM_CASE(STT_ERROR_INVALID_PARAMETER); + ENUM_CASE(STT_ERROR_TIMED_OUT); + ENUM_CASE(STT_ERROR_RECORDER_BUSY); + ENUM_CASE(STT_ERROR_OUT_OF_NETWORK); + ENUM_CASE(STT_ERROR_PERMISSION_DENIED); + ENUM_CASE(STT_ERROR_NOT_SUPPORTED); + ENUM_CASE(STT_ERROR_INVALID_STATE); + ENUM_CASE(STT_ERROR_INVALID_LANGUAGE); + ENUM_CASE(STT_ERROR_ENGINE_NOT_FOUND); + ENUM_CASE(STT_ERROR_OPERATION_FAILED); + ENUM_CASE(STT_ERROR_NOT_SUPPORTED_FEATURE); + ENUM_CASE(STT_ERROR_RECORDING_TIMED_OUT); + ENUM_CASE(STT_ERROR_NO_SPEECH); + ENUM_CASE(STT_ERROR_IN_PROGRESS_TO_READY); + ENUM_CASE(STT_ERROR_IN_PROGRESS_TO_RECORDING); + ENUM_CASE(STT_ERROR_IN_PROGRESS_TO_PROCESSING); + ENUM_CASE(STT_ERROR_SERVICE_RESET); + }; + + NOTREACHED() << "Invalid stt_error_e! (" << error << ")"; + return ""; +} + +} // namespace + +namespace content { + +blink::mojom::SpeechRecognitionErrorCode GetErrorCode(stt_error_e reason) { + switch (reason) { + case STT_ERROR_NONE: + return blink::mojom::SpeechRecognitionErrorCode::kNone; + case STT_ERROR_NO_SPEECH: + return blink::mojom::SpeechRecognitionErrorCode::kNoSpeech; + case STT_ERROR_RECORDING_TIMED_OUT: + case STT_ERROR_IO_ERROR: + case STT_ERROR_RECORDER_BUSY: + return blink::mojom::SpeechRecognitionErrorCode::kAudioCapture; + case STT_ERROR_OUT_OF_NETWORK: + return blink::mojom::SpeechRecognitionErrorCode::kNetwork; + case STT_ERROR_PERMISSION_DENIED: + return blink::mojom::SpeechRecognitionErrorCode::kNotAllowed; + case STT_ERROR_INVALID_LANGUAGE: + return blink::mojom::SpeechRecognitionErrorCode::kLanguageNotSupported; + case STT_ERROR_NOT_SUPPORTED: + return blink::mojom::SpeechRecognitionErrorCode::kServiceNotAllowed; + default: + return blink::mojom::SpeechRecognitionErrorCode::kAborted; + } +} + +SpeechRecognizerImplTizen::SpeechRecognizerImplTizen( + SpeechRecognitionEventListener* listener, + int session_id) + : SpeechRecognizer(listener, session_id) {} + +SpeechRecognizerImplTizen::~SpeechRecognizerImplTizen() { + base::AutoLock auto_lock(abort_lock_); + if (!handle_ || is_aborted_) + return; + + Destroy(); +} + +void SpeechRecognizerImplTizen::StartRecognition(const std::string& device_id) { + SpeechRecognitionSessionConfig config = + SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id()); + + recognition_type_ = config.interim_results ? STT_RECOGNITION_TYPE_FREE_PARTIAL + : STT_RECOGNITION_TYPE_FREE; + continuous_ = config.continuous; + + if (config.language.empty()) { + LOG(ERROR) << "stt session #" << session_id() + << " language config is empty! Use 'en_US'"; + is_lang_supported_ = true; + language_ = "en_US"; + } else { + language_ = GetLanguageString(config.language); + } + + // Initialize and prepare stt in UI thread + Prepare(); +} + +void SpeechRecognizerImplTizen::Prepare() { + RUN_ON_BROWSER_UI_THREAD(Prepare); + + if (!Initialize()) + return; + + stt_wrapper_foreach_supported_languages(handle_, &OnSupportedLanguages, this); + +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + int err = stt_wrapper_prepare_with_evas(handle_, evas_); +#else + int err = stt_wrapper_prepare(handle_); +#endif + if (STT_ERROR_NONE != err) + HandleSttError(static_cast(err), FROM_HERE); +} + +void SpeechRecognizerImplTizen::AbortRecognition() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + EndRecognition(FROM_HERE); +} + +void SpeechRecognizerImplTizen::StopAudioCapture() { + RUN_ON_BROWSER_UI_THREAD(StopAudioCapture); + continuous_ = false; + + if (GetCurrentState() != STT_STATE_RECORDING) + return; + + int err = stt_wrapper_stop(handle_); + if (STT_ERROR_NONE != err) + HandleSttError(static_cast(err), FROM_HERE); +} + +bool SpeechRecognizerImplTizen::IsActive() const { + return GetCurrentState() > STT_STATE_CREATED ? true : false; +} + +bool SpeechRecognizerImplTizen::IsCapturingAudio() const { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + return GetCurrentState() >= STT_STATE_RECORDING ? true : false; +} + +bool SpeechRecognizerImplTizen::Initialize() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + is_aborted_ = false; + + int err = stt_wrapper_create(&handle_); + if (err != STT_ERROR_NONE) { + HandleSttError(static_cast(err), FROM_HERE); + return false; + } + + err = stt_wrapper_set_recognition_result_cb(handle_, &OnRecognitionResult, + this); + if (err != STT_ERROR_NONE) { + HandleSttError(static_cast(err), FROM_HERE); + return false; + } + + err = stt_wrapper_set_state_changed_cb(handle_, &OnStateChange, this); + if (err != STT_ERROR_NONE) { + HandleSttError(static_cast(err), FROM_HERE); + return false; + } + + err = stt_wrapper_set_error_cb(handle_, &OnError, this); + if (err != STT_ERROR_NONE) { + HandleSttError(static_cast(err), FROM_HERE); + return false; + } + return true; +} + +void SpeechRecognizerImplTizen::StartInternal() { + RUN_ON_BROWSER_UI_THREAD(StartInternal); + + LOG(INFO) << "stt session #" << session_id() + << " language used : " << language_.c_str() + << " type : " << recognition_type_; + if (!is_lang_supported_) { + HandleSttError(STT_ERROR_INVALID_LANGUAGE, FROM_HERE); + return; + } + + int err = stt_wrapper_start(handle_, language_.c_str(), recognition_type_); + if (STT_ERROR_NONE != err) + HandleSttError(static_cast(err), FROM_HERE); +} + +void SpeechRecognizerImplTizen::Destroy() { + RUN_ON_BROWSER_UI_THREAD(Destroy); + if (!handle_) + return; + + is_lang_supported_ = false; + continuous_ = false; + if (GetCurrentState() >= STT_STATE_RECORDING) + stt_wrapper_cancel(handle_); + if (GetCurrentState() == STT_STATE_READY) { +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + stt_wrapper_unprepare_with_evas(handle_, evas_); +#else + stt_wrapper_unprepare(handle_); +#endif + } + if (GetCurrentState() == STT_STATE_CREATED) { + stt_wrapper_unset_recognition_result_cb(handle_); + stt_wrapper_unset_state_changed_cb(handle_); + stt_wrapper_unset_error_cb(handle_); + } + + // Valid states to be called: created, Ready, Recording, Processing +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + int err = stt_wrapper_destroy_with_evas(handle_, evas_); +#else + int err = stt_wrapper_destroy(handle_); +#endif + if (err != STT_ERROR_NONE) + LOG(ERROR) << "stt session #" << session_id() << " stt_destroy failed with " + << GetErrorString(static_cast(err)); + else + handle_ = nullptr; +} + +bool SpeechRecognizerImplTizen::ShouldStartRecognition() const { + return GetCurrentState() >= STT_STATE_READY; +} + +// There is no default stt state. So use |STT_STATE_CREATED| +// This will work as we will use it to determine audio capturing. +stt_state_e SpeechRecognizerImplTizen::GetCurrentState() const { + if (!handle_ || is_aborted_) + return STT_STATE_CREATED; + + stt_state_e state = STT_STATE_CREATED; + int err = stt_wrapper_get_state(handle_, &state); + if (err != STT_ERROR_NONE) + LOG(ERROR) << "stt session #" << session_id() << " stt_get_state FAILED!"; + return state; +} + +void SpeechRecognizerImplTizen::RecognitionResults( + bool no_speech, + std::vector& results) { + { + base::AutoLock auto_lock(abort_lock_); + if (is_aborted_) { + LOG(INFO) << "stt engine is in error state"; + return; + } + } + + if (no_speech && !continuous_) { + HandleSttError(STT_ERROR_NO_SPEECH, FROM_HERE); + return; + } + + listener()->OnRecognitionResults(session_id(), results); +} + +void SpeechRecognizerImplTizen::HandleSttError(stt_error_e error, + const base::Location& location) { + RUN_ON_BROWSER_IO_THREAD(HandleSttError, error, location); + LOG(ERROR) << "stt session #" << session_id() << " error " + << GetErrorString(error) << " from " << location.function_name() + << "(" << location.line_number() << ")"; + { + base::AutoLock auto_lock(abort_lock_); + if (!handle_ || is_aborted_) + return; + } + + blink::mojom::SpeechRecognitionError recognition_error; + recognition_error.code = GetErrorCode(static_cast(error)); + recognition_error.details = blink::mojom::SpeechAudioErrorDetails::kNone; + + listener()->OnRecognitionError(session_id(), recognition_error); + EndRecognition(FROM_HERE); +} + +void SpeechRecognizerImplTizen::HandleSttResultError(const std::string error) { + RUN_ON_BROWSER_IO_THREAD(HandleSttResultError, error); + LOG(ERROR) << "stt session #" << session_id() << " no result as " << error; + + { + base::AutoLock auto_lock(abort_lock_); + if (!handle_ || is_aborted_) + return; + } + + if (error == STT_RESULT_MESSAGE_ERROR_TOO_SOON || + error == STT_RESULT_MESSAGE_ERROR_TOO_SHORT || + error == STT_RESULT_MESSAGE_ERROR_TOO_LONG || + error == STT_RESULT_MESSAGE_ERROR_TOO_QUIET || + error == STT_RESULT_MESSAGE_ERROR_TOO_LOUD || + error == STT_RESULT_MESSAGE_ERROR_TOO_FAST) { + blink::mojom::SpeechRecognitionError recognition_error; + recognition_error.code = blink::mojom::SpeechRecognitionErrorCode::kNoMatch; + recognition_error.details = blink::mojom::SpeechAudioErrorDetails::kNone; + listener()->OnRecognitionError(session_id(), recognition_error); + } +} + +void SpeechRecognizerImplTizen::RecognitionStarted() { + RUN_ON_BROWSER_IO_THREAD(RecognitionStarted); + + listener()->OnAudioStart(session_id()); + listener()->OnSoundStart(session_id()); + listener()->OnRecognitionStart(session_id()); +} + +void SpeechRecognizerImplTizen::AudioCaptureEnd() { + RUN_ON_BROWSER_IO_THREAD(AudioCaptureEnd); + + listener()->OnSoundEnd(session_id()); + listener()->OnAudioEnd(session_id()); +} + +void SpeechRecognizerImplTizen::EndRecognition(const base::Location& location) { + RUN_ON_BROWSER_IO_THREAD(EndRecognition, location); + + { + base::AutoLock auto_lock(abort_lock_); + if (is_aborted_) + return; + + is_aborted_ = true; + } + + LOG(INFO) << "stt session #" << session_id() + << " ending recognition called from " << location.function_name() + << "(" << location.line_number() << ")"; + + if (GetCurrentState() == STT_STATE_RECORDING) + AudioCaptureEnd(); + + listener()->OnRecognitionEnd(session_id()); + Destroy(); +} + +bool SpeechRecognizerImplTizen::OnSupportedLanguages(stt_h stt, + const char* language, + void* user_data) { + SpeechRecognizerImplTizen* speech = + static_cast(user_data); + if (!speech) + return false; + + if (!speech->language_.compare(language)) { + speech->is_lang_supported_ = true; + return false; + } + + return true; +} + +void SpeechRecognizerImplTizen::OnRecognitionResult(stt_h stt, + stt_result_event_e event, + const char** data, + int data_count, + const char* msg, + void* user_data) { + SpeechRecognizerImplTizen* speech = + static_cast(user_data); + if (!speech) + return; + + if (event == STT_RESULT_EVENT_ERROR) { + speech->HandleSttResultError(msg); + return; + } + + bool no_speech = true; + blink::mojom::SpeechRecognitionResultPtr result = + blink::mojom::SpeechRecognitionResult::New(); + for (int i = 0; i < data_count; i++) { + if (data[i] && data[i][0] != ' ') { + no_speech = false; + std::u16string utterance; + base::UTF8ToUTF16(data[i], strlen(data[i]), &utterance); + result->hypotheses.push_back( + blink::mojom::SpeechRecognitionHypothesis::New(utterance, 1.0)); + } + } + + result->is_provisional = + (event == STT_RESULT_EVENT_FINAL_RESULT) ? false : true; + + std::vector results; + results.push_back(std::move(result)); + + speech->RecognitionResults(no_speech, results); +} + +void SpeechRecognizerImplTizen::OnStateChange(stt_h stt, + stt_state_e previous, + stt_state_e current, + void* user_data) { + SpeechRecognizerImplTizen* speech = + static_cast(user_data); + if (!speech) + return; + + LOG(INFO) << "stt session #" << speech->session_id() + << " state change called. Previous : " << previous + << " Current : " << current; + + switch (current) { + case STT_STATE_READY: + switch (previous) { + case STT_STATE_CREATED: + speech->StartInternal(); + break; + case STT_STATE_RECORDING: + if (!speech->is_aborted_) + speech->HandleSttError(STT_ERROR_NO_SPEECH, FROM_HERE); + break; + case STT_STATE_PROCESSING: + // If continuous attribute is true recognition shouldn't stop after + // receiving one final result. So start the recognition again. + if (speech->continuous_) + speech->StartInternal(); + // |stt_recognition_result_cb| is called even when a partial result is + // obtained. So, need to end recognition only when the state change + // is confirmed. + else + speech->EndRecognition(FROM_HERE); + break; + default: + break; + } + break; + case STT_STATE_RECORDING: + speech->RecognitionStarted(); + break; + case STT_STATE_PROCESSING: + speech->AudioCaptureEnd(); + break; + default: + break; + } +} + +void SpeechRecognizerImplTizen::OnError(stt_h stt, + stt_error_e reason, + void* user_data) { + SpeechRecognizerImplTizen* speech = + static_cast(user_data); + if (!speech) + return; +#if BUILDFLAG(IS_TIZEN_TV) + char* error_msg = nullptr; + const std::string no_speech_msg = "voice_engine.error.no_speech"; + int ret = stt_wrapper_get_error_message(stt, &error_msg); + if (ret == STT_ERROR_NONE) { + LOG(INFO) << "stt session #" << speech->session_id() + << "err msg : " << error_msg; + if (!no_speech_msg.compare(error_msg)) + reason = STT_ERROR_NO_SPEECH; + if (error_msg) + free(error_msg); + } else { + LOG(ERROR) << "stt session #" << speech->session_id() + << " stt_wrapper_get_error_message:" + << GetErrorString(static_cast(ret)); + } +#endif + speech->HandleSttError(reason, FROM_HERE); +} + +} // namespace content diff --git a/tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.h b/tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.h new file mode 100644 index 0000000..1cb47ce --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.h @@ -0,0 +1,93 @@ +// Copyright 2016 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_TIZEN_ +#define CONTENT_BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_TIZEN_ + +#include + +#include "base/location.h" +#include "content/browser/speech/speech_recognizer.h" +#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h" + +#if BUILDFLAG(IS_TIZEN_TV) +#include +#if defined(USE_WAYLAND) +#include +#endif +#else +#include +#endif + +namespace content { + +class CONTENT_EXPORT SpeechRecognizerImplTizen : public SpeechRecognizer { + public: + SpeechRecognizerImplTizen(SpeechRecognitionEventListener* listener, + int session_id); + + // SpeechRecognizer methods. + void StartRecognition(const std::string& device_id) override; + void AbortRecognition() override; + void StopAudioCapture() override; + bool IsActive() const override; + bool IsCapturingAudio() const override; +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + void SetEvas(Evas* evas) override { evas_ = evas; } +#endif + + private: + SpeechRecognizerImplTizen(const SpeechRecognizerImplTizen&) = delete; + SpeechRecognizerImplTizen& operator=(const SpeechRecognizerImplTizen&) = + delete; + + ~SpeechRecognizerImplTizen() override; + + void Prepare(); + bool Initialize(); + void StartInternal(); + void Destroy(); + stt_state_e GetCurrentState() const; + bool ShouldStartRecognition() const; + void RecognitionResults( + bool no_speech, + std::vector& results); + void HandleSttError(stt_error_e error, const base::Location& location); + void HandleSttResultError(const std::string error); + void RecognitionStarted(); + void AudioCaptureEnd(); + void EndRecognition(const base::Location& location); + + // Callbacks + static bool OnSupportedLanguages(stt_h stt, + const char* language, + void* user_data); + static void OnRecognitionResult(stt_h stt, + stt_result_event_e event, + const char** data, + int data_count, + const char* msg, + void* user_data); + static void OnStateChange(stt_h stt, + stt_state_e previous, + stt_state_e current, + void* user_data); + static void OnError(stt_h stt, stt_error_e reason, void* user_data); + +#if BUILDFLAG(IS_TIZEN_TV) && defined(USE_WAYLAND) + Evas* evas_ = nullptr; +#endif + + stt_h handle_ = nullptr; + std::string language_; + bool is_lang_supported_ = false; + bool continuous_ = false; + const char* recognition_type_ = ""; + bool is_aborted_ = false; + base::Lock abort_lock_; +}; + +} // namespace content + +#endif // BROWSER_SPEECH_SPEECH_RECOGNIZER_IMPL_TIZEN_ diff --git a/tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.cc b/tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.cc new file mode 100644 index 0000000..8435e66 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.cc @@ -0,0 +1,37 @@ +// Copyright 2016 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speech/tizen_speech_recognition_manager_delegate.h" + +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" + +#if BUILDFLAG(IS_TIZEN_TV) +#include "tizen_src/ewk/efl_integration/common/application_type.h" +#endif + +namespace content { + +void TizenSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( + int session_id, + base::OnceCallback callback) { + // For tizen, we expect speech recognition to happen when requested. + + // Therefore we simply authorize it by calling back with is_allowed=true. The + // first parameter, ask_user, is set to false because we don't want to prompt + // the user for permission with an infobar. + + // In browser, a pop-up for permission to use microphone will show up. + // In web app, however, the user agrees on the access to microphone + // when the app is installed on device. So the pop-up will not show up. +#if BUILDFLAG(IS_TIZEN_TV) && defined(WRT_BRINGUP) + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), IsTIZENWRT(), false)); +#else + GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), false, true)); +#endif +} + +} // namespace content diff --git a/tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.h b/tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.h new file mode 100644 index 0000000..6ac79bb --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.h @@ -0,0 +1,41 @@ +// Copyright 2016 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SPEECH_TIZEN_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_ +#define CONTENT_BROWSER_SPEECH_TIZEN_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_ + +#include "base/bind.h" +#include "content/public/browser/speech_recognition_manager_delegate.h" + +namespace content { + +class SpeechRecognitionEventListener; +// This delegate is used by the speech recognition manager to +// check for permission to record audio. For tizen, we always authorize +// speech recognition. +class TizenSpeechRecognitionManagerDelegate + : public SpeechRecognitionManagerDelegate { + public: + TizenSpeechRecognitionManagerDelegate() {} + ~TizenSpeechRecognitionManagerDelegate() override {} + + private: + TizenSpeechRecognitionManagerDelegate( + const TizenSpeechRecognitionManagerDelegate&) = delete; + TizenSpeechRecognitionManagerDelegate& operator=( + const TizenSpeechRecognitionManagerDelegate&) = delete; + + void CheckRecognitionIsAllowed( + int session_id, + base::OnceCallback callback) + override; + SpeechRecognitionEventListener* GetEventListener() override { + return nullptr; + } + bool FilterProfanities(int render_process_id) override { return false; } +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPEECH_TIZEN_SPEECH_RECOGNITION_MANAGER_DELEGATE_H_ diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc index 7b36d0f..23882ee 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc @@ -41,6 +41,10 @@ #include "private/ewk_notification_private.h" +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) +#include "content/browser/speech/tizen_speech_recognition_manager_delegate.h" +#endif + using web_contents_utils::WebContentsFromFrameID; using web_contents_utils::WebContentsFromViewID; using web_contents_utils::WebViewFromWebContents; @@ -250,6 +254,13 @@ bool ContentBrowserClientEfl::HasErrorPage(int http_status_code) { error_page::Error::kHttpErrorDomain, http_status_code); } +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) +SpeechRecognitionManagerDelegate* +ContentBrowserClientEfl::CreateSpeechRecognitionManagerDelegate() { + return new TizenSpeechRecognitionManagerDelegate(); +} +#endif + void ContentBrowserClientEfl::AllowCertificateError( WebContents* web_contents, int cert_error, diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.h b/tizen_src/ewk/efl_integration/content_browser_client_efl.h index cef8cb6..7b3f8f1 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.h +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.h @@ -21,6 +21,11 @@ namespace content { class BrowserMainPartsEfl; class NotificationControllerEfl; class SharedURLLoaderFactoryEfl; + +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) +class SpeechRecognitionManagerDelegate; +#endif + class WebContents; class WebContentsView; @@ -59,6 +64,11 @@ class ContentBrowserClientEfl : public ContentBrowserClient { bool opener_suppressed, bool* no_javascript_access) override; +#if defined(TIZEN_WEB_SPEECH_RECOGNITION) + SpeechRecognitionManagerDelegate* CreateSpeechRecognitionManagerDelegate() + override; +#endif + scoped_refptr CreateQuotaPermissionContext() override; bool HasErrorPage(int http_status_code) override; -- 2.7.4 From eb1cfd8dd1dec8e0c312d1245ac19d51935c81ad Mon Sep 17 00:00:00 2001 From: Gajendra N Date: Tue, 24 Jan 2023 12:15:06 +0530 Subject: [PATCH 07/16] [M108 Migration][API] Introduce AddJavascriptInterface for Tizen Introduces AddJavascriptInterface for tizen, adds logs for debugging and support for posting blob type data type when using custom JS msg handler. Additionally, on M108, due to lot of upstream changes in base/values.{h,cc} prototypes, this patch fixes many build errors with respect to conversion of JS types (list, blob, dict etc) to Native types. Reference: https://review.tizen.org/gerrit/273935 Change-Id: Id18d8756919c3730ad991ab2a2ea02f91d64131f Signed-off-by: Gajendra N --- .../renderer_host/render_frame_host_impl.cc | 1 + ipc/ipc_message_start.h | 1 + .../core/frame/local_frame_mojo_handler.cc | 1 + tizen_src/ewk/efl_integration/BUILD.gn | 21 ++ .../gin_native_bound_object.cc | 43 +++ .../javascript_interface/gin_native_bound_object.h | 63 ++++ .../gin_native_bridge_dispatcher_host.cc | 381 +++++++++++++++++++++ .../gin_native_bridge_dispatcher_host.h | 98 ++++++ .../gin_native_bridge_message_filter.cc | 137 ++++++++ .../gin_native_bridge_message_filter.h | 98 ++++++ .../common/gin_native_bridge_errors.cc | 39 +++ .../common/gin_native_bridge_errors.h | 31 ++ .../common/gin_native_bridge_messages.h | 60 ++++ .../common/gin_native_bridge_value.cc | 105 ++++++ .../common/gin_native_bridge_value.h | 56 +++ .../efl_integration/common/message_generator_ewk.h | 3 +- tizen_src/ewk/efl_integration/eweb_view.cc | 31 +- tizen_src/ewk/efl_integration/eweb_view.h | 13 + tizen_src/ewk/efl_integration/public/ewk_view.cc | 39 +++ .../renderer/content_renderer_client_efl.cc | 3 + .../renderer/gin_native_bridge_dispatcher.cc | 120 +++++++ .../renderer/gin_native_bridge_dispatcher.h | 77 +++++ .../renderer/gin_native_bridge_object.cc | 124 +++++++ .../renderer/gin_native_bridge_object.h | 74 ++++ .../renderer/gin_native_bridge_value_converter.cc | 37 ++ .../renderer/gin_native_bridge_value_converter.h | 36 ++ .../gin_native_function_invocation_helper.cc | 108 ++++++ .../gin_native_function_invocation_helper.h | 42 +++ 28 files changed, 1833 insertions(+), 9 deletions(-) create mode 100644 tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.cc create mode 100644 tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.h create mode 100644 tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.cc create mode 100644 tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.h create mode 100644 tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.cc create mode 100644 tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.h create mode 100644 tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.cc create mode 100644 tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.h create mode 100644 tizen_src/ewk/efl_integration/common/gin_native_bridge_messages.h create mode 100644 tizen_src/ewk/efl_integration/common/gin_native_bridge_value.cc create mode 100644 tizen_src/ewk/efl_integration/common/gin_native_bridge_value.h create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.cc create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.h create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.cc create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.h create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.cc create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.h create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.cc create mode 100644 tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.h diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index c735f4a..a614089 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc @@ -2326,6 +2326,7 @@ void RenderFrameHostImpl::ForEachRenderFrameHostImpl( base::FunctionRef on_frame, bool include_speculative) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + LOG(INFO) << __FUNCTION__; if (!include_speculative && (lifecycle_state() == LifecycleStateImpl::kSpeculative || diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h index 8c91037..7758a5f 100644 --- a/ipc/ipc_message_start.h +++ b/ipc/ipc_message_start.h @@ -27,6 +27,7 @@ enum IPCMessageStart { TtsMsgStart, #endif ExtensionWorkerMsgStart, + GinNativeBridgeMsgStart, LastIPCMsgStart // Must come last. }; diff --git a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc index 4716b95..4dd8501 100644 --- a/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc +++ b/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc @@ -943,6 +943,7 @@ void LocalFrameMojoHandler::JavaScriptExecuteRequestForTests( bool resolve_promises, int32_t world_id, JavaScriptExecuteRequestForTestsCallback callback) { + LOG(INFO) << __FUNCTION__; TRACE_EVENT_INSTANT0("test_tracing", "JavaScriptExecuteRequestForTests", TRACE_EVENT_SCOPE_THREAD); diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index c04d0c6..bfbb46a 100755 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -313,6 +313,12 @@ shared_library("chromium-ewk") { "browser/input_picker/color_chooser_efl.h", "browser/input_picker/input_picker.cc", "browser/input_picker/input_picker.h", + "browser/javascript_interface/gin_native_bound_object.cc", + "browser/javascript_interface/gin_native_bound_object.h", + "browser/javascript_interface/gin_native_bridge_dispatcher_host.cc", + "browser/javascript_interface/gin_native_bridge_dispatcher_host.h", + "browser/javascript_interface/gin_native_bridge_message_filter.cc", + "browser/javascript_interface/gin_native_bridge_message_filter.h", "browser/network_service/browser_url_loader_throttle_efl.cc", "browser/network_service/browser_url_loader_throttle_efl.h", "browser/notification/notification_controller_efl.cc", @@ -345,6 +351,11 @@ shared_library("chromium-ewk") { "common/content_switches_efl.cc", "common/content_switches_efl.h", "common/editing_messages.h", + "common/gin_native_bridge_errors.cc", + "common/gin_native_bridge_errors.h", + "common/gin_native_bridge_messages.h", + "common/gin_native_bridge_value.cc", + "common/gin_native_bridge_value.h", "common/hit_test_params.h", "common/message_generator_ewk.cc", "common/message_generator_ewk.h", @@ -549,6 +560,16 @@ shared_library("chromium-ewk") { "renderer/content_renderer_client_efl.h", "renderer/content_settings_client_efl.cc", "renderer/content_settings_client_efl.h", + "renderer/gin_native_bridge_dispatcher.cc", + "renderer/gin_native_bridge_dispatcher.h", + "renderer/gin_native_bridge_object.cc", + "renderer/gin_native_bridge_object.h", + "renderer/gin_native_bridge_value_converter.cc", + "renderer/gin_native_bridge_value_converter.h", + "renderer/gin_native_function_invocation_helper.cc", + "renderer/gin_native_function_invocation_helper.h", + "renderer/plugins/plugin_placeholder_efl.cc", + "renderer/plugins/plugin_placeholder_efl.h", "renderer/print_web_view_helper_efl.cc", "renderer/print_web_view_helper_efl.h", "renderer/render_frame_observer_efl.cc", diff --git a/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.cc b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.cc new file mode 100644 index 0000000..a16ee7a2 --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.cc @@ -0,0 +1,43 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/javascript_interface/gin_native_bound_object.h" + +namespace content { + +GinNativeBoundObject::GinNativeBoundObject(Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name) + : obj_(obj), callback_(callback), name_(name), names_count_(0) {} + +GinNativeBoundObject::GinNativeBoundObject(Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name, + const std::set& holders) + : obj_(obj), + callback_(callback), + name_(name), + names_count_(0), + holders_(holders) {} + +// static +GinNativeBoundObject* GinNativeBoundObject::CreateNamed( + Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name) { + return new GinNativeBoundObject(obj, callback, name); +} + +// static +GinNativeBoundObject* GinNativeBoundObject::CreateTransient( + Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name, + int32_t holder) { + std::set holders; + holders.insert(holder); + return new GinNativeBoundObject(obj, callback, name, holders); +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.h b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.h new file mode 100644 index 0000000..d95658f --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bound_object.h @@ -0,0 +1,63 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BOUND_OBJECT_H_ +#define EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BOUND_OBJECT_H_ + +#include +#include + +#include +#include + +#include "base/memory/ref_counted.h" +#include "public/ewk_view.h" + +namespace content { + +class GinNativeBoundObject + : public base::RefCountedThreadSafe { + public: + typedef int32_t ObjectID; + static GinNativeBoundObject* CreateNamed(Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name); + static GinNativeBoundObject* CreateTransient( + Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name, + int32_t holder); + void AddName() { ++names_count_; } + void RemoveName() { --names_count_; } + Evas_Object* GetView() const { return obj_; } + Ewk_View_Script_Message_Cb CallBack() const { return callback_; } + const char* Name() const { return name_.c_str(); } + + private: + friend class base::RefCountedThreadSafe; + GinNativeBoundObject(Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name); + GinNativeBoundObject(Evas_Object* obj, + Ewk_View_Script_Message_Cb callback, + const std::string& name, + const std::set& holders); + ~GinNativeBoundObject(){}; + + GinNativeBoundObject(const GinNativeBoundObject&) = delete; + GinNativeBoundObject& operator=(const GinNativeBoundObject&) = delete; + + Evas_Object* obj_; + Ewk_View_Script_Message_Cb callback_; + std::string name_; + + // An object must be kept in retained_object_set_ either if it has + // names or if it has a non-empty holders set. + int names_count_; + std::set holders_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BOUND_OBJECT_H_ diff --git a/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.cc b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.cc new file mode 100644 index 0000000..145925c --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.cc @@ -0,0 +1,381 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h" + +#include "base/logging.h" +#include "base/task/task_runner_util.h" +#include "browser/javascript_interface/gin_native_bridge_message_filter.h" +#include "common/gin_native_bridge_messages.h" +#include "common/gin_native_bridge_value.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "ipc/ipc_message_utils.h" + +namespace content { + +GinNativeBridgeDispatcherHost::GinNativeBridgeDispatcherHost( + WebContents* web_contents) + : WebContentsObserver(web_contents), next_object_id_(1) {} + +GinNativeBridgeDispatcherHost::~GinNativeBridgeDispatcherHost() {} + +void GinNativeBridgeDispatcherHost::InstallFilterAndRegisterAllRoutingIds() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!web_contents()->GetPrimaryMainFrame()->GetProcess()->GetChannel()) { + return; + } + + web_contents()->GetPrimaryMainFrame()->ForEachRenderFrameHost( + [this](RenderFrameHostImpl* frame) { + auto filter = GinNativeBridgeMessageFilter::FromHost(this, true); + filter->AddRoutingIdForHost(this, frame); + }); +} + +void GinNativeBridgeDispatcherHost::RenderFrameCreated( + RenderFrameHost* render_frame_host) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (auto filter = GinNativeBridgeMessageFilter::FromHost(this, false)) { + filter->AddRoutingIdForHost( + this, static_cast(render_frame_host)); + } else { + InstallFilterAndRegisterAllRoutingIds(); + } + for (NamedObjectMap::const_iterator iter = named_objects_.begin(); + iter != named_objects_.end(); ++iter) { + render_frame_host->Send(new GinNativeBridgeMsg_AddNamedObject( + render_frame_host->GetRoutingID(), iter->first, iter->second)); + } +} + +void GinNativeBridgeDispatcherHost::WebContentsDestroyed() { + scoped_refptr filter = + GinNativeBridgeMessageFilter::FromHost(this, false); + if (filter) + filter->RemoveHost(this); +} + +WebContentsImpl* GinNativeBridgeDispatcherHost::web_contents() const { + return static_cast(WebContentsObserver::web_contents()); +} + +bool GinNativeBridgeDispatcherHost::AddNamedObject( + Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + const std::string& name) { + LOG(INFO) << __FUNCTION__; + DCHECK_CURRENTLY_ON(BrowserThread::UI); + GinNativeBoundObject::ObjectID object_id; + NamedObjectMap::iterator iter = named_objects_.find(name); + if (iter != named_objects_.end()) + return false; + + object_id = AddObject(view, callback, name, true, 0); + named_objects_[name] = object_id; + + InstallFilterAndRegisterAllRoutingIds(); + + web_contents() + ->GetPrimaryMainFrame() + ->ForEachRenderFrameHostIncludingSpeculative( + [&name, object_id](RenderFrameHostImpl* render_frame_host) { + render_frame_host->Send(new GinNativeBridgeMsg_AddNamedObject( + render_frame_host->GetRoutingID(), name, object_id)); + }); + + return true; +} + +void GinNativeBridgeDispatcherHost::RemoveNamedObject(const std::string& name) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + NamedObjectMap::iterator iter = named_objects_.find(name); + if (iter == named_objects_.end()) + return; + + // |name| may come from |named_objects_|. Make a copy of name so that if + // |name| is from |named_objects_| it'll be valid after the remove below. + const std::string copied_name(name); + { + base::AutoLock locker(objects_lock_); + objects_[iter->second]->RemoveName(); + } + named_objects_.erase(iter); + + // As the object isn't going to be removed from the JavaScript side until the + // next page reload, calls to it must still work, thus we should continue to + // hold it. All the transient objects and removed named objects will be purged + // during the cleansing caused by DocumentAvailableInMainFrame event. + web_contents() + ->GetPrimaryMainFrame() + ->ForEachRenderFrameHostIncludingSpeculative( + [&copied_name](RenderFrameHostImpl* render_frame_host) { + render_frame_host->Send(new GinNativeBridgeMsg_RemoveNamedObject( + render_frame_host->GetRoutingID(), copied_name)); + }); +} + +GinNativeBoundObject::ObjectID GinNativeBridgeDispatcherHost::AddObject( + Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + const std::string& name, + bool is_named, + int32_t holder) { + scoped_refptr new_object = + is_named + ? GinNativeBoundObject::CreateNamed(view, callback, name) + : GinNativeBoundObject::CreateTransient(view, callback, name, holder); + // Note that we are abusing the fact that StaticAtomicSequenceNumber + // uses Atomic32 as a counter, so it is guaranteed that it will not + // overflow our int32_t IDs. IDs start from 1. + GinNativeBoundObject::ObjectID object_id = next_object_id_++; + { + base::AutoLock locker(objects_lock_); + objects_[object_id] = new_object; + } + return object_id; +} + +void GinNativeBridgeDispatcherHost::PrimaryMainDocumentElementAvailable() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Called when the window object has been cleared in the main frame. + // That means, all sub-frames have also been cleared, so only named + // objects survived. + + NOTIMPLEMENTED(); +} + +scoped_refptr GinNativeBridgeDispatcherHost::FindObject( + GinNativeBoundObject::ObjectID object_id) { + // Can be called on any thread. + base::AutoLock locker(objects_lock_); + auto iter = objects_.find(object_id); + if (iter != objects_.end()) + return iter->second; + LOG(ERROR) << "WebView: Unknown object: " << object_id; + return nullptr; +} + +void GinNativeBridgeDispatcherHost::OnHasMethod( + GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + bool* result) { + scoped_refptr object = FindObject(object_id); + + *result = (object.get()) ? true : false; +} + +void GinNativeBridgeDispatcherHost::OnInvokeMethod( + int routing_id, + GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + const base::Value::List& arguments, + base::Value::List* wrapped_result, + content::GinNativeBridgeError* error_code) { + LOG(INFO) << __FUNCTION__; + DCHECK(routing_id != MSG_ROUTING_NONE); + if (method_name != "postMessage") { + LOG(ERROR) << __FUNCTION__ << " : kGinNativeBridgeMethodNotFound"; + wrapped_result->Append(base::Value()); + *error_code = kGinNativeBridgeMethodNotFound; + return; + } + + scoped_refptr object = FindObject(object_id); + if (!object.get()) { + LOG(ERROR) << "WebView: Unknown object: " << object_id; + wrapped_result->Append(base::Value()); + *error_code = kGinNativeBridgeUnknownObjectId; + return; + } + + Ewk_Script_Message msg; + msg.name = object->Name(); + + if (named_objects_.find(msg.name) == named_objects_.end()) { + LOG(ERROR) << __FUNCTION__ << " : kGinNativeBridgeMessageNameIsWrong"; + wrapped_result->Append(base::Value()); + *error_code = kGinNativeBridgeMessageNameIsWrong; + return; + } + + JavaScript_Values values; + values.bool_buf = EINA_FALSE; + values.int_buf = -1; + values.double_buf = -1; + values.str_buf = ""; + + bool bool_buf = false; + bool should_free = false; + + base::Value::List::const_iterator iter = arguments.begin(); + + switch (iter->type()) { + case base::Value::Type::BOOLEAN: + bool_buf = iter->GetBool(); + (bool_buf) ? values.bool_buf = EINA_TRUE : values.bool_buf = EINA_FALSE; + msg.body = &values.bool_buf; + break; + case base::Value::Type::INTEGER: + values.int_buf = iter->GetInt(); + msg.body = &values.int_buf; + break; + case base::Value::Type::DOUBLE: + values.double_buf = iter->GetDouble(); + msg.body = &values.double_buf; + break; + case base::Value::Type::STRING: + values.str_buf = iter->GetString(); + msg.body = strdup(values.str_buf.c_str()); + should_free = true; + break; + case base::Value::Type::DICTIONARY: + values.str_buf = ConvertDictionaryValueToString(iter->GetDict()); + msg.body = strdup(values.str_buf.c_str()); + should_free = true; + break; + case base::Value::Type::LIST: + values.str_buf = ConvertListValueToString(iter->GetList()); + msg.body = strdup(values.str_buf.c_str()); + should_free = true; + break; + case base::Value::Type::BINARY: + values.str_buf.assign(iter->GetBlob().begin(), iter->GetBlob().end()); + msg.body = (void*)values.str_buf.data(); + break; + default: + LOG(ERROR) << __FUNCTION__ << " : kGinNativeBridgeNotSupportedTypes"; + wrapped_result->Append(base::Value()); + *error_code = kGinNativeBridgeNotSupportedTypes; + return; + } + + object->CallBack()(object->GetView(), msg); + wrapped_result->Append(base::Value::FromUniquePtrValue( + GinNativeBridgeValue::CreateObjectIDValue(object_id))); + + if (should_free) + free(msg.body); + + return; +} + +std::string GinNativeBridgeDispatcherHost::ConvertListValueToString( + const base::Value::List& list) { + bool init = false; + bool bool_buf = false; + int int_buf = -1; + double double_buf = -1; + std::string str_buf = ""; + std::string token = ""; + + str_buf = "["; + for (base::Value::List::const_iterator iter_list = list.begin(); + iter_list != list.end(); ++iter_list) { + if (init) + str_buf += ","; + + switch (iter_list->type()) { + case base::Value::Type::BOOLEAN: + bool_buf = false; + bool_buf = iter_list->GetBool(); + (bool_buf) ? str_buf += "true" : str_buf += "false"; + break; + case base::Value::Type::INTEGER: + int_buf = -1; + int_buf = iter_list->GetInt(); + str_buf += std::to_string(int_buf); + break; + case base::Value::Type::DOUBLE: + double_buf = -1; + double_buf = iter_list->GetDouble(); + str_buf += std::to_string(double_buf); + break; + case base::Value::Type::STRING: + token = ""; + token = iter_list->GetString(); + str_buf += "\""; + str_buf += token; + str_buf += "\""; + break; + case base::Value::Type::DICTIONARY: + str_buf = ConvertDictionaryValueToString(iter_list->GetDict()); + break; + case base::Value::Type::LIST: + str_buf += ConvertListValueToString(iter_list->GetList()); + break; + default: + str_buf += "\"\""; + break; + } + init = true; + } + str_buf += "]"; + + return str_buf; +} + +std::string GinNativeBridgeDispatcherHost::ConvertDictionaryValueToString( + const base::Value::Dict& dict) { + bool init = false; + bool bool_buf = false; + int int_buf = -1; + double double_buf = -1; + std::string str_buf = ""; + std::string token = ""; + + str_buf = "{"; + for (const auto item : dict) { + if (init) + str_buf += ","; + str_buf += " \""; + str_buf += item.first; + str_buf += "\": "; + + switch (item.second.type()) { + case base::Value::Type::BOOLEAN: + bool_buf = false; + bool_buf = item.second.GetBool(); + (bool_buf) ? str_buf += "true" : str_buf += "false"; + break; + case base::Value::Type::INTEGER: + int_buf = -1; + int_buf = item.second.GetInt(); + str_buf += std::to_string(int_buf); + break; + case base::Value::Type::DOUBLE: + double_buf = -1; + double_buf = item.second.GetDouble(); + str_buf += std::to_string(double_buf); + break; + case base::Value::Type::STRING: + token = ""; + token = item.second.GetString(); + str_buf += "\""; + str_buf += token; + str_buf += "\""; + break; + case base::Value::Type::DICTIONARY: + str_buf += ConvertDictionaryValueToString(item.second.GetDict()); + break; + case base::Value::Type::LIST: + str_buf += ConvertListValueToString(item.second.GetList()); + break; + default: + str_buf += "\"\""; + break; + } + init = true; + } + str_buf += "}"; + + return str_buf; +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.h b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.h new file mode 100644 index 0000000..43df6ef --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_dispatcher_host.h @@ -0,0 +1,98 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BRIDGE_DISPATCHER_HOST_H_ +#define EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BRIDGE_DISPATCHER_HOST_H_ + +#include +#include +#include + +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "browser/javascript_interface/gin_native_bound_object.h" +#include "common/gin_native_bridge_errors.h" +#include "content/public/browser/browser_message_filter.h" +#include "content/public/browser/web_contents_observer.h" +#include "public/ewk_view.h" + +namespace content { + +class GinNativeBridgeDispatcherHost + : public base::RefCountedThreadSafe, + public WebContentsObserver { + public: + explicit GinNativeBridgeDispatcherHost(WebContents* web_contents); + ~GinNativeBridgeDispatcherHost() override; + + GinNativeBridgeDispatcherHost(const GinNativeBridgeDispatcherHost&) = delete; + GinNativeBridgeDispatcherHost& operator=( + const GinNativeBridgeDispatcherHost&) = delete; + + // WebContentsObserver + void RenderFrameCreated(RenderFrameHost* render_frame_host) override; + void WebContentsDestroyed() override; + void PrimaryMainDocumentElementAvailable() override; + + bool AddNamedObject(Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + const std::string& name); + void RemoveNamedObject(const std::string& name); + void OnHasMethod(GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + bool* result); + + void OnInvokeMethod(int routing_id, + GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + const base::Value::List& arguments, + base::Value::List* result, + content::GinNativeBridgeError* error_code); + WebContentsImpl* web_contents() const; + + private: + friend class base::RefCountedThreadSafe; + typedef std::map> + ObjectMap; + + // Run on the UI thread. + void InstallFilterAndRegisterAllRoutingIds(); + + bool FindObjectId(); + GinNativeBoundObject::ObjectID AddObject(Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + const std::string& name, + bool is_named, + int32_t holder); + scoped_refptr FindObject( + GinNativeBoundObject::ObjectID object_id); + + std::string ConvertListValueToString(const base::Value::List& list); + + std::string ConvertDictionaryValueToString(const base::Value::Dict& dict); + + typedef std::map NamedObjectMap; + NamedObjectMap named_objects_; + + GinNativeBoundObject::ObjectID next_object_id_; + + // Note that retained_object_set_ does not need to be consistent + // with objects_. + ObjectMap objects_; + base::Lock objects_lock_; + + struct _JavaScript_Values { + Eina_Bool bool_buf; /**< Buffer for boolean */ + int int_buf; /**< Buffer for integer */ + double double_buf; /**< Buffer for double */ + std::string str_buf; /**< Buffer for string */ + }; + typedef struct _JavaScript_Values JavaScript_Values; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BRIDGE_DISPATCHER_HOST_H_ diff --git a/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.cc b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.cc new file mode 100644 index 0000000..2eacac2 --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.cc @@ -0,0 +1,137 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/javascript_interface/gin_native_bridge_message_filter.h" + +#include "base/auto_reset.h" +#include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h" +#include "common/gin_native_bridge_messages.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" + +namespace { +const char kGinNativeBridgeMessageFilterKey[] = "GinNativeBridgeMessageFilter"; +} // namespace + +namespace content { + +GinNativeBridgeMessageFilter::GinNativeBridgeMessageFilter() + : BrowserMessageFilter(GinNativeBridgeMsgStart), + current_routing_id_(MSG_ROUTING_NONE) {} + +GinNativeBridgeMessageFilter::~GinNativeBridgeMessageFilter() {} + +void GinNativeBridgeMessageFilter::OnDestruct() const { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) + delete this; + else + BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); +} + +bool GinNativeBridgeMessageFilter::OnMessageReceived( + const IPC::Message& message) { + base::AutoReset routing_id(¤t_routing_id_, + message.routing_id()); + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(GinNativeBridgeMessageFilter, message) + IPC_MESSAGE_HANDLER(GinNativeBridgeHostMsg_HasMethod, OnHasMethod) + IPC_MESSAGE_HANDLER(GinNativeBridgeHostMsg_InvokeMethod, OnInvokeMethod) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +scoped_refptr +GinNativeBridgeMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& message) { + // As the filter is only invoked for the messages of the particular class, + // we can return the task runner unconfitionally. + return nullptr; +} + +void GinNativeBridgeMessageFilter::AddRoutingIdForHost( + GinNativeBridgeDispatcherHost* host, + RenderFrameHostImpl* render_frame_host) { + base::AutoLock locker(hosts_lock_); + hosts_[render_frame_host->GetRoutingID()] = host; +} + +void GinNativeBridgeMessageFilter::RemoveHost( + GinNativeBridgeDispatcherHost* host) { + base::AutoLock locker(hosts_lock_); + auto iter = hosts_.begin(); + while (iter != hosts_.end()) { + if (iter->second == host) + hosts_.erase(iter++); + else + ++iter; + } +} + +// static +scoped_refptr +GinNativeBridgeMessageFilter::FromHost(GinNativeBridgeDispatcherHost* host, + bool create_if_not_exists) { + RenderProcessHost* rph = + host->web_contents()->GetPrimaryMainFrame()->GetProcess(); + scoped_refptr filter = + base::UserDataAdapter::Get( + rph, kGinNativeBridgeMessageFilterKey); + if (!filter && create_if_not_exists) { + filter = new GinNativeBridgeMessageFilter(); + rph->AddFilter(filter.get()); + rph->SetUserData( + kGinNativeBridgeMessageFilterKey, + base::WrapUnique( + new base::UserDataAdapter( + filter.get()))); + } + return filter; +} + +GinNativeBridgeDispatcherHost* GinNativeBridgeMessageFilter::FindHost() { + base::AutoLock locker(hosts_lock_); + auto iter = hosts_.find(current_routing_id_); + if (iter != hosts_.end()) + return iter->second; + // This is usually OK -- we can receive messages form RenderFrames for + // which the corresponding host part has already been destroyed. That means, + // any references to Native objects that the host was holding were already + // released (with the death of ContentViewCore), so we can just drop such + // messages. + LOG(WARNING) << "WebView: Unknown frame routing id: " << current_routing_id_; + return nullptr; +} + +void GinNativeBridgeMessageFilter::OnHasMethod( + GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + bool* result) { + GinNativeBridgeDispatcherHost* host = FindHost(); + if (host) + host->OnHasMethod(object_id, method_name, result); + else + *result = false; +} + +void GinNativeBridgeMessageFilter::OnInvokeMethod( + GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + const base::Value::List& arguments, + base::Value::List* wrapped_result, + content::GinNativeBridgeError* error_code) { + LOG(INFO) << __FUNCTION__; + GinNativeBridgeDispatcherHost* host = FindHost(); + if (host) { + host->OnInvokeMethod(current_routing_id_, object_id, method_name, arguments, + wrapped_result, error_code); + } else { + wrapped_result->Append(base::Value()); + *error_code = kGinNativeBridgeRenderFrameDeleted; + } +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.h b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.h new file mode 100644 index 0000000..dbb24c6 --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/javascript_interface/gin_native_bridge_message_filter.h @@ -0,0 +1,98 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BRIDGE_MESSAGE_FILTER_H_ +#define EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BRIDGE_MESSAGE_FILTER_H_ + +#include + +#include +#include +#include + +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "base/values.h" +#include "browser/javascript_interface/gin_native_bound_object.h" +#include "common/gin_native_bridge_errors.h" +#include "content/public/browser/browser_message_filter.h" + +namespace base { +class ListValue; +} + +namespace IPC { +class Message; +} + +namespace content { + +class GinNativeBridgeDispatcherHost; +class RenderFrameHostImpl; + +class GinNativeBridgeMessageFilter : public BrowserMessageFilter { + public: + // BrowserMessageFilter + void OnDestruct() const override; + bool OnMessageReceived(const IPC::Message& message) override; + scoped_refptr OverrideTaskRunnerForMessage( + const IPC::Message& message) override; + + // Called on the UI thread. + void AddRoutingIdForHost(GinNativeBridgeDispatcherHost* host, + RenderFrameHostImpl* render_frame_host); + void RemoveHost(GinNativeBridgeDispatcherHost* host); + + static scoped_refptr FromHost( + GinNativeBridgeDispatcherHost* host, + bool create_if_not_exists); + + private: + friend class BrowserThread; + friend class base::DeleteHelper; + + // WebView (who owns GinNativeBridgeDispatcherHost) outlives + // WebContents, and GinNativeBridgeDispatcherHost removes itself form the map + // on WebContents destruction, so there is no risk that the pointer would + // become stale. + // + // The filter keeps its own routing map of RenderFrames for two reasons: + // 1. Message dispatching must be done on the background thread, + // without resorting to the UI thread, which can be in fact currently + // blocked, waiting for an event from an injected Native object. + // 2. As RenderFrames pass away earlier than JavaScript wrappers, + // messages form the latter can arrive after the RenderFrame has been + // removed from the WebContent's routing table. + typedef std::map HostMap; + + GinNativeBridgeMessageFilter(); + ~GinNativeBridgeMessageFilter() override; + + GinNativeBridgeMessageFilter(const GinNativeBridgeMessageFilter&) = delete; + GinNativeBridgeMessageFilter& operator=(const GinNativeBridgeMessageFilter&) = + delete; + + // Called on the background thread. + GinNativeBridgeDispatcherHost* FindHost(); + void OnHasMethod(GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + bool* result); + void OnInvokeMethod(GinNativeBoundObject::ObjectID object_id, + const std::string& method_name, + const base::Value::List& arguments, + base::Value::List* result, + content::GinNativeBridgeError* error_code); + + // Accessed both from UI and background threads. + HostMap hosts_; + base::Lock hosts_lock_; + + // The routing id of the RenderFrameHost whose request we are processing. + // Used on the backgrount thread. + int32_t current_routing_id_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_BROWSER_JAVASCRIPT_INTERFACE_GIN_NATIVE_BRIDGE_MESSAGE_FILTER_H_ diff --git a/tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.cc b/tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.cc new file mode 100644 index 0000000..dd8184a --- /dev/null +++ b/tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.cc @@ -0,0 +1,39 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "common/gin_native_bridge_errors.h" + +#include "base/notreached.h" + +namespace content { + +const char* GinNativeBridgeErrorToString(GinNativeBridgeError error) { + switch (error) { + case kGinNativeBridgeNoError: + return "No error"; + case kGinNativeBridgeUnknownObjectId: + return "Unknown Native object ID"; + case kGinNativeBridgeObjectIsGone: + return "Native object is gone"; + case kGinNativeBridgeMethodNotFound: + return "Method not found"; + case kGinNativeBridgeAccessToObjectGetClassIsBlocked: + return "Access to Object.getClass is blocked"; + case kGinNativeBridgeNativeExceptionRaised: + return "Native exception was raised during method invocation"; + case kGinNativeBridgeNonAssignableTypes: + return "The type of the object passed to the method is incompatible " + "with the type of method's argument"; + case kGinNativeBridgeRenderFrameDeleted: + return "RenderFrame has been deleted"; + case kGinNativeBridgeNotSupportedTypes: + return "This type is not supported"; + case kGinNativeBridgeMessageNameIsWrong: + return "Message name is wrong"; + } + NOTREACHED(); + return "Unknown error"; +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.h b/tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.h new file mode 100644 index 0000000..cee74ff --- /dev/null +++ b/tizen_src/ewk/efl_integration/common/gin_native_bridge_errors.h @@ -0,0 +1,31 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_COMMON_GIN_NATIVE_BRIDGE_ERRORS_H_ +#define EWK_EFL_INTEGRATION_COMMON_GIN_NATIVE_BRIDGE_ERRORS_H_ + +#include "content/common/content_export.h" + +namespace content { + +enum GinNativeBridgeError { + kGinNativeBridgeNoError = 0, + kGinNativeBridgeUnknownObjectId, + kGinNativeBridgeObjectIsGone, + kGinNativeBridgeMethodNotFound, + kGinNativeBridgeAccessToObjectGetClassIsBlocked, + kGinNativeBridgeNativeExceptionRaised, + kGinNativeBridgeNonAssignableTypes, + kGinNativeBridgeRenderFrameDeleted, + kGinNativeBridgeNotSupportedTypes, + kGinNativeBridgeMessageNameIsWrong, + kGinNativeBridgeErrorLast = kGinNativeBridgeRenderFrameDeleted +}; + +CONTENT_EXPORT const char* GinNativeBridgeErrorToString( + GinNativeBridgeError error); + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_COMMON_GIN_NATIVE_BRIDGE_ERRORS_H_ diff --git a/tizen_src/ewk/efl_integration/common/gin_native_bridge_messages.h b/tizen_src/ewk/efl_integration/common/gin_native_bridge_messages.h new file mode 100644 index 0000000..6f976df --- /dev/null +++ b/tizen_src/ewk/efl_integration/common/gin_native_bridge_messages.h @@ -0,0 +1,60 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include "common/gin_native_bridge_errors.h" +#include "content/common/content_export.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_message_start.h" + +#undef IPC_MESSAGE_EXPORT +#define IPC_MESSAGE_EXPORT CONTENT_EXPORT +#define IPC_MESSAGE_START GinNativeBridgeMsgStart + +// Messages for handling Java objects injected into JavaScript ----------------- + +IPC_ENUM_TRAITS_MAX_VALUE(content::GinNativeBridgeError, + content::kGinNativeBridgeErrorLast) + +// Sent from browser to renderer to add a Native object with the given name. +// Object IDs are generated on the browser side. +IPC_MESSAGE_ROUTED2(GinNativeBridgeMsg_AddNamedObject, + std::string /* name */, + int32_t /* object_id */) + +// Sent from browser to renderer to remove a Java object with the given name. +IPC_MESSAGE_ROUTED1(GinNativeBridgeMsg_RemoveNamedObject, + std::string /* name */) + +// Sent from renderer to browser to get information about methods of +// the given object. The query will only succeed if inspection of injected +// objects is enabled on the browser side. +IPC_SYNC_MESSAGE_ROUTED1_1(GinNativeBridgeHostMsg_GetMethods, + int32_t /* object_id */, + std::set /* returned_method_names */) + +// Sent from renderer to browser to find out, if an object has a method with +// the given name. +IPC_SYNC_MESSAGE_ROUTED2_1(GinNativeBridgeHostMsg_HasMethod, + int32_t /* object_id */, + std::string /* method_name */, + bool /* result */) + +// Sent from renderer to browser to invoke a method. Method arguments +// are chained into |arguments| list. base::Value::List is used for |result| as +// a container to work around immutability of base::Value. +// Empty result list indicates that an error has happened on the Native side +// (either bridge-induced error or an unhandled Native exception) and an +// exception must be thrown into JavaScript. |error_code| indicates the cause of +// the error. +// Some special value types that are not supported by base::Value are encoded +// as BinaryValues via GinNativeBridgeValue. +IPC_SYNC_MESSAGE_ROUTED3_2(GinNativeBridgeHostMsg_InvokeMethod, + int32_t /* object_id */, + std::string /* method_name */, + base::Value::List /* arguments */, + base::Value::List /* result */, + content::GinNativeBridgeError /* error_code */) diff --git a/tizen_src/ewk/efl_integration/common/gin_native_bridge_value.cc b/tizen_src/ewk/efl_integration/common/gin_native_bridge_value.cc new file mode 100644 index 0000000..ab8e34a --- /dev/null +++ b/tizen_src/ewk/efl_integration/common/gin_native_bridge_value.cc @@ -0,0 +1,105 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ewk/efl_integration/common/gin_native_bridge_value.h" + +namespace content { + +namespace { +// The magic value is only used to prevent accidental attempts of reading +// GinJavaBridgeValue from a random BinaryValue. GinJavaBridgeValue is not +// intended for scenarios where with BinaryValues are being used for anything +// else than holding GinJavaBridgeValues. If a need for such scenario ever +// emerges, the best solution would be to extend GinJavaBridgeValue to be able +// to wrap raw BinaryValues. +const uint32_t kHeaderMagic = 0xBEEFCAFE; + +#pragma pack(push, 4) +struct Header : public base::Pickle::Header { + uint32_t magic; + int32_t type; +}; +#pragma pack(pop) +} // namespace + +// static +std::unique_ptr GinNativeBridgeValue::CreateObjectIDValue( + int32_t in_value) { + GinNativeBridgeValue gin_value(TYPE_OBJECT_ID); + gin_value.pickle_.WriteInt(in_value); + return gin_value.SerializeToValue(); +} + +// static +bool GinNativeBridgeValue::ContainsGinJavaBridgeValue( + const base::Value* value) { + if (!value->is_blob()) + return false; + const base::Value* binary_value = reinterpret_cast(value); + if (binary_value->GetBlob().size() < sizeof(Header)) + return false; + base::Pickle pickle((const char*)binary_value->GetBlob().data(), + binary_value->GetBlob().size()); + // Broken binary value: payload or header size is wrong + if (!pickle.data() || pickle.size() - pickle.payload_size() != sizeof(Header)) + return false; + Header* header = pickle.headerT
(); + return (header->magic == kHeaderMagic && header->type >= TYPE_FIRST_VALUE && + header->type < TYPE_LAST_VALUE); +} + +// static +std::unique_ptr GinNativeBridgeValue::FromValue( + const base::Value* value) { + return std::unique_ptr( + value->is_blob() ? new GinNativeBridgeValue( + reinterpret_cast(value)) + : NULL); +} + +GinNativeBridgeValue::Type GinNativeBridgeValue::GetType() const { + const Header* header = pickle_.headerT
(); + DCHECK(header->type >= TYPE_FIRST_VALUE && header->type < TYPE_LAST_VALUE); + return static_cast(header->type); +} + +bool GinNativeBridgeValue::IsType(Type type) const { + return GetType() == type; +} + +bool GinNativeBridgeValue::GetAsNonFinite(float* out_value) const { + if (GetType() != TYPE_NONFINITE) + return false; + + base::PickleIterator iter(pickle_); + return iter.ReadFloat(out_value); +} + +bool GinNativeBridgeValue::GetAsObjectID(int32_t* out_object_id) const { + if (GetType() != TYPE_OBJECT_ID) + return false; + + base::PickleIterator iter(pickle_); + return iter.ReadInt(out_object_id); +} + +GinNativeBridgeValue::GinNativeBridgeValue(Type type) + : pickle_(sizeof(Header)) { + Header* header = pickle_.headerT
(); + header->magic = kHeaderMagic; + header->type = type; +} + +GinNativeBridgeValue::GinNativeBridgeValue(const base::Value* value) + : pickle_((const char*)value->GetBlob().data(), value->GetBlob().size()) { + DCHECK(ContainsGinJavaBridgeValue(value)); +} + +std::unique_ptr GinNativeBridgeValue::SerializeToValue() { + return std::make_unique(base::Value::BlobStorage( + reinterpret_cast(pickle_.data()), + reinterpret_cast(pickle_.data()) + pickle_.size())); +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/common/gin_native_bridge_value.h b/tizen_src/ewk/efl_integration/common/gin_native_bridge_value.h new file mode 100644 index 0000000..946293f9 --- /dev/null +++ b/tizen_src/ewk/efl_integration/common/gin_native_bridge_value.h @@ -0,0 +1,56 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_COMMON_GIN_NATIVE_BRIDGE_VALUE_H_ +#define EWK_EFL_INTEGRATION_COMMON_GIN_NATIVE_BRIDGE_VALUE_H_ + +#include + +#include "base/pickle.h" +#include "base/values.h" +#include "content/common/content_export.h" + +namespace content { + +class GinNativeBridgeValue { + public: + enum Type { + TYPE_FIRST_VALUE = 0, + // JavaScript 'undefined' + TYPE_UNDEFINED = 0, + // JavaScript NaN and Infinity + TYPE_NONFINITE, + // Bridge Object ID + TYPE_OBJECT_ID, + TYPE_LAST_VALUE + }; + + CONTENT_EXPORT static std::unique_ptr CreateObjectIDValue( + int32_t in_value); + + // De-serialization + CONTENT_EXPORT static bool ContainsGinJavaBridgeValue( + const base::Value* value); + CONTENT_EXPORT static std::unique_ptr FromValue( + const base::Value* value); + CONTENT_EXPORT Type GetType() const; + CONTENT_EXPORT bool IsType(Type type) const; + CONTENT_EXPORT bool GetAsNonFinite(float* out_value) const; + CONTENT_EXPORT bool GetAsObjectID(int32_t* out_object_id) const; + + private: + explicit GinNativeBridgeValue(Type type); + explicit GinNativeBridgeValue(const base::Value* value); + + GinNativeBridgeValue(const GinNativeBridgeValue&) = delete; + GinNativeBridgeValue& operator=(const GinNativeBridgeValue&) = delete; + + std::unique_ptr SerializeToValue(); + + base::Pickle pickle_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_COMMON_GIN_NATIVE_BRIDGE_VALUE_H_ diff --git a/tizen_src/ewk/efl_integration/common/message_generator_ewk.h b/tizen_src/ewk/efl_integration/common/message_generator_ewk.h index db42330..f9760ba 100644 --- a/tizen_src/ewk/efl_integration/common/message_generator_ewk.h +++ b/tizen_src/ewk/efl_integration/common/message_generator_ewk.h @@ -5,5 +5,6 @@ // Multiply-included file, hence no include guard. // efl message generator -#include "common/render_messages_ewk.h" #include "common/editing_messages.h" +#include "common/gin_native_bridge_messages.h" +#include "common/render_messages_ewk.h" diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index a9f9686..449ac1b 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" +#include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h" #include "browser/navigation_policy_handler_efl.h" #include "browser/quota_permission_context_efl.h" #include "browser/selectpicker/popup_menu_item.h" @@ -64,6 +65,7 @@ #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/display/screen.h" +#include "ui/events/event_switches.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/vector2d_f.h" #include "ui/platform_window/platform_window_init_properties.h" @@ -290,6 +292,7 @@ EWebView::~EWebView() { if (context_->GetImpl()->browser_context()->IsOffTheRecord()) Ewk_Context::Delete(context_.get()); + gin_native_bridge_dispatcher_host_.reset(); } void EWebView::ReleasePopupMenuList() { @@ -332,6 +335,17 @@ Eina_Bool EWebView::HasFocus() const { return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE; } +Eina_Bool EWebView::AddJavaScriptMessageHandler( + Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + std::string name) { + if (!gin_native_bridge_dispatcher_host_) + return EINA_FALSE; + + return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback, + name); +} + bool EWebView::CreateNewWindow( content::WebContentsEflDelegate::WebContentsCreateCallback cb) { create_new_window_web_contents_cb_ = cb; @@ -734,18 +748,17 @@ void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data, bool EWebView::ExecuteJavaScript(const char* script, Ewk_View_Script_Execute_Callback callback, void* userdata) { - if (!script) - return false; - - if (!web_contents_delegate_) // question, can I remove this check? - return false; - - if (!web_contents_) + LOG(INFO) << __FUNCTION__; + if (!web_contents_) { + LOG(ERROR) << __FUNCTION__ << "web_contents_ is null"; return false; + } RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame(); - if (!render_frame_host) + if (!render_frame_host) { + LOG(ERROR) << __FUNCTION__ << " render_frame_host is null"; return false; + } // Note: M37. Execute JavaScript, |script| with // |RenderFrameHost::ExecuteJavaScript|. @@ -2264,6 +2277,8 @@ void EWebView::InitializeContent() { new _Ewk_Back_Forward_List(web_contents_->GetController())); permission_popup_manager_.reset(new PermissionPopupManager(evas_object_)); + gin_native_bridge_dispatcher_host_.reset( + new content::GinNativeBridgeDispatcherHost(web_contents_.get())); native_view_ = static_cast(web_contents_.get())->GetEflNativeView(); diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index 93a0b53..bb7357b 100755 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -71,6 +71,7 @@ class WebContentsViewAura; class ContextMenuControllerEfl; class PopupControllerEfl; class InputPicker; +class GinNativeBridgeDispatcherHost; } class ErrorParams; @@ -475,6 +476,14 @@ class EWebView { return context_menu_.get(); } void ResetContextMenuController(); + Eina_Bool AddJavaScriptMessageHandler(Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + std::string name); + + content::GinNativeBridgeDispatcherHost* GetGinNativeBridgeDispatcherHost() + const { + return gin_native_bridge_dispatcher_host_.get(); + } /// ---- Event handling bool HandleShow(); @@ -623,6 +632,10 @@ class EWebView { std::unique_ptr permission_popup_manager_; std::unique_ptr scroll_detector_; + // Manages injecting native objects. + std::unique_ptr + gin_native_bridge_dispatcher_host_; + #if BUILDFLAG(IS_TIZEN) blink::mojom::FileChooserParams::Mode filechooser_mode_; #endif diff --git a/tizen_src/ewk/efl_integration/public/ewk_view.cc b/tizen_src/ewk/efl_integration/public/ewk_view.cc index 40d8e79..9392ea8 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_view.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_view.cc @@ -21,6 +21,7 @@ #include "ewk_view_product.h" #include +#include #include "authentication_challenge_popup.h" #include "content/public/browser/navigation_controller.h" @@ -1318,6 +1319,44 @@ Eina_Bool ewk_view_tts_mode_set(Evas_Object* view, ewk_tts_mode tts_mode) { return false; } +Eina_Bool ewk_view_javascript_message_handler_add( + Evas_Object* view, + Ewk_View_Script_Message_Cb callback, + const char* name) { + EWK_VIEW_IMPL_GET_OR_RETURN(view, impl, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + return impl->AddJavaScriptMessageHandler(view, callback, std::string(name)); +} + +Eina_Bool ewk_view_evaluate_javascript(Evas_Object* view, + const char* name, + const char* result) { + EWK_VIEW_IMPL_GET_OR_RETURN(view, impl, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(result, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + + std::string function(name); + std::string data(result); + std::string pattern("\n"); + std::string replace("
"); + std::string::size_type pos = 0; + std::string::size_type offset = 0; + while ((pos = data.find(pattern, offset)) != std::string::npos) { + data.replace(data.begin() + pos, data.begin() + pos + pattern.size(), + replace); + offset = pos + replace.size(); + } + + // For JSON Object or Array. + if (result[0] == '{' || result[0] == '[') { + data = "javascript:" + function + "(JSON.parse('" + data + "'))"; + } else { + data = "javascript:" + function + "('" + data + "')"; + } + + return impl->ExecuteJavaScript(data.c_str(), NULL, 0); +} + void ewk_view_authentication_callback_set( Evas_Object* ewk_view, Ewk_View_Authentication_Callback callback, diff --git a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc index eb24496..aaf4c52 100644 --- a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc +++ b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc @@ -26,6 +26,7 @@ #if !defined(EWK_BRINGUP) // FIXME: m94 bringup #include "renderer/editorclient_agent.h" #endif +#include "renderer/gin_native_bridge_dispatcher.h" #include "renderer/plugins/plugin_placeholder_efl.h" #include "renderer/render_frame_observer_efl.h" #include "third_party/blink/public/platform/url_conversion.h" @@ -147,6 +148,8 @@ void ContentRendererClientEfl::RenderThreadStarted() { void ContentRendererClientEfl::RenderFrameCreated(content::RenderFrame* render_frame) { new content::RenderFrameObserverEfl(render_frame); new content::ContentSettingsClientEfl(render_frame); + // Deletes itself when render_frame is destroyed. + new content::GinNativeBridgeDispatcher(render_frame); #if defined(TIZEN_AUTOFILL_SUPPORT) PasswordAutofillAgent* password_autofill_agent = diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.cc b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.cc new file mode 100644 index 0000000..1b95734 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.cc @@ -0,0 +1,120 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "renderer/gin_native_bridge_dispatcher.h" + +#include "base/auto_reset.h" +#include "common/gin_native_bridge_messages.h" +#include "content/public/renderer/render_frame.h" +#include "renderer/gin_native_bridge_object.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_view.h" + +namespace content { + +GinNativeBridgeDispatcher::GinNativeBridgeDispatcher(RenderFrame* render_frame) + : RenderFrameObserver(render_frame), + inside_did_clear_window_object_(false) {} + +GinNativeBridgeDispatcher::~GinNativeBridgeDispatcher() {} + +bool GinNativeBridgeDispatcher::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(GinNativeBridgeDispatcher, msg) + IPC_MESSAGE_HANDLER(GinNativeBridgeMsg_AddNamedObject, OnAddNamedObject) + IPC_MESSAGE_HANDLER(GinNativeBridgeMsg_RemoveNamedObject, + OnRemoveNamedObject) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void GinNativeBridgeDispatcher::DidClearWindowObject() { + // Accessing window object when adding properties to it may trigger + // a nested call to DidClearWindowObject. + if (inside_did_clear_window_object_) + return; + base::AutoReset flag_entry(&inside_did_clear_window_object_, true); + for (NamedObjectMap::const_iterator iter = named_objects_.begin(); + iter != named_objects_.end(); ++iter) { + // Always create a new GinNativeBridgeObject, so we don't pull any of the V8 + // wrapper's custom properties into the context of the page we have + // navigated to. The old GinNativeBridgeObject will be automatically + // deleted after its wrapper will be collected. + // On the browser side, we ignore wrapper deletion events for named objects, + // as they are only removed upon embedder's request (RemoveNamedObject). + if (objects_.Lookup(iter->second)) + objects_.Remove(iter->second); + GinNativeBridgeObject* object = GinNativeBridgeObject::InjectNamed( + render_frame()->GetWebFrame(), AsWeakPtr(), iter->first, iter->second); + if (object) { + objects_.AddWithID(object, iter->second); + } else { + // FIXME: Inform the host about wrapper creation failure. + } + } +} + +void GinNativeBridgeDispatcher::OnAddNamedObject(const std::string& name, + ObjectID object_id) { + LOG(INFO) << __FUNCTION__; + // Added objects only become available after page reload, so here they + // are only added into the internal map. + named_objects_.insert(std::make_pair(name, object_id)); +} + +void GinNativeBridgeDispatcher::OnRemoveNamedObject(const std::string& name) { + // Removal becomes in effect on next reload. We simply removing the entry + // from the map here. + NamedObjectMap::iterator iter = named_objects_.find(name); + DCHECK(iter != named_objects_.end()); + named_objects_.erase(iter); +} + +void GinNativeBridgeDispatcher::GetNativeMethods( + ObjectID object_id, + std::set* methods) { + render_frame()->Send( + new GinNativeBridgeHostMsg_GetMethods(routing_id(), object_id, methods)); +} + +bool GinNativeBridgeDispatcher::HasNativeMethod( + ObjectID object_id, + const std::string& method_name) { + bool result; + render_frame()->Send(new GinNativeBridgeHostMsg_HasMethod( + routing_id(), object_id, method_name, &result)); + return result; +} + +std::unique_ptr GinNativeBridgeDispatcher::InvokeNativeMethod( + ObjectID object_id, + const std::string& method_name, + const base::Value::List& arguments, + GinNativeBridgeError* error) { + LOG(INFO) << __FUNCTION__; + base::Value::List result_wrapper; + render_frame()->Send(new GinNativeBridgeHostMsg_InvokeMethod( + routing_id(), object_id, method_name, arguments, &result_wrapper, error)); + if (result_wrapper.empty()) + return nullptr; + return base::Value::ToUniquePtrValue(result_wrapper[0].Clone()); +} + +GinNativeBridgeObject* GinNativeBridgeDispatcher::GetObject( + ObjectID object_id) { + GinNativeBridgeObject* result = objects_.Lookup(object_id); + if (!result) { + result = GinNativeBridgeObject::InjectAnonymous(AsWeakPtr(), object_id); + if (result) + objects_.AddWithID(result, object_id); + } + return result; +} + +void GinNativeBridgeDispatcher::OnDestruct() { + delete this; +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.h b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.h new file mode 100644 index 0000000..0905eb6 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_dispatcher.h @@ -0,0 +1,77 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_DISPATCHER_H_ +#define EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_DISPATCHER_H_ + +#include +#include +#include + +#include "base/containers/id_map.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "content/public/renderer/render_frame_observer.h" +#include "ewk/efl_integration/common/gin_native_bridge_errors.h" + +namespace blink { +class WebFrame; +} + +namespace content { + +class GinNativeBridgeObject; + +// This class handles injecting Native objects into the main frame of a +// RenderView. The 'add' and 'remove' messages received from the browser +// process modify the entries in a map of 'pending' objects. These objects are +// bound to the window object of the main frame when that window object is next +// cleared. These objects remain bound until the window object is cleared +// again. + +class GinNativeBridgeDispatcher + : public base::SupportsWeakPtr, + public RenderFrameObserver { + public: + // GinNativeBridgeObjects are managed by gin. An object gets destroyed + // when it is no more referenced from JS. As GinNativeBridgeObjects reports + // deletion of self to GinNativeBridgeDispatcher, we would not have stale + // pointers here. + typedef base::IDMap ObjectMap; + typedef ObjectMap::KeyType ObjectID; + + explicit GinNativeBridgeDispatcher(RenderFrame* render_frame); + ~GinNativeBridgeDispatcher() override; + + GinNativeBridgeDispatcher(const GinNativeBridgeDispatcher&) = delete; + GinNativeBridgeDispatcher& operator=(const GinNativeBridgeDispatcher&) = + delete; + + // RenderFrameObserver override: + void OnDestruct() override; + bool OnMessageReceived(const IPC::Message& message) override; + void DidClearWindowObject() override; + + void GetNativeMethods(ObjectID object_id, std::set* methods); + bool HasNativeMethod(ObjectID object_id, const std::string& method_name); + std::unique_ptr InvokeNativeMethod( + ObjectID object_id, + const std::string& method_name, + const base::Value::List& arguments, + GinNativeBridgeError* error); + GinNativeBridgeObject* GetObject(ObjectID object_id); + + private: + void OnAddNamedObject(const std::string& name, ObjectID object_id); + void OnRemoveNamedObject(const std::string& name); + + typedef std::map NamedObjectMap; + NamedObjectMap named_objects_; + ObjectMap objects_; + bool inside_did_clear_window_object_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_DISPATCHER_H_ diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.cc b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.cc new file mode 100644 index 0000000..caf9e41 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.cc @@ -0,0 +1,124 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "renderer/gin_native_bridge_object.h" + +#include "common/gin_native_bridge_messages.h" +#include "content/public/renderer/render_thread.h" +#include "gin/function_template.h" +#include "renderer/gin_native_function_invocation_helper.h" +#include "third_party/blink/public/web/blink.h" +#include "third_party/blink/public/web/web_frame.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "v8/include/v8-function.h" + +namespace content { +// static +GinNativeBridgeObject* GinNativeBridgeObject::InjectNamed( + blink::WebFrame* frame, + const base::WeakPtr& dispatcher, + const std::string& object_name, + GinNativeBridgeDispatcher::ObjectID object_id) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + + if (!frame->IsWebLocalFrame()) + return NULL; + + v8::Local context = + frame->ToWebLocalFrame()->MainWorldScriptContext(); + if (context.IsEmpty()) + return NULL; + + GinNativeBridgeObject* object = + new GinNativeBridgeObject(isolate, dispatcher, object_id); + + v8::Context::Scope context_scope(context); + v8::Handle global = context->Global(); + gin::Handle controller = + gin::CreateHandle(isolate, object); + // WrappableBase instance deletes itself in case of a wrapper + // creation failure, thus there is no need to delete |object|. + if (controller.IsEmpty()) + return NULL; + + global->Set(context, gin::StringToV8(isolate, object_name), controller.ToV8()) + .Check(); + return object; +} + +// static +GinNativeBridgeObject* GinNativeBridgeObject::InjectAnonymous( + const base::WeakPtr& dispatcher, + GinNativeBridgeDispatcher::ObjectID object_id) { + return new GinNativeBridgeObject(blink::MainThreadIsolate(), dispatcher, + object_id); +} + +GinNativeBridgeObject::GinNativeBridgeObject( + v8::Isolate* isolate, + const base::WeakPtr& dispatcher, + GinNativeBridgeDispatcher::ObjectID object_id) + : gin::NamedPropertyInterceptor(isolate, this), + dispatcher_(dispatcher), + object_id_(object_id), + frame_routing_id_(dispatcher_->routing_id()), + template_cache_(isolate) {} + +GinNativeBridgeObject::~GinNativeBridgeObject() {} + +gin::ObjectTemplateBuilder GinNativeBridgeObject::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return gin::Wrappable::GetObjectTemplateBuilder( + isolate) + .AddNamedPropertyInterceptor(); +} + +v8::Local GinNativeBridgeObject::GetNamedProperty( + v8::Isolate* isolate, + const std::string& property) { + std::map::iterator method_pos = + known_methods_.find(property); + if (method_pos == known_methods_.end()) { + if (!dispatcher_) + return v8::Local(); + + known_methods_[property] = + dispatcher_->HasNativeMethod(object_id_, property); + } + if (known_methods_[property]) + return GetFunctionTemplate(isolate, property) + ->GetFunction(isolate->GetCurrentContext()) + .FromMaybe(v8::Local()); + else + return v8::Local(); +} + +std::vector GinNativeBridgeObject::EnumerateNamedProperties( + v8::Isolate* isolate) { + std::set method_names; + if (dispatcher_) + dispatcher_->GetNativeMethods(object_id_, &method_names); + return std::vector(method_names.begin(), method_names.end()); +} + +v8::Local GinNativeBridgeObject::GetFunctionTemplate( + v8::Isolate* isolate, + const std::string& name) { + v8::Local function_template = template_cache_.Get(name); + if (!function_template.IsEmpty()) + return function_template; + function_template = gin::CreateFunctionTemplate( + isolate, + base::BindRepeating(&GinNativeFunctionInvocationHelper::Invoke, + base::Owned(new GinNativeFunctionInvocationHelper( + name, dispatcher_)))); + template_cache_.Set(name, function_template); + return function_template; +} + +gin::WrapperInfo GinNativeBridgeObject::kWrapperInfo = { + gin::kEmbedderNativeGin}; + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.h b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.h new file mode 100644 index 0000000..4c5af69 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_object.h @@ -0,0 +1,74 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_OBJECT_H_ +#define EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_OBJECT_H_ + +#include +#include +#include +#include + +#include "base/memory/weak_ptr.h" +#include "gin/handle.h" +#include "gin/interceptor.h" +#include "gin/object_template_builder.h" +#include "gin/wrappable.h" +#include "renderer/gin_native_bridge_dispatcher.h" +#include "v8/include/v8-util.h" + +namespace blink { +class WebFrame; +} + +namespace content { + +class GinNativeBridgeObject : public gin::Wrappable, + public gin::NamedPropertyInterceptor { + public: + static gin::WrapperInfo kWrapperInfo; + GinNativeBridgeDispatcher::ObjectID object_id() const { return object_id_; } + + // gin::Wrappable. + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + + // gin::NamedPropertyInterceptor + v8::Local GetNamedProperty(v8::Isolate* isolate, + const std::string& property) override; + std::vector EnumerateNamedProperties( + v8::Isolate* isolate) override; + + static GinNativeBridgeObject* InjectNamed( + blink::WebFrame* frame, + const base::WeakPtr& dispatcher, + const std::string& object_name, + GinNativeBridgeDispatcher::ObjectID object_id); + static GinNativeBridgeObject* InjectAnonymous( + const base::WeakPtr& dispatcher, + GinNativeBridgeDispatcher::ObjectID object_id); + + private: + GinNativeBridgeObject( + v8::Isolate* isolate, + const base::WeakPtr& dispatcher, + GinNativeBridgeDispatcher::ObjectID object_id); + ~GinNativeBridgeObject() override; + + GinNativeBridgeObject(const GinNativeBridgeObject&) = delete; + GinNativeBridgeObject& operator=(const GinNativeBridgeObject&) = delete; + + v8::Local GetFunctionTemplate(v8::Isolate* isolate, + const std::string& name); + + base::WeakPtr dispatcher_; + GinNativeBridgeDispatcher::ObjectID object_id_; + int frame_routing_id_; + std::map known_methods_; + v8::StdGlobalValueMap template_cache_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_OBJECT_H_ diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.cc b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.cc new file mode 100644 index 0000000..209eb6a --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.cc @@ -0,0 +1,37 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "renderer/gin_native_bridge_value_converter.h" + +#include + +#include "base/values.h" +#include "gin/array_buffer.h" +#include "renderer/gin_native_bridge_object.h" + +namespace content { + +GinNativeBridgeValueConverter::GinNativeBridgeValueConverter() + : converter_(V8ValueConverter::Create()) { + converter_->SetDateAllowed(false); + converter_->SetRegExpAllowed(false); + converter_->SetFunctionAllowed(true); + converter_->SetStrategy(this); +} + +GinNativeBridgeValueConverter::~GinNativeBridgeValueConverter() {} + +v8::Local GinNativeBridgeValueConverter::ToV8Value( + const base::Value* value, + v8::Local context) const { + return converter_->ToV8Value(*value, context); +} + +std::unique_ptr GinNativeBridgeValueConverter::FromV8Value( + v8::Local value, + v8::Local context) const { + return converter_->FromV8Value(value, context); +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.h b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.h new file mode 100644 index 0000000..fb4185b --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_bridge_value_converter.h @@ -0,0 +1,36 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_VALUE_CONVERTER_H_ +#define EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_VALUE_CONVERTER_H_ + +#include "content/common/content_export.h" +#include "content/public/renderer/v8_value_converter.h" + +namespace content { + +class GinNativeBridgeValueConverter + : public content::V8ValueConverter::Strategy { + public: + CONTENT_EXPORT GinNativeBridgeValueConverter(); + CONTENT_EXPORT ~GinNativeBridgeValueConverter() override; + + GinNativeBridgeValueConverter(const GinNativeBridgeValueConverter&) = delete; + GinNativeBridgeValueConverter& operator=( + const GinNativeBridgeValueConverter&) = delete; + + CONTENT_EXPORT v8::Local ToV8Value( + const base::Value* value, + v8::Local context) const; + CONTENT_EXPORT std::unique_ptr FromV8Value( + v8::Local value, + v8::Local context) const; + + private: + std::unique_ptr converter_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_BRIDGE_VALUE_CONVERTER_H_ diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.cc b/tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.cc new file mode 100644 index 0000000..8906fdd --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.cc @@ -0,0 +1,108 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "renderer/gin_native_function_invocation_helper.h" + +#include "common/gin_native_bridge_value.h" +#include "content/public/renderer/v8_value_converter.h" +#include "renderer/gin_native_bridge_object.h" +#include "renderer/gin_native_bridge_value_converter.h" +#include "v8/include/v8-exception.h" + +namespace content { + +namespace { + +const char kMethodInvocationAsConstructorDisallowed[] = + "Native bridge method can't be invoked as a constructor"; +const char kMethodInvocationOnNonInjectedObjectDisallowed[] = + "Native bridge method can't be invoked on a non-injected object"; +const char kMethodInvocationErrorMessage[] = + "Native bridge method invocation error"; + +} // namespace + +GinNativeFunctionInvocationHelper::GinNativeFunctionInvocationHelper( + const std::string& method_name, + const base::WeakPtr& dispatcher) + : method_name_(method_name), + dispatcher_(dispatcher), + converter_(new GinNativeBridgeValueConverter()) {} + +GinNativeFunctionInvocationHelper::~GinNativeFunctionInvocationHelper() {} + +v8::Local GinNativeFunctionInvocationHelper::Invoke( + gin::Arguments* args) { + if (!dispatcher_) { + args->isolate()->ThrowException(v8::Exception::Error( + gin::StringToV8(args->isolate(), kMethodInvocationErrorMessage))); + return v8::Undefined(args->isolate()); + } + + if (args->IsConstructCall()) { + args->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8( + args->isolate(), kMethodInvocationAsConstructorDisallowed))); + return v8::Undefined(args->isolate()); + } + + content::GinNativeBridgeObject* object = NULL; + if (!args->GetHolder(&object) || !object) { + args->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8( + args->isolate(), kMethodInvocationOnNonInjectedObjectDisallowed))); + return v8::Undefined(args->isolate()); + } + + base::Value::List arguments; + { + v8::HandleScope handle_scope(args->isolate()); + v8::Local context = args->isolate()->GetCurrentContext(); + v8::Local val; + while (args->GetNext(&val)) { + std::unique_ptr arg(converter_->FromV8Value(val, context)); + if (arg.get()) { + arguments.Append(base::Value::FromUniquePtrValue(std::move(arg))); + } else { + arguments.Append(base::Value()); + } + } + } + + GinNativeBridgeError error; + std::unique_ptr result = dispatcher_->InvokeNativeMethod( + object->object_id(), method_name_, arguments, &error); + if (!result.get()) { + args->isolate()->ThrowException(v8::Exception::Error( + gin::StringToV8(args->isolate(), GinNativeBridgeErrorToString(error)))); + return v8::Undefined(args->isolate()); + } + if (!result->is_blob()) { + return converter_->ToV8Value(result.get(), + args->isolate()->GetCurrentContext()); + } + + std::unique_ptr gin_value = + GinNativeBridgeValue::FromValue(result.get()); + + if (gin_value->IsType(GinNativeBridgeValue::TYPE_OBJECT_ID)) { + GinNativeBridgeObject* result = NULL; + GinNativeBridgeDispatcher::ObjectID object_id; + if (gin_value->GetAsObjectID(&object_id)) { + result = dispatcher_->GetObject(object_id); + } + if (result) { + gin::Handle controller = + gin::CreateHandle(args->isolate(), result); + if (controller.IsEmpty()) + return v8::Undefined(args->isolate()); + return controller.ToV8(); + } + } else if (gin_value->IsType(GinNativeBridgeValue::TYPE_NONFINITE)) { + float float_value; + gin_value->GetAsNonFinite(&float_value); + return v8::Number::New(args->isolate(), float_value); + } + return v8::Undefined(args->isolate()); +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.h b/tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.h new file mode 100644 index 0000000..adca806 --- /dev/null +++ b/tizen_src/ewk/efl_integration/renderer/gin_native_function_invocation_helper.h @@ -0,0 +1,42 @@ +// Copyright 2017 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_FUNCTION_INVOCATION_HELPER_H_ +#define EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_FUNCTION_INVOCATION_HELPER_H_ + +#include +#include + +#include "base/memory/weak_ptr.h" +#include "gin/arguments.h" +#include "gin/handle.h" +#include "renderer/gin_native_bridge_dispatcher.h" + +namespace content { + +class GinNativeBridgeValueConverter; + +class GinNativeFunctionInvocationHelper { + public: + GinNativeFunctionInvocationHelper( + const std::string& method_name, + const base::WeakPtr& dispatcher); + ~GinNativeFunctionInvocationHelper(); + + GinNativeFunctionInvocationHelper(const GinNativeFunctionInvocationHelper&) = + delete; + GinNativeFunctionInvocationHelper& operator=( + const GinNativeFunctionInvocationHelper&) = delete; + + v8::Local Invoke(gin::Arguments* args); + + private: + std::string method_name_; + base::WeakPtr dispatcher_; + std::unique_ptr converter_; +}; + +} // namespace content + +#endif // EWK_EFL_INTEGRATION_RENDERER_GIN_NATIVE_FUNCTION_INVOCATION_HELPER_H_ -- 2.7.4 From 466cbd900fd1345e16151291208758c451d818aa Mon Sep 17 00:00:00 2001 From: "b.kiran" Date: Wed, 25 Jan 2023 10:26:48 +0530 Subject: [PATCH 08/16] [M108 Migration] Implement view port setting and zoom factor API This patch implement below preference setting and API for content scale. 1. As default meta view port enabling for mobile 2. Implement ewk api for view port set/get Reference: https://review.tizen.org/gerrit/c/278887 Change-Id: Id030ba049d55d46e55aaa2b8c75e27f3c7ed5fe9 Signed-off-by: Bakka Uday Kiran --- content/browser/web_contents/web_contents_impl.cc | 8 ++++++++ tizen_src/ewk/efl_integration/eweb_context.cc | 22 ++++++++++++++++++++++ tizen_src/ewk/efl_integration/eweb_context.h | 3 +++ .../efl_integration/private/ewk_context_private.cc | 8 ++++++++ .../efl_integration/private/ewk_context_private.h | 4 ++++ .../ewk/efl_integration/public/ewk_context.cc | 16 +++++++++++----- 6 files changed, 56 insertions(+), 5 deletions(-) diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 0f16da0..c2cd303 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -189,6 +189,7 @@ #if BUILDFLAG(IS_EFL) #include "content/browser/date_time_chooser_efl.h" +#include "tizen/system_info.h" #endif #if BUILDFLAG(IS_ANDROID) @@ -2829,6 +2830,13 @@ const blink::web_pref::WebPreferences WebContentsImpl::ComputeWebPreferences() { prefs.viewport_meta_enabled = false; } +#if BUILDFLAG(IS_EFL) + if (IsMobileProfile()) + prefs.viewport_meta_enabled = true; + + prefs.viewport_enabled |= prefs.viewport_meta_enabled; +#endif + prefs.spatial_navigation_enabled = command_line.HasSwitch(switches::kEnableSpatialNavigation); diff --git a/tizen_src/ewk/efl_integration/eweb_context.cc b/tizen_src/ewk/efl_integration/eweb_context.cc index e74e8a3..6e0ef15 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.cc +++ b/tizen_src/ewk/efl_integration/eweb_context.cc @@ -21,6 +21,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/dom_storage_context.h" +#include "content/public/browser/host_zoom_map.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_usage_info.h" @@ -31,6 +32,7 @@ #include "storage/browser/database/database_quota_client.h" #include "storage/browser/file_system/file_system_quota_client.h" #include "storage/browser/quota/quota_manager.h" +#include "third_party/blink/public/common/page/page_zoom.h" #include "ui/gl/gl_shared_context_efl.h" #if defined(ENABLE_PLUGINS) @@ -799,6 +801,26 @@ bool EWebContext::GetExtensibleAPI(const std::string& api_name) { return TizenExtensibleHost::GetInstance()->GetExtensibleAPI(api_name); } +void EWebContext::SetDefaultZoomFactor(double zoom_factor) { + content::HostZoomMap* host_zoom_map = + content::HostZoomMap::GetDefaultForBrowserContext(browser_context_.get()); + if (host_zoom_map) { + host_zoom_map->SetDefaultZoomLevel( + blink::PageZoomFactorToZoomLevel(zoom_factor)); + } +} + +double EWebContext::GetDefaultZoomFactor() const { + content::HostZoomMap* host_zoom_map = + content::HostZoomMap::GetDefaultForBrowserContext(browser_context_.get()); + if (host_zoom_map) { + return blink::PageZoomLevelToZoomFactor( + host_zoom_map->GetDefaultZoomLevel()); + } + + return -1.0; +} + void EWebContext::SetInterceptRequestCallback( Ewk_Context* ewk_context, Ewk_Context_Intercept_Request_Callback callback, diff --git a/tizen_src/ewk/efl_integration/eweb_context.h b/tizen_src/ewk/efl_integration/eweb_context.h index 04812da..560b3aa 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.h +++ b/tizen_src/ewk/efl_integration/eweb_context.h @@ -174,6 +174,9 @@ class EWebContext { bool SetExtensibleAPI(const std::string& api_name, bool enable); bool GetExtensibleAPI(const std::string& api_name); + void SetDefaultZoomFactor(double zoom_factor); + double GetDefaultZoomFactor() const; + void SetInterceptRequestCallback( Ewk_Context* ewk_context, Ewk_Context_Intercept_Request_Callback callback, diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_private.cc b/tizen_src/ewk/efl_integration/private/ewk_context_private.cc index cd4e31d..f10f434 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_private.cc +++ b/tizen_src/ewk/efl_integration/private/ewk_context_private.cc @@ -269,6 +269,14 @@ void Ewk_Context::SetContextInterceptRequestCallback( impl->SetInterceptRequestCallback(this, callback, user_data); } +void Ewk_Context::SetDefaultZoomFactor(double zoom_factor) { + impl->SetDefaultZoomFactor(zoom_factor); +} + +double Ewk_Context::GetDefaultZoomFactor() const { + return impl->GetDefaultZoomFactor(); +} + #if BUILDFLAG(IS_TIZEN_TV) void Ewk_Context::SetApplicationType( const Ewk_Application_Type application_type) { diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_private.h b/tizen_src/ewk/efl_integration/private/ewk_context_private.h index dce8618..d6daffc 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_private.h +++ b/tizen_src/ewk/efl_integration/private/ewk_context_private.h @@ -134,6 +134,10 @@ struct Ewk_Context : public base::RefCounted { Ewk_Context_Notification_Cancel_Callback cancel_callback, void* user_data); + // default zoom factor + void SetDefaultZoomFactor(double zoom_factor); + double GetDefaultZoomFactor() const; + void SetContextInterceptRequestCallback( Ewk_Context_Intercept_Request_Callback callback, void* user_data); diff --git a/tizen_src/ewk/efl_integration/public/ewk_context.cc b/tizen_src/ewk/efl_integration/public/ewk_context.cc index 3e3d06f..358a9679 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_context.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_context.cc @@ -974,11 +974,6 @@ void ewk_context_form_autofill_credit_card_changed_callback_set( LOG_EWK_API_MOCKUP(); } -void ewk_context_default_zoom_factor_set(Ewk_Context* context, - double zoom_factor) { - LOG_EWK_API_MOCKUP(); -} - void ewk_context_application_type_set( Ewk_Context* ewkContext, const Ewk_Application_Type applicationType) { @@ -1002,3 +997,14 @@ Ewk_Application_Type ewk_context_application_type_get(Ewk_Context* ewkContext) { return EWK_APPLICATION_TYPE_OTHER; #endif } + +void ewk_context_default_zoom_factor_set(Ewk_Context* context, + double zoom_factor) { + EINA_SAFETY_ON_NULL_RETURN(context); + context->SetDefaultZoomFactor(zoom_factor); +} + +double ewk_context_default_zoom_factor_get(Ewk_Context* context) { + EINA_SAFETY_ON_NULL_RETURN_VAL(context, -1.0); + return context->GetDefaultZoomFactor(); +} -- 2.7.4 From 13abb71fc3add7717ff7284a5b14bd19c45aa3ed Mon Sep 17 00:00:00 2001 From: Bakka Uday Kiran Date: Wed, 25 Jan 2023 17:38:03 +0530 Subject: [PATCH 09/16] [M108 Migration][Product TV] Support TV specific keys 1. Support keys on TV remote controller, like the media control keys: play, pause, stop. Mapping these keys from EFL key names to VKEYs. 2. Enable DomCode and DomKey conversion on standard profiles. Reference: https://review.tizen.org/gerrit/c/277836 https://review.tizen.org/gerrit/c/279232 https://review.tizen.org/gerrit/c/279340 Change-Id: Iefb7f9c30a5bdc623e77adf2034c3c1c8160cb6a Signed-off-by: Bakka Uday Kiran --- .../blink/renderer/platform/keyboard_codes.h | 357 +++++++++++++++++++++ .../renderer/platform/windows_keyboard_codes.h | 154 +++++++++ .../ui/ozone/platform/efl/efl_keycode_map.h | 99 ++++++ ui/events/event.cc | 3 + ui/events/event_utils.h | 5 + ui/events/events_default.cc | 8 + ui/events/keycodes/dom/dom_key_data.inc | 127 ++++++++ ui/events/keycodes/keyboard_codes_posix.h | 159 +++++++++ 8 files changed, 912 insertions(+) diff --git a/third_party/blink/renderer/platform/keyboard_codes.h b/third_party/blink/renderer/platform/keyboard_codes.h index b183f16..b5c7d2f 100644 --- a/third_party/blink/renderer/platform/keyboard_codes.h +++ b/third_party/blink/renderer/platform/keyboard_codes.h @@ -564,6 +564,363 @@ enum { // VKEY_OEM_CLEAR (FE) Clear key VKEY_OEM_CLEAR = VK_OEM_CLEAR, +#if BUILDFLAG(IS_TIZEN_TV) + // VKEY_RED (193) Red key on tv remote. + VKEY_RED = VK_RED, + + // VKEY_GREEN (194) Green key on tv remote. + VKEY_GREEN = VK_GREEN, + + // VKEY_YELLOW (195) Yellow key on tv remote. + VKEY_YELLOW = VK_YELLOW, + + // VKEY_BLUE (196) Blue key on tv remote. + VKEY_BLUE = VK_BLUE, + + // VKEY_GREY (197) Grey key on tv remote. + VKEY_GREY = VK_GREY, + + // VKEY_BROWN (198) Brown key on tv remote. + VKEY_BROWN = VK_BROWN, + + // VKEY_DTV_RETURN (2719) Return key on tv remote. + VKEY_DTV_RETURN = VK_DTV_RETURN, + + // VKEY_DTV_HOME (2757) + VKEY_DTV_HOME = VK_DTV_HOME, + + // VKEY_SOURCE (2758) + VKEY_SOURCE = VK_SOURCE, + + // VKEY_CH_LIST (2759) + VKEY_CH_LIST = VK_CH_LIST, + + // VKEY_POWER (199) + VKEY_POWER = VK_POWER, + + // VKEY_DTV_MENU (2795) + VKEY_DTV_MENU = VK_DTV_MENU, + + // VKEY_GUIDE (1CA) + VKEY_GUIDE = VK_GUIDE, + + // VKEY_ADDDEL (1AD) + VKEY_ADDDEL = VK_ADDDEL, + + // VKEY_AUTO_PROGRAM (1B9) + VKEY_AUTO_PROGRAM = VK_AUTO_PROGRAM, + + // VKEY_FAVCH (1B1) + VKEY_FAVCH = VK_FAVCH, + + // VKEY_BT_DUALVIEW (1BB) + VKEY_BT_DUALVIEW = VK_BT_DUALVIEW, + + // VKEY_SUB_TITLE (1CC) + VKEY_SUB_TITLE = VK_SUB_TITLE, + + // VKEY_REWIND (19c) Rewind key on tv remote. + VKEY_REWIND = VK_REWIND, + + // VKEY_STOP (19D) + VKEY_STOP = VK_STOP, + + // VKEY_RECORD (1A0) + VKEY_RECORD = VK_RECORD, + + // VKEY_FAST_FWD (1a1) Fast forward key on tv remote. + VKEY_FAST_FWD = VK_FAST_FWD, + + // VKEY_CHANNEL_UP (1ab) P+ key on tv remote. + VKEY_CHANNEL_UP = VK_CHANNEL_UP, + + // VKEY_CHANNEL_DOWN (1ac) P- key on tv remote. + VKEY_CHANNEL_DOWN = VK_CHANNEL_DOWN, + + // VKEY_INFO (1C9) + VKEY_INFO = VK_INFO, + + // VKEY_REPEAT (2799) + VKEY_REPEAT = VK_REPEAT, + + // VKEY_ASPECT (279C) + VKEY_ASPECT = VK_ASPECT, + + // VKEY_PMODE (279D) + VKEY_PMODE = VK_PMODE, + + // VKEY_HDMI (279F) + VKEY_HDMI = VK_HDMI, + + // VKEY_USBHUB_SWITCH (27A0) + VKEY_USBHUB_SWITCH = VK_USBHUB_SWITCH, + + // VKEY_EMANUAL (27A2) + VKEY_EMANUAL = VK_EMANUAL, + + // VKEY_TOOLS (2797) + VKEY_TOOLS = VK_TOOLS, + + // VKEY_MORE (27A4) + VKEY_MORE = VK_MORE, + + // VKEY_FACTORY (27A5) + VKEY_FACTORY = VK_FACTORY, + + // VKEY_TV (27A9) + VKEY_TV = VK_TV, + + // VKEY_DTV (27AA) + VKEY_DTV = VK_DTV, + + // VKEY_STB_POWER (27AB) + VKEY_STB_POWER = VK_STB_POWER, + + // VKEY_PANEL_DOWN (27AD) + VKEY_PANEL_DOWN = VK_PANEL_DOWN, + + // VKEY_CONVERGENCE (27AE) + VKEY_CONVERGENCE = VK_CONVERGENCE, + + // VKEY_BT_COLOR_MECHA (27AF) + VKEY_BT_COLOR_MECHA = VK_BT_COLOR_MECHA, + + // VKEY_STILL_PICTURE (27B0) + VKEY_STILL_PICTURE = VK_STILL_PICTURE, + + // VKEY_BT_TRIGGER (27B1) + VKEY_BT_TRIGGER = VK_BT_TRIGGER, + + // VKEY_BT_HOTVK (27B2) + VKEY_BT_HOTVK = VK_BT_HOTVK, + + // VKEY_BT_DEVICE (27B3) + VKEY_BT_DEVICE = VK_BT_DEVICE, + + // VKEY_BT_CONTENTSBAR (27B4) + VKEY_BT_CONTENTSBAR = VK_BT_CONTENTSBAR, + + // VKEY_GAME (27B5) + VKEY_GAME = VK_GAME, + + // VKEY_PIP_CHUP (27B7) + VKEY_PIP_CHUP = VK_PIP_CHUP, + + // VKEY_PIP_CHDOWN (27B8) + VKEY_PIP_CHDOWN = VK_PIP_CHDOWN, + + // VKEY_ANTENA (27B9) + VKEY_ANTENA = VK_ANTENA, + + // VKEY_PANEL_ENTER (27BB) + VKEY_PANEL_ENTER = VK_PANEL_ENTER, + + // VKEY_LINK (27BC) + VKEY_LINK = VK_LINK, + + // VKEY_PANEL_UP (27BD) + VKEY_PANEL_UP = VK_PANEL_UP, + + // VKEY_ANGLE (27C1) + VKEY_ANGLE = VK_ANGLE, + + // VKEY_WHEEL_LEFT (27C2) + VKEY_WHEEL_LEFT = VK_WHEEL_LEFT, + + // VKEY_WHEEL_RIGHT (27C3) + VKEY_WHEEL_RIGHT = VK_WHEEL_RIGHT, + + // VKEY_CONTENTS (2757) + VKEY_CONTENTS = VK_CONTENTS, + + // VKEY_PANEL_EXIT (27C5) + VKEY_PANEL_EXIT = VK_PANEL_EXIT, + + // VKEY_EXIT (27C6) + VKEY_EXIT = VK_EXIT, + + // VKEY_MBR_TV (27C7) + VKEY_MBR_TV = VK_MBR_TV, + + // VKEY_MBR_STB_GUIDE (27C8) + VKEY_MBR_STB_GUIDE = VK_MBR_STB_GUIDE, + + // VKEY_MBR_BD_POPUP (27C9) + VKEY_MBR_BD_POPUP = VK_MBR_BD_POPUP, + + // VKEY_MBR_BDDVD_POWER (27CA) + VKEY_MBR_BDDVD_POWER = VK_MBR_BDDVD_POWER, + + // VKEY_MBR_SETUP_FAILURE (27CB) + VKEY_MBR_SETUP_FAILURE = VK_MBR_SETUP_FAILURE, + + // VKEY_MBR_SETUP (27CC) + VKEY_MBR_SETUP = VK_MBR_SETUP, + + // VKEY_MBR_WATCH_TV (27CD) + VKEY_MBR_WATCH_TV = VK_MBR_WATCH_TV, + + // VKEY_PRECH (27CE) + VKEY_PRECH = VK_PRECH, + + // VKEY_RECOMMEND_SEARCH_TOGGLE (27D0) + VKEY_RECOMMEND_SEARCH_TOGGLE = VK_RECOMMEND_SEARCH_TOGGLE, + + // VKEY_BT_NUMBER (27D1) + VKEY_BT_NUMBER = VK_BT_NUMBER, + + // VKEY_16_9 (27D2) + VKEY_16_9 = VK_16_9, + + // VKEY_MTS (27D3) + VKEY_MTS = VK_MTS, + + // VKEY_SMODE (27D5) + VKEY_SMODE = VK_SMODE, + + // VKEY_3SPEED (27D6) + VKEY_3SPEED = VK_3SPEED, + + // VKEY_3D (27D7) + VKEY_3D = VK_3D, + + // VKEY_TTX_MIX (27D8) + VKEY_TTX_MIX = VK_TTX_MIX, + + // VKEY_SRSTSXT (27D9) + VKEY_SRSTSXT = VK_SRSTSXT, + + // VKEY_WIFI_PAIRING (27DA) + VKEY_WIFI_PAIRING = VK_WIFI_PAIRING, + + // VKEY_BT_SAMSUNG_APPS (27E3) + VKEY_BT_SAMSUNG_APPS = VK_BT_SAMSUNG_APPS, + + // VKEY_W_LINK (2757) + VKEY_W_LINK = VK_W_LINK, + + // VKEY_ESAVING (27E5) + VKEY_ESAVING = VK_ESAVING, + + // VKEY_TV_SNS (27E9) + VKEY_TV_SNS = VK_TV_SNS, + + // VKEY_DVR (27EA) + VKEY_DVR = VK_DVR, + + // VKEY_APP_LIST (27EB) + VKEY_APP_LIST = VK_APP_LIST, + + // VKEY_CAMERA (27EC) + VKEY_CAMERA = VK_CAMERA, + + // VKEY_CAPTION (27ED) + VKEY_CAPTION = VK_CAPTION, + + // VKEY_ZOOM1 (27EE) + VKEY_ZOOM1 = VK_ZOOM1, + + // VKEY_PANEL_PLUS (27EF) + VKEY_PANEL_PLUS = VK_PANEL_PLUS, + + // VKEY_BT_VOICE (27F0) + VKEY_BT_VOICE = VK_BT_VOICE, + + // VKEY_SEARCH (27F1) + VKEY_SEARCH = VK_SEARCH, + + // VKEY_PANEL_MINUS (27F3) + VKEY_PANEL_MINUS = VK_PANEL_MINUS, + + // VKEY_SOCCER_MODE (27F4) + VKEY_SOCCER_MODE = VK_SOCCER_MODE, + + // VKEY_FUNCTIONS_AMAZON (27F5) + VKEY_FUNCTIONS_AMAZON = VK_FUNCTIONS_AMAZON, + + // VKEY_AD (27F6) + VKEY_AD = VK_AD, + + // VKEY_REWIND_ (27F8) + VKEY_REWIND_ = VK_REWIND_, + + // VKEY_FF_ (27F9) + VKEY_FF_ = VK_FF_, + + // VKEY_FUNCTIONS_NETFLIX (27FA) + VKEY_FUNCTIONS_NETFLIX = VK_FUNCTIONS_NETFLIX, + + // VKEY_PIP_ONOFF (27FB) + VKEY_PIP_ONOFF = VK_PIP_ONOFF, + + // VKEY_MBR_WATCH_MOVIE (27FC) + VKEY_MBR_WATCH_MOVIE = VK_MBR_WATCH_MOVIE, + + // VKEY_MBR_STBBD_MENU (27FD) + VKEY_MBR_STBBD_MENU = VK_MBR_STBBD_MENU, + + // VKEY_MBR_SETUP_CONFIRM (27FE) + VKEY_MBR_SETUP_CONFIRM = VK_MBR_SETUP_CONFIRM, + + // VKEY_FAMILYHUB (27FF) + VKEY_FAMILYHUB = VK_FAMILYHUB, + + // VKEY_ANYVIEW (2800) + VKEY_ANYVIEW = VK_ANYVIEW, + + // VKEY_PAGE_LEFT (2809) + VKEY_PAGE_LEFT = VK_PAGE_LEFT, + + // VKEY_PAGE_RIGHT (280A) + VKEY_PAGE_RIGHT = VK_PAGE_RIGHT, + + // VKEY_SOFT_WAKE_UP (2804) + VKEY_SOFT_WAKE_UP = VK_SOFT_WAKE_UP, + + // VKEY_PANEL_ON (280B) + VKEY_PANEL_ON = VK_PANEL_ON, + + // VKEY_PLAY_BACK (280C) + VKEY_PLAY_BACK = VK_PLAY_BACK, + + // VKEY_EXTRA (280D) + VKEY_EXTRA = VK_EXTRA, + + // VKEY_COLOR (2891) + VKEY_COLOR = VK_COLOR, + + // VKEY_ALARM (28B2) + VKEY_ALARM = VK_ALARM, + + // VKEY_HOTEL_MOVIES (28FE) + VKEY_HOTEL_MOVIES = VK_HOTEL_MOVIES, + + // VKEY_HOTEL_LANGUAGE (28FF) + VKEY_HOTEL_LANGUAGE = VK_HOTEL_LANGUAGE, + + // VKEY_HOTEL_TV_GUIDE (2900) + VKEY_HOTEL_TV_GUIDE = VK_HOTEL_TV_GUIDE, + + // VKEY_HOTEL_APPS_GUEST (2901) + VKEY_HOTEL_APPS_GUEST = VK_HOTEL_APPS_GUEST, + + // VKEY_NOISE_REDUCTION (2917) + VKEY_NOISE_REDUCTION = VK_NOISE_REDUCTION, + + // VKEY_NR (2919) + VKEY_NR = VK_NR, + + // VKEY_HOTEL_ROOM_CONTROL (291A) + VKEY_HOTEL_ROOM_CONTROL = VK_HOTEL_ROOM_CONTROL, + + // VKEY_IME_DONE (FF60) Done key on TV IME panel + VKEY_IME_DONE = VK_IME_DONE, + + // VKEY_IME_CANCEL (FF69) Cancel key on TV IME panel + VKEY_IME_CANCEL = VK_IME_CANCEL, + +#endif + VKEY_UNKNOWN = 0 }; diff --git a/third_party/blink/renderer/platform/windows_keyboard_codes.h b/third_party/blink/renderer/platform/windows_keyboard_codes.h index fea3fa6..dcfd4d3 100644 --- a/third_party/blink/renderer/platform/windows_keyboard_codes.h +++ b/third_party/blink/renderer/platform/windows_keyboard_codes.h @@ -142,9 +142,11 @@ #ifndef VK_DELETE #define VK_DELETE 0x2E // DEL key #endif +#if !BUILDFLAG(IS_TIZEN_TV) #ifndef VK_HELP #define VK_HELP 0x2F // HELP key #endif +#endif #define VK_0 0x30 #define VK_1 0x31 @@ -334,6 +336,158 @@ #define VK_OEM_CLEAR 0xFE // Clear key +#if BUILDFLAG(IS_TIZEN_TV) +// TV keys on remote controller. +// Virtual keys defined in http://www.atsc.org/cms/standards/a100/a_100_2.pdf +// Same volume virtual keys are already defined in Windows virtual keys but we +// overlap with the keys defined in DTV. +#undef VK_PLAY +#undef VK_VOLUME_UP +#undef VK_VOLUME_DOWN +#undef VK_VOLUME_MUTE +#undef VK_SLEEP +#undef VK_CLEAR + +#define VK_RED 0x193 +#define VK_GREEN 0x194 +#define VK_YELLOW 0x195 +#define VK_BLUE 0x196 +#define VK_GREY 0x197 +#define VK_BROWN 0x198 +#define VK_DTV_RETURN 0x2719 +#define VK_DTV_HOME 0x2757 +#define VK_SOURCE 0x2758 +#define VK_CH_LIST 0x2759 +#define VK_POWER 0x199 +#define VK_DTV_MENU 0x2795 +#define VK_GUIDE 0x1CA +#define VK_ADDDEL 0x1AD +#define VK_AUTO_PROGRAM 0x1B9 +#define VK_FAVCH 0x1B1 +#define VK_BT_DUALVIEW 0x1BB +#define VK_SUB_TITLE 0x1CC +#define VK_REWIND 0x19C +#define VK_STOP 0x19D +#define VK_PLAY 0x19F +#define VK_RECORD 0x1A0 +#define VK_FAST_FWD 0x1A1 +#define VK_CHANNEL_UP 0x1AB +#define VK_CHANNEL_DOWN 0x1AC +#define VK_VOLUME_UP 0x1BF +#define VK_VOLUME_DOWN 0x1C0 +#define VK_VOLUME_MUTE 0x1C1 +#define VK_INFO 0x1C9 +#define VK_REPEAT 0x2799 +#define VK_ASPECT 0x279C +#define VK_PMODE 0x279D +#define VK_HDMI 0x279F +#define VK_USBHUB_SWITCH 0x27A0 +#define VK_EMANUAL 0x27A2 +#define VK_TOOLS 0x2797 +#define VK_MORE 0x27A4 +#define VK_FACTORY 0x27A5 +#define VK_SLEEP 0x27A6 +#define VK_TV 0x27A9 +#define VK_DTV 0x27AA +#define VK_STB_POWER 0x27AB +#define VK_PANEL_DOWN 0x27AD +#define VK_CONVERGENCE 0x27AE +#define VK_BT_COLOR_MECHA 0x27AF +#define VK_STILL_PICTURE 0x27B0 +#define VK_BT_TRIGGER 0x27B1 +#define VK_BT_HOTVK 0x27B2 +#define VK_BT_DEVICE 0x27B3 +#define VK_BT_CONTENTSBAR 0x27B4 +#define VK_GAME 0x27B5 +#define VK_PIP_CHUP 0x27B7 +#define VK_PIP_CHDOWN 0x27B8 +#define VK_ANTENA 0x27B9 +#define VK_PANEL_ENTER 0x27BB +#define VK_LINK 0x27BC +#define VK_PANEL_UP 0x27BD + +#define VK_ANGLE 0x27C1 +#define VK_WHEEL_LEFT 0x27C2 +#define VK_WHEEL_RIGHT 0x27C3 +#define VK_CONTENTS 0x2757 +#define VK_PANEL_EXIT 0x27C5 +#define VK_EXIT 0x27C6 + +#define VK_MBR_TV 0x27C7 +#define VK_MBR_STB_GUIDE 0x27C8 +#define VK_MBR_BD_POPUP 0x27C9 +#define VK_MBR_BDDVD_POWER 0x27CA +#define VK_MBR_SETUP_FAILURE 0x27CB +#define VK_MBR_SETUP 0x27CC +#define VK_MBR_WATCH_TV 0x27CD + +#define VK_PRECH 0x27CE +#define VK_RECOMMEND_SEARCH_TOGGLE 0x27D0 +#define VK_BT_NUMBER 0x27D1 +#define VK_16_9 0x27D2 +#define VK_MTS 0x27D3 +#define VK_SMODE 0x27D5 +#define VK_3SPEED 0x27D6 +#define VK_3D 0x27D7 +#define VK_TTX_MIX 0x27D8 +#define VK_SRSTSXT 0x27D9 +#define VK_WIFI_PAIRING 0x27DA +#define VK_BT_SAMSUNG_APPS 0x27E3 +#define VK_W_LINK 0x2757 +#define VK_ESAVING 0x27E5 +#define VK_CLEAR 0x27E6 +#define VK_TV_SNS 0x27E9 +#define VK_DVR 0x27EA +#define VK_APP_LIST 0x27EB +#define VK_CAMERA 0x27EC +#define VK_CAPTION 0x27ED +#define VK_ZOOM1 0x27EE +#define VK_PANEL_PLUS 0x27EF +#define VK_BT_VOICE 0x27F0 +#define VK_SEARCH 0x27F1 +#define VK_PANEL_MINUS 0x27F3 +#define VK_SOCCER_MODE 0x27F4 +#define VK_FUNCTIONS_AMAZON 0x27F5 +#define VK_AD 0x27F6 +#define VK_REWIND_ 0x27F8 +#define VK_FF_ 0x27F9 +#define VK_FUNCTIONS_NETFLIX 0x27FA +#define VK_PIP_ONOFF 0x27FB +#define VK_MBR_WATCH_MOVIE 0x27FC +#define VK_MBR_STBBD_MENU 0x27FD +#define VK_MBR_SETUP_CONFIRM 0x27FE +#define VK_FAMILYHUB 0x27FF +#define VK_ANYVIEW 0x2800 +#define VK_PAGE_LEFT 0x2809 +#define VK_PAGE_RIGHT 0x280A + +#define VK_SOFT_WAKE_UP 0x2804 +#define VK_PANEL_ON 0x280B +#define VK_PLAY_BACK 0x280C +#define VK_EXTRA 0x280D +#define VK_COLOR 0x2891 + +#define VK_ALARM 0x28B2 +#define VK_HOTEL_MOVIES 0x28FE +#define VK_HOTEL_LANGUAGE 0x28FF +#define VK_HOTEL_TV_GUIDE 0x2900 +#define VK_HOTEL_APPS_GUEST 0x2901 +#define VK_NOISE_REDUCTION 0x2917 +#define VK_HELP 0x2918 +#define VK_NR 0x2919 +#define VK_HOTEL_ROOM_CONTROL 0x291A + +#define VK_IME_DONE \ + 0xFF60 // keyname of IME Done button is Select. but Select(0xFF60) is only + // Tizen TV IME keyname defined by ISF, there is no X Server keycode. + // 0xFF60 is ISF keycode. +#define VK_IME_CANCEL \ + 0xFF69 // keyname of IME Cancel button is Cancel. but Select(0xFF69) is only + // Tizen TV IME keyname defined by ISF, there is no X Server keycode. + // 0xFF69 is ISF keycode. + +#endif // #if BUILDFLAG(IS_TIZEN_TV) + #endif // VK_UNKNOWN #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WINDOWS_KEYBOARD_CODES_H_ diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h index a83ceac..4c3e9ef 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h @@ -111,6 +111,105 @@ static ui::KeyboardCode UIKeyCodeFromEflKey(const char* key) { {"XF86KbdBrightnessDown", ui::VKEY_KBD_BRIGHTNESS_DOWN}, {"XF86KbdBrightnessUp", ui::VKEY_KBD_BRIGHTNESS_UP}, +#if BUILDFLAG(IS_TIZEN_TV) + {"XF86Back", ui::VKEY_DTV_RETURN}, + {"XF86RaiseChannel", ui::VKEY_CHANNEL_UP}, + {"XF86LowerChannel", ui::VKEY_CHANNEL_DOWN}, + {"XF86AudioRewind", ui::VKEY_REWIND}, + {"XF86AudioPause", ui::VKEY_PAUSE}, + {"XF86AudioNext", ui::VKEY_FAST_FWD}, + {"XF86AudioRecord", ui::VKEY_RECORD}, {"XF86AudioPlay", ui::VKEY_PLAY}, + {"XF86AudioStop", ui::VKEY_STOP}, {"XF86Red", ui::VKEY_RED}, + {"XF86Green", ui::VKEY_GREEN}, {"XF86Yellow", ui::VKEY_YELLOW}, + {"XF86Blue", ui::VKEY_BLUE}, {"XF86Grey", ui::VKEY_GREY}, + {"XF86Brown", ui::VKEY_BROWN}, {"XF86Info", ui::VKEY_INFO}, + {"XF86Home", ui::VKEY_DTV_HOME}, {"XF86Display", ui::VKEY_SOURCE}, + {"XF86ChannelList", ui::VKEY_CH_LIST}, + {"XF86MBRRepeat", ui::VKEY_REPEAT}, + {"XF86PictureSize", ui::VKEY_ASPECT}, + {"XF86PictureMode", ui::VKEY_PMODE}, {"XF86Hdmi", ui::VKEY_HDMI}, + {"XF86UsbHub", ui::VKEY_USBHUB_SWITCH}, + {"XF86EManual", ui::VKEY_EMANUAL}, {"XF86SimpleMenu", ui::VKEY_TOOLS}, + {"XF86More", ui::VKEY_MORE}, {"XF86FactoryMode", ui::VKEY_FACTORY}, + {"XF86Sleep", ui::VKEY_SLEEP}, {"XF86TV", ui::VKEY_TV}, + {"XF86DTV", ui::VKEY_DTV}, {"XF86STBPower", ui::VKEY_STB_POWER}, + {"XF86PanelDown", ui::VKEY_PANEL_DOWN}, + {"XF86WWW", ui::VKEY_CONVERGENCE}, + {"XF86BTColorMecha", ui::VKEY_BT_COLOR_MECHA}, + {"XF86StillPicture", ui::VKEY_STILL_PICTURE}, + {"XF86BTPairing", ui::VKEY_BT_TRIGGER}, + {"XF86BTHotkey", ui::VKEY_BT_HOTVK}, + {"XF86BTDevice", ui::VKEY_BT_DEVICE}, + {"XF86BTContentsBar", ui::VKEY_BT_CONTENTSBAR}, + {"XF86Game", ui::VKEY_GAME}, {"XF86PIPChannelUp", ui::VKEY_PIP_CHUP}, + {"XF86PIPChannelDown", ui::VKEY_PIP_CHDOWN}, + {"XF86Antena", ui::VKEY_ANTENA}, + {"XF86PanelEnter", ui::VKEY_PANEL_ENTER}, + {"XF86MBRLink", ui::VKEY_LINK}, {"XF86PanelUp", ui::VKEY_PANEL_UP}, + {"XF86Game3D", ui::VKEY_ANGLE}, + {"XF86WheelLeftKey", ui::VKEY_WHEEL_LEFT}, + {"XF86WheelRightKey", ui::VKEY_WHEEL_RIGHT}, + {"XF86PanelExit", ui::VKEY_PANEL_EXIT}, {"XF86Exit", ui::VKEY_EXIT}, + {"XF86MBRTV", ui::VKEY_MBR_TV}, + {"XF86MBRSTBGuide", ui::VKEY_MBR_STB_GUIDE}, + {"XF86MBRBDPopup", ui::VKEY_MBR_BD_POPUP}, + {"XF86MBRBDDVDPower", ui::VKEY_MBR_BDDVD_POWER}, + {"XF86MBRSetupFailure", ui::VKEY_MBR_SETUP_FAILURE}, + {"XF86MBRSetup", ui::VKEY_MBR_SETUP}, + {"XF86MBRWatchTV", ui::VKEY_MBR_WATCH_TV}, + {"XF86PreviousChannel", ui::VKEY_PRECH}, + {"XF86Recommend", ui::VKEY_RECOMMEND_SEARCH_TOGGLE}, + {"XF86NumberPad", ui::VKEY_BT_NUMBER}, + {"XF86AspectRatio169", ui::VKEY_16_9}, {"XF86MTS", ui::VKEY_MTS}, + {"XF86SoundMode", ui::VKEY_SMODE}, {"XF863XSpeed", ui::VKEY_3SPEED}, + {"XF863D", ui::VKEY_3D}, {"XF86TTXMIX", ui::VKEY_TTX_MIX}, + {"XF86SRSSXT", ui::VKEY_SRSTSXT}, + {"XF86WIFIPairing", ui::VKEY_WIFI_PAIRING}, + {"XF86BTApps", ui::VKEY_BT_SAMSUNG_APPS}, + {"XF86EnergySaving", ui::VKEY_ESAVING}, + {"XF86MBRClear", ui::VKEY_CLEAR}, {"XF86TVSNS", ui::VKEY_TV_SNS}, + {"XF86DVR", ui::VKEY_DVR}, {"XF86Apps", ui::VKEY_APP_LIST}, + {"XF86Camera", ui::VKEY_CAMERA}, {"XF86Caption", ui::VKEY_CAPTION}, + {"XF86ZoomIn", ui::VKEY_ZOOM1}, {"XF86PanelPlus", ui::VKEY_PANEL_PLUS}, + {"XF86BTVoice", ui::VKEY_BT_VOICE}, {"XF86Search", ui::VKEY_SEARCH}, + {"XF86PanelMinus", ui::VKEY_PANEL_MINUS}, + {"XF86SoccerMode", ui::VKEY_SOCCER_MODE}, + {"XF86Amazon", ui::VKEY_FUNCTIONS_AMAZON}, + {"XF86AudioDescription", ui::VKEY_AD}, + {"XF86PreviousChapter", ui::VKEY_REWIND_}, + {"XF86NextChapter", ui::VKEY_FF_}, + {"XF86Netflix", ui::VKEY_FUNCTIONS_NETFLIX}, + {"XF86PIP", ui::VKEY_PIP_ONOFF}, + {"XF86MBRWatchMovie", ui::VKEY_MBR_WATCH_MOVIE}, + {"XF86MBRMenu", ui::VKEY_MBR_STBBD_MENU}, + {"XF86MBRConfirm", ui::VKEY_MBR_SETUP_CONFIRM}, + {"XF86FamilyHub", ui::VKEY_FAMILYHUB}, + {"XF86HDMICEC", ui::VKEY_ANYVIEW}, {"XF86LeftPage", ui::VKEY_PAGE_LEFT}, + {"XF86RightPage", ui::VKEY_PAGE_RIGHT}, + {"XF86PowerOff", ui::VKEY_POWER}, {"XF86SysMenu", ui::VKEY_DTV_MENU}, + {"XF86ChannelGuide", ui::VKEY_GUIDE}, + {"XF86ChannelAddDel", ui::VKEY_ADDDEL}, + {"XF86ChannelAutoTune", ui::VKEY_AUTO_PROGRAM}, + {"XF86FavoriteChannel", ui::VKEY_FAVCH}, + {"XF86DualView", ui::VKEY_BT_DUALVIEW}, + {"XF86Subtitle", ui::VKEY_SUB_TITLE}, + {"XF86SoftWakeup", ui::VKEY_SOFT_WAKE_UP}, + {"XF86PlayBack", ui::VKEY_PLAY_BACK}, {"XF86ExtraApp", ui::VKEY_EXTRA}, + {"XF86Color", ui::VKEY_COLOR}, + + {"XF86NoiseReduction", ui::VKEY_NOISE_REDUCTION}, + {"XF86Help", ui::VKEY_HELP}, + {"XF86HotelAppsGuest", ui::VKEY_HOTEL_APPS_GUEST}, + {"XF86HotelMovies", ui::VKEY_HOTEL_MOVIES}, + {"XF86HotelLanguage", ui::VKEY_HOTEL_LANGUAGE}, + {"XF86HotelTVGuide", ui::VKEY_HOTEL_TV_GUIDE}, {"XF86NR", ui::VKEY_NR}, + {"XF86HotelRoomControl", ui::VKEY_HOTEL_ROOM_CONTROL}, + {"XF86Alarm", ui::VKEY_ALARM}, + + // TV IME Keys + {"Select", ui::VKEY_RETURN}, {"Clear", ui::VKEY_DELETE}, +#endif + {"0", ui::VKEY_0}, {"1", ui::VKEY_1}, {"2", ui::VKEY_2}, {"3", ui::VKEY_3}, {"4", ui::VKEY_4}, {"5", ui::VKEY_5}, {"6", ui::VKEY_6}, {"7", ui::VKEY_7}, {"8", ui::VKEY_8}, diff --git a/ui/events/event.cc b/ui/events/event.cc index 2721ef0..21cafe7 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc @@ -825,6 +825,9 @@ KeyEvent::KeyEvent(const PlatformEvent& native_event, int event_flags) scan_code_(ScanCodeFromNative(native_event)), #endif // defined(USE_OZONE) code_(CodeFromNative(native_event)), +#if BUILDFLAG(IS_TIZEN) + key_(KeyFromNative(native_event)), +#endif // BUILDFLAG(IS_TIZEN) #if BUILDFLAG(IS_EFL) is_system_key(IsSystemKeyFromNative(native_event)), #endif diff --git a/ui/events/event_utils.h b/ui/events/event_utils.h index 0fa0079..ca4e631 100644 --- a/ui/events/event_utils.h +++ b/ui/events/event_utils.h @@ -116,6 +116,11 @@ KeyboardCodeFromNative(const PlatformEvent& native_event); // keyboard) from a native event. EVENTS_EXPORT DomCode CodeFromNative(const PlatformEvent& native_event); +#if BUILDFLAG(IS_TIZEN) +// Returns the DOM KeyboardEvent key (layout meaning) from a native event. +EVENTS_EXPORT DomKey KeyFromNative(const PlatformEvent& native_event); +#endif + #if BUILDFLAG(IS_EFL) // Returns the |is_system_key| value from a native event. EVENTS_EXPORT bool IsSystemKeyFromNative(const PlatformEvent& native_event); diff --git a/ui/events/events_default.cc b/ui/events/events_default.cc index be759cb..c434740 100644 --- a/ui/events/events_default.cc +++ b/ui/events/events_default.cc @@ -83,6 +83,14 @@ DomCode CodeFromNative(const PlatformEvent& native_event) { return event->code(); } +#if BUILDFLAG(IS_TIZEN) +DomKey KeyFromNative(const PlatformEvent& native_event) { + const ui::KeyEvent* event = static_cast(native_event); + DCHECK(event->IsKeyEvent()); + return event->GetDomKey(); +} +#endif + #if BUILDFLAG(IS_EFL) bool IsSystemKeyFromNative(const PlatformEvent& native_event) { const ui::KeyEvent* event = static_cast(native_event); diff --git a/ui/events/keycodes/dom/dom_key_data.inc b/ui/events/keycodes/dom/dom_key_data.inc index 286fc32..218bd58 100644 --- a/ui/events/keycodes/dom/dom_key_data.inc +++ b/ui/events/keycodes/dom/dom_key_data.inc @@ -536,4 +536,131 @@ DOM_KEY_MAP_DECLARATION { DOM_KEY_MAP("VideoModeNext", VIDEO_MODE_NEXT, 0x0D4C), DOM_KEY_MAP("Wink", WINK, 0x0D4D), DOM_KEY_MAP("ZoomToggle", ZOOM_TOGGLE, 0x0D4E), + +#if BUILDFLAG(IS_TIZEN_TV) + // ================================================================== + // EFL Key + // http://mosaic.sec.samsung.net/club/club.menu.bbs.read.screen?page_num=1&p_club_id=466&p_menu_id=107&p_group_id=80&search_field=&search_query=&search_category=&message_id=4764929 + // ================================================================== + + // Key Enum Value + DOM_KEY_MAP("XF86Back", XF86Back, 0x2719), + DOM_KEY_MAP("XF86RaiseChannel", XF86RaiseChannel, 0x01AB), + DOM_KEY_MAP("XF86LowerChannel", XF86LowerChannel, 0x01AC), + DOM_KEY_MAP("XF86AudioRewind", XF86AudioRewind, 0x019C), + DOM_KEY_MAP("XF86AudioPause", XF86AudioPause, 0x0013), + DOM_KEY_MAP("XF86AudioNext", XF86AudioNext, 0x01A1), + DOM_KEY_MAP("XF86AudioRecord", XF86AudioRecord, 0x01A0), + DOM_KEY_MAP("XF86AudioPlay", XF86AudioPlay, 0x00FA), + DOM_KEY_MAP("XF86AudioStop", XF86AudioStop, 0x019D), + DOM_KEY_MAP("XF86Red", XF86Red, 0x0193), + DOM_KEY_MAP("XF86Green", XF86Green, 0x0194), + DOM_KEY_MAP("XF86Yellow", XF86Yellow, 0x0195), + DOM_KEY_MAP("XF86Blue", XF86Blue, 0x0196), + DOM_KEY_MAP("XF86Info", XF86Info, 0x01C9), + DOM_KEY_MAP("XF86Home", XF86Home, 0x2757), + DOM_KEY_MAP("XF86Display", XF86Display, 0x2758), + DOM_KEY_MAP("XF86ChannelList", XF86ChannelList, 0x2759), + DOM_KEY_MAP("XF86MBRRepeat", XF86MBRRepeat, 0x2799), + DOM_KEY_MAP("XF86PictureSize", XF86PictureSize, 0x279C), + DOM_KEY_MAP("XF86PictureMode", XF86PictureMode, 0x279D), + DOM_KEY_MAP("XF86Hdmi", XF86Hdmi, 0x279F), + DOM_KEY_MAP("XF86UsbHub", XF86UsbHub, 0x27A0), + DOM_KEY_MAP("XF86EManual", XF86EManual, 0x27A2), + DOM_KEY_MAP("XF86SimpleMenu", XF86SimpleMenu, 0x2797), + DOM_KEY_MAP("XF86More", XF86More, 0x27A4), + DOM_KEY_MAP("XF86FactoryMode", XF86FactoryMode, 0x27A5), + DOM_KEY_MAP("XF86Sleep", XF86Sleep, 0x27A6), + DOM_KEY_MAP("XF86TV", XF86TV, 0x27A9), + DOM_KEY_MAP("XF86DTV", XF86DTV, 0x27AA), + DOM_KEY_MAP("XF86STBPower", XF86STBPower, 0x27AB), + DOM_KEY_MAP("XF86PanelDown", XF86PanelDown, 0x27AD), + DOM_KEY_MAP("XF86WWW", XF86WWW, 0x27AE), + DOM_KEY_MAP("XF86BTColorMecha", XF86BTColorMecha, 0x27AF), + DOM_KEY_MAP("XF86StillPicture", XF86StillPicture, 0x27B0), + DOM_KEY_MAP("XF86BTPairing", XF86BTPairing, 0x27B1), + DOM_KEY_MAP("XF86BTHotkey", XF86BTHotkey, 0x27B2), + DOM_KEY_MAP("XF86BTDevice", XF86BTDevice, 0x27B3), + DOM_KEY_MAP("XF86BTContentsBar", XF86BTContentsBar, 0x27B4), + DOM_KEY_MAP("XF86Game", XF86Game, 0x27B5), + DOM_KEY_MAP("XF86PIPChannelUp", XF86PIPChannelUp, 0x27B7), + DOM_KEY_MAP("XF86PIPChannelDown", XF86PIPChannelDown, 0x27B8), + DOM_KEY_MAP("XF86Antena", XF86Antena, 0x27B9), + DOM_KEY_MAP("XF86PanelEnter", XF86PanelEnter, 0x27BB), + DOM_KEY_MAP("XF86MBRLink", XF86MBRLink, 0x27BC), + DOM_KEY_MAP("XF86PanelUp", XF86PanelUp, 0x27BD), + DOM_KEY_MAP("XF86Game3D", XF86Game3D, 0x27C1), + DOM_KEY_MAP("XF86WheelLeftKey", XF86WheelLeftKey, 0x27C2), + DOM_KEY_MAP("XF86WheelRightKey", XF86WheelRightKey, 0x27C3), + DOM_KEY_MAP("XF86PanelExit", XF86PanelExit, 0x27C5), + DOM_KEY_MAP("XF86Exit", XF86Exit, 0x27C6), + DOM_KEY_MAP("XF86MBRTV", XF86MBRTV, 0x27C7), + DOM_KEY_MAP("XF86MBRSTBGuide", XF86MBRSTBGuide, 0x27C8), + DOM_KEY_MAP("XF86MBRBDPopup", XF86MBRBDPopup, 0x27C9), + DOM_KEY_MAP("XF86MBRBDDVDPower", XF86MBRBDDVDPower, 0x27CA), + DOM_KEY_MAP("XF86MBRSetupFailure", XF86MBRSetupFailure, 0x27CB), + DOM_KEY_MAP("XF86MBRSetup", XF86MBRSetup, 0x27CC), + DOM_KEY_MAP("XF86MBRWatchTV", XF86MBRWatchTV, 0x27CD), + DOM_KEY_MAP("XF86PreviousChannel", XF86PreviousChannel, 0x27CE), + DOM_KEY_MAP("XF86Recommend", XF86Recommend, 0x27D0), + DOM_KEY_MAP("XF86NumberPad", XF86NumberPad, 0x27D1), + DOM_KEY_MAP("XF86AspectRatio169", XF86AspectRatio169, 0x27D2), + DOM_KEY_MAP("XF86MTS", XF86MTS, 0x27D3), + DOM_KEY_MAP("XF86SoundMode", XF86SoundMode, 0x27D5), + DOM_KEY_MAP("XF863XSpeed", XF863XSpeed, 0x27D6), + DOM_KEY_MAP("XF863D", XF863D, 0x27D7), + DOM_KEY_MAP("XF86TTXMIX", XF86TTXMIX, 0x27D8), + DOM_KEY_MAP("XF86SRSSXT", XF86SRSSXT, 0x27D9), + DOM_KEY_MAP("XF86WIFIPairing", XF86WIFIPairing, 0x27DA), + DOM_KEY_MAP("XF86BTApps", XF86BTApps, 0x27E3), + DOM_KEY_MAP("XF86EnergySaving", XF86EnergySaving, 0x27E5), + DOM_KEY_MAP("XF86MBRClear", XF86MBRClear, 0x000C), + DOM_KEY_MAP("XF86TVSNS", XF86TVSNS, 0x27E9), + DOM_KEY_MAP("XF86DVR", XF86DVR, 0x27EA), + DOM_KEY_MAP("XF86Apps", XF86Apps, 0x27EB), + DOM_KEY_MAP("XF86Camera", XF86Camera, 0x27EC), + DOM_KEY_MAP("XF86Caption", XF86Caption, 0x27ED), + DOM_KEY_MAP("XF86ZoomIn", XF86ZoomIn, 0x27EE), + DOM_KEY_MAP("XF86PanelPlus", XF86PanelPlus, 0x27EF), + DOM_KEY_MAP("XF86BTVoice", XF86BTVoice, 0x27F0), + DOM_KEY_MAP("XF86Search", XF86Search, 0x27F1), + DOM_KEY_MAP("XF86PanelMinus", XF86PanelMinus, 0x27F3), + DOM_KEY_MAP("XF86SoccerMode", XF86SoccerMode, 0x27F4), + DOM_KEY_MAP("XF86Amazon", XF86Amazon, 0x27F5), + DOM_KEY_MAP("XF86AudioDescription", XF86AudioDescription, 0x27F6), + DOM_KEY_MAP("XF86PreviousChapter", XF86PreviousChapter, 0x27F8), + DOM_KEY_MAP("XF86NextChapter", XF86NextChapter, 0x27F9), + DOM_KEY_MAP("XF86Netflix", XF86Netflix, 0x27FA), + DOM_KEY_MAP("XF86PIP", XF86PIP, 0x27FB), + DOM_KEY_MAP("XF86MBRWatchMovie", XF86MBRWatchMovie, 0x27FC), + DOM_KEY_MAP("XF86MBRMenu", XF86MBRMenu, 0x27FD), + DOM_KEY_MAP("XF86MBRConfirm", XF86MBRConfirm, 0x27FE), + DOM_KEY_MAP("XF86FamilyHub", XF86FamilyHub, 0x27FF), + DOM_KEY_MAP("XF86HDMICEC", XF86HDMICEC, 0x2800), + DOM_KEY_MAP("XF86LeftPage", XF86LeftPage, 0x2809), + DOM_KEY_MAP("XF86RightPage", XF86RightPage, 0x280A), + DOM_KEY_MAP("XF86PowerOff", XF86PowerOff, 0x0199), + DOM_KEY_MAP("XF86SysMenu", XF86SysMenu, 0x2795), + DOM_KEY_MAP("XF86ChannelGuide", XF86ChannelGuide, 0x01CA), + DOM_KEY_MAP("XF86ChannelAddDel", XF86ChannelAddDel, 0x01AD), + DOM_KEY_MAP("XF86ChannelAutoTune", XF86ChannelAutoTune, 0x01B9), + DOM_KEY_MAP("XF86FavoriteChannel", XF86FavoriteChannel, 0x01B1), + DOM_KEY_MAP("XF86DualView", XF86DualView, 0x01BB), + DOM_KEY_MAP("XF86Subtitle", XF86Subtitle, 0x01CC), + DOM_KEY_MAP("XF86SoftWakeup", XF86SoftWakeup, 0x2804), + DOM_KEY_MAP("XF86PlayBack", XF86PlayBack, 0x280C), + DOM_KEY_MAP("XF86ExtraApp", XF86ExtraApp, 0x280D), + DOM_KEY_MAP("XF86Color", XF86Color, 0x2891), + DOM_KEY_MAP("XF86Alarm", XF86Alarm, 0x28B2), + DOM_KEY_MAP("XF86HotelMovies", XF86HotelMovies, 0x28FE), + DOM_KEY_MAP("XF86HotelLanguage", XF86HotelLanguage, 0x28FF), + DOM_KEY_MAP("XF86HotelTVGuide", XF86HotelTVGuide, 0x2900), + DOM_KEY_MAP("XF86HotelAppsGuest", XF86HotelAppsGuest, 0x2901), + DOM_KEY_MAP("XF86NoiseReduction", XF86NoiseReduction, 0x2917), + DOM_KEY_MAP("XF86Help", XF86Help, 0x2918), + DOM_KEY_MAP("XF86NR", XF86NR, 0x2919), + DOM_KEY_MAP("XF86HotelRoomControl", XF86HotelRoomControl, 0x291A), + DOM_KEY_MAP("Select", Select, 0x000D), + DOM_KEY_MAP("Clear", Clear, 0x002E), +#endif }; diff --git a/ui/events/keycodes/keyboard_codes_posix.h b/ui/events/keycodes/keyboard_codes_posix.h index e8f04f4..56f2b9a 100644 --- a/ui/events/keycodes/keyboard_codes_posix.h +++ b/ui/events/keycodes/keyboard_codes_posix.h @@ -42,7 +42,9 @@ enum KeyboardCode { VKEY_BACK = 0x08, VKEY_TAB = 0x09, VKEY_BACKTAB = 0x0A, +#if !BUILDFLAG(IS_TIZEN_TV) VKEY_CLEAR = 0x0C, +#endif VKEY_RETURN = 0x0D, VKEY_SHIFT = 0x10, VKEY_CONTROL = 0x11, @@ -76,7 +78,9 @@ enum KeyboardCode { VKEY_SNAPSHOT = 0x2C, // Print Screen / SysRq VKEY_INSERT = 0x2D, VKEY_DELETE = 0x2E, +#if !BUILDFLAG(IS_TIZEN_TV) VKEY_HELP = 0x2F, +#endif VKEY_0 = 0x30, VKEY_1 = 0x31, VKEY_2 = 0x32, @@ -117,7 +121,9 @@ enum KeyboardCode { VKEY_COMMAND = VKEY_LWIN, // Provide the Mac name for convenience. VKEY_RWIN = 0x5C, VKEY_APPS = 0x5D, +#if !BUILDFLAG(IS_TIZEN_TV) VKEY_SLEEP = 0x5F, +#endif VKEY_NUMPAD0 = 0x60, VKEY_NUMPAD1 = 0x61, VKEY_NUMPAD2 = 0x62, @@ -173,9 +179,11 @@ enum KeyboardCode { VKEY_BROWSER_SEARCH = 0xAA, VKEY_BROWSER_FAVORITES = 0xAB, VKEY_BROWSER_HOME = 0xAC, +#if !BUILDFLAG(IS_TIZEN_TV) VKEY_VOLUME_MUTE = 0xAD, VKEY_VOLUME_DOWN = 0xAE, VKEY_VOLUME_UP = 0xAF, +#endif VKEY_MEDIA_NEXT_TRACK = 0xB0, VKEY_MEDIA_PREV_TRACK = 0xB1, VKEY_MEDIA_STOP = 0xB2, @@ -211,7 +219,9 @@ enum KeyboardCode { VKEY_CRSEL = 0xF7, VKEY_EXSEL = 0xF8, VKEY_EREOF = 0xF9, +#if !BUILDFLAG(IS_TIZEN_TV) VKEY_PLAY = 0xFA, +#endif VKEY_ZOOM = 0xFB, VKEY_NONAME = 0xFC, VKEY_PA1 = 0xFD, @@ -221,7 +231,9 @@ enum KeyboardCode { // POSIX specific VKEYs. Note that as of Windows SDK 7.1, 0x97-9F, 0xD8-DA, // and 0xE8 are unassigned. VKEY_WLAN = 0x97, +#if !BUILDFLAG(IS_TIZEN_TV) VKEY_POWER = 0x98, +#endif VKEY_ASSISTANT = 0x99, VKEY_SETTINGS = 0x9A, VKEY_PRIVACY_SCREEN_TOGGLE = 0x9B, @@ -257,10 +269,157 @@ enum KeyboardCode { VKEY_ALL_APPLICATIONS = 0xEF, #if BUILDFLAG(IS_TIZEN_TV) + // TV keys on remote controller. + // Virtual keys defined in http://www.atsc.org/cms/standards/a100/a_100_2.pdf + // Same volume virtual keys are already defined in Windows virtual keys but we + // overlap with the keys defined in DTV. + // VKEY_PLAY + // VKEY_VOLUME_UP + // VKEY_VOLUME_DOWN + // VKEY_VOLUME_MUTE + + VKEY_RED = 0x193, + VKEY_GREEN = 0x194, + VKEY_YELLOW = 0x195, + VKEY_BLUE = 0x196, + VKEY_GREY = 0x197, + VKEY_BROWN = 0x198, + + VKEY_DTV_RETURN = 0x2719, + VKEY_DTV_HOME = 0x2757, + VKEY_SOURCE = 0x2758, + VKEY_CH_LIST = 0x2759, + + VKEY_POWER = 0x199, + VKEY_DTV_MENU = 0x2795, + VKEY_GUIDE = 0x1CA, + VKEY_ADDDEL = 0x1AD, + VKEY_AUTO_PROGRAM = 0x1B9, + VKEY_FAVCH = 0x1B1, + VKEY_BT_DUALVIEW = 0x1BB, + VKEY_SUB_TITLE = 0x1CC, + + VKEY_REWIND = 0x19C, + VKEY_STOP = 0x19D, + VKEY_PLAY = 0x19F, + VKEY_RECORD = 0x1A0, + VKEY_FAST_FWD = 0x1A1, + + VKEY_CHANNEL_UP = 0x1AB, + VKEY_CHANNEL_DOWN = 0x1AC, + + VKEY_VOLUME_UP = 0x1BF, + VKEY_VOLUME_DOWN = 0x1C0, + VKEY_VOLUME_MUTE = 0x1C1, + + VKEY_INFO = 0x1C9, + + VKEY_REPEAT = 0x2799, + VKEY_ASPECT = 0x279C, + VKEY_PMODE = 0x279D, + VKEY_HDMI = 0x279F, + VKEY_USBHUB_SWITCH = 0x27A0, + VKEY_EMANUAL = 0x27A2, + VKEY_TOOLS = 0x2797, + VKEY_MORE = 0x27A4, + VKEY_FACTORY = 0x27A5, + VKEY_SLEEP = 0x27A6, + VKEY_TV = 0x27A9, + VKEY_DTV = 0x27AA, + VKEY_STB_POWER = 0x27AB, + VKEY_PANEL_DOWN = 0x27AD, + VKEY_CONVERGENCE = 0x27AE, + VKEY_BT_COLOR_MECHA = 0x27AF, + VKEY_STILL_PICTURE = 0x27B0, + VKEY_BT_TRIGGER = 0x27B1, + VKEY_BT_HOTVK = 0x27B2, + VKEY_BT_DEVICE = 0x27B3, + VKEY_BT_CONTENTSBAR = 0x27B4, + VKEY_GAME = 0x27B5, + VKEY_PIP_CHUP = 0x27B7, + VKEY_PIP_CHDOWN = 0x27B8, + VKEY_ANTENA = 0x27B9, + VKEY_PANEL_ENTER = 0x27BB, + VKEY_LINK = 0x27BC, + VKEY_PANEL_UP = 0x27BD, + + VKEY_ANGLE = 0x27C1, + VKEY_WHEEL_LEFT = 0x27C2, + VKEY_WHEEL_RIGHT = 0x27C3, + VKEY_CONTENTS = 0x2757, + VKEY_PANEL_EXIT = 0x27C5, + VKEY_EXIT = 0x27C6, + + VKEY_MBR_TV = 0x27C7, + VKEY_MBR_STB_GUIDE = 0x27C8, + VKEY_MBR_BD_POPUP = 0x27C9, + VKEY_MBR_BDDVD_POWER = 0x27CA, + VKEY_MBR_SETUP_FAILURE = 0x27CB, + VKEY_MBR_SETUP = 0x27CC, + VKEY_MBR_WATCH_TV = 0x27CD, + + VKEY_PRECH = 0x27CE, + VKEY_RECOMMEND_SEARCH_TOGGLE = 0x27D0, + VKEY_BT_NUMBER = 0x27D1, + VKEY_16_9 = 0x27D2, + VKEY_MTS = 0x27D3, + VKEY_SMODE = 0x27D5, + VKEY_3SPEED = 0x27D6, + VKEY_3D = 0x27D7, + VKEY_TTX_MIX = 0x27D8, + VKEY_SRSTSXT = 0x27D9, + VKEY_WIFI_PAIRING = 0x27DA, + VKEY_BT_SAMSUNG_APPS = 0x27E3, + VKEY_W_LINK = 0x2757, + VKEY_ESAVING = 0x27E5, + VKEY_CLEAR = 0x27E6, + VKEY_TV_SNS = 0x27E9, + VKEY_DVR = 0x27EA, + VKEY_APP_LIST = 0x27EB, + VKEY_CAMERA = 0x27EC, + VKEY_CAPTION = 0x27ED, + VKEY_ZOOM1 = 0x27EE, + VKEY_PANEL_PLUS = 0x27EF, + VKEY_BT_VOICE = 0x27F0, + VKEY_SEARCH = 0x27F1, + VKEY_PANEL_MINUS = 0x27F3, + VKEY_SOCCER_MODE = 0x27F4, + VKEY_FUNCTIONS_AMAZON = 0x27F5, + VKEY_AD = 0x27F6, + VKEY_REWIND_ = 0x27F8, + VKEY_FF_ = 0x27F9, + VKEY_FUNCTIONS_NETFLIX = 0x27FA, + VKEY_PIP_ONOFF = 0x27FB, + VKEY_MBR_WATCH_MOVIE = 0x27FC, + VKEY_MBR_STBBD_MENU = 0x27FD, + VKEY_MBR_SETUP_CONFIRM = 0x27FE, + VKEY_FAMILYHUB = 0x27FF, + VKEY_ANYVIEW = 0x2800, + + VKEY_PAGE_LEFT = 0x2809, + VKEY_PAGE_RIGHT = 0x280A, + + VKEY_SOFT_WAKE_UP = 0x2804, + VKEY_PANEL_ON = 0x280B, + VKEY_PLAY_BACK = 0x280C, + VKEY_EXTRA = 0x280D, + VKEY_COLOR = 0x2891, + + VKEY_ALARM = 0x28B2, + VKEY_HOTEL_MOVIES = 0x28FE, + VKEY_HOTEL_LANGUAGE = 0x28FF, + VKEY_HOTEL_TV_GUIDE = 0x2900, + VKEY_HOTEL_APPS_GUEST = 0x2901, + VKEY_NOISE_REDUCTION = 0x2917, + VKEY_HELP = 0x2918, + VKEY_NR = 0x2919, + VKEY_HOTEL_ROOM_CONTROL = 0x291A, + // TV IME "Select" key, no X Server keycode, 0xFF60 ISF code. VKEY_IME_DONE = 0xFF60, // TV IME "Cancel" key, no X Server keycode, 0xFF69 ISF code. VKEY_IME_CANCEL = 0xFF69, + #endif }; -- 2.7.4 From 008476a8941389bec8bdeb1f907d3d4da501b042 Mon Sep 17 00:00:00 2001 From: Bakka Uday Kiran Date: Wed, 25 Jan 2023 01:20:55 +0530 Subject: [PATCH 10/16] [M108 Migration] Bring up ttrace Add '--ttrace' build option Import ttrace package Define USE_TTRACE macro Add use_ttrace GN variable Add helper macro functions for TTRACE Add TTRACE backend under TRACE_EVENT macro Enable TTRACE except chrome trace log for TV product by default. Reference: https://review.tizen.org/gerrit/c/277764 Change-Id: I40e2ec67c3619827a8b7de9c7e3bbcc22722d8a4 Signed-off-by: Bakka Uday Kiran --- base/trace_event/trace_event.h | 29 +++++++++++++++++ packaging/chromium-efl.spec | 4 +++ third_party/skia/src/core/SkTraceEvent.h | 31 +++++++++++++++++- tizen_src/build/BUILD.gn | 9 ++++- tizen_src/build/common.sh | 5 +++ tizen_src/build/config/BUILD.gn | 14 ++++++-- tizen_src/build/config/tizen_features.gni | 12 +++++++ tizen_src/chromium_impl/base/BUILD.gn | 11 +++++++ tizen_src/chromium_impl/base/base_efl.gni | 8 +++++ .../base/trace_event/trace_event_ttrace.cc | 37 +++++++++++++++++++++ tizen_src/chromium_impl/base/trace_event/ttrace.h | 38 ++++++++++++++++++++++ tizen_src/ewk/efl_integration/public/ewk_view.cc | 2 ++ .../efl_integration/web_contents_delegate_efl.cc | 3 +- v8/BUILD.gn | 4 +++ v8/src/tracing/trace-event.h | 32 ++++++++++++++++-- 15 files changed, 229 insertions(+), 10 deletions(-) create mode 100644 tizen_src/chromium_impl/base/BUILD.gn create mode 100644 tizen_src/chromium_impl/base/trace_event/trace_event_ttrace.cc create mode 100644 tizen_src/chromium_impl/base/trace_event/ttrace.h diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index 02f96b1..2283ae7c 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h @@ -29,6 +29,10 @@ #include "base/trace_event/traced_value_support.h" #include "base/tracing_buildflags.h" +#if BUILDFLAG(IS_EFL) +#include "base/trace_event/ttrace.h" +#endif + #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) // By default, const char* argument values are assumed to have long-lived scope @@ -253,9 +257,16 @@ // Implementation detail: internal macro to create static category and add begin // event if the category is enabled. Also adds the end event when the scope // ends. +#if defined(USE_TTRACE_TRACE_EVENT_WEBCORE) +#define TTRACE_TRACE_EVENT(tracer, category_group, name) \ + INTERNAL_TRACE_EVENT_UID(tracer).TTraceBegin(category_group, name); +#else +#define TTRACE_TRACE_EVENT(tracer, category_group, name) +#endif #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ + TTRACE_TRACE_EVENT(tracer, category_group, name) \ if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ base::trace_event::TraceEventHandle INTERNAL_TRACE_EVENT_UID(h) = \ trace_event_internal::AddTraceEvent( \ @@ -712,9 +723,17 @@ static void AddMetadataEvent(const unsigned char* category_group_enabled, // Used by TRACE_EVENTx macros. Do not use directly. class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { public: +#if defined(USE_TTRACE_TRACE_EVENT_WEBCORE) + ScopedTracer() : use_ttrace_(false) {} +#else ScopedTracer() = default; +#endif ~ScopedTracer() { +#if defined(USE_TTRACE_TRACE_EVENT_WEBCORE) + if (use_ttrace_) + TTRACE_WEB_TRACE_EVENT_END(); +#endif if (category_group_enabled_ && *category_group_enabled_) { TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, event_handle_); @@ -729,6 +748,12 @@ class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { event_handle_ = event_handle; } +#if defined(USE_TTRACE_TRACE_EVENT_WEBCORE) + void TTraceBegin(const char* category_group, const char* name) { + use_ttrace_ = TTRACE_WEB_TRACE_EVENT_BEGIN(category_group, name); + } +#endif + private: // NOTE: Only initialize the first member to reduce generated code size, // since there is no point in initializing the other members if Initialize() @@ -736,6 +761,10 @@ class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { const unsigned char* category_group_enabled_ = nullptr; const char* name_; base::trace_event::TraceEventHandle event_handle_; + +#if defined(USE_TTRACE_TRACE_EVENT_WEBCORE) + bool use_ttrace_; +#endif }; // Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly. diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index baa95b3..d5b0dac 100644 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -107,6 +107,7 @@ BuildRequires: pkgconfig(scim) BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(stt) +BuildRequires: pkgconfig(ttrace) BuildRequires: pkgconfig(tts) BuildRequires: pkgconfig(ui-gadget-1) BuildRequires: pkgconfig(vconf) @@ -308,6 +309,9 @@ fi %else "build_chrome=false" \ %endif +%if "%{?_ttrace}" == "1" + "use_ttrace=true" \ +%endif %endif # _skip_gn ninja %{_smp_mflags} -C "%{OUTPUT_FOLDER}" \ diff --git a/third_party/skia/src/core/SkTraceEvent.h b/third_party/skia/src/core/SkTraceEvent.h index c1881e3..273a194 100644 --- a/third_party/skia/src/core/SkTraceEvent.h +++ b/third_party/skia/src/core/SkTraceEvent.h @@ -10,9 +10,14 @@ #ifndef SkTraceEvent_DEFINED #define SkTraceEvent_DEFINED +#include +#include "build/build_config.h" #include "include/utils/SkEventTracer.h" #include "src/core/SkTraceEventCommon.h" -#include + +#if BUILDFLAG(IS_EFL) +#include "base/trace_event/ttrace.h" +#endif //////////////////////////////////////////////////////////////////////////////// // Implementation specific tracing API definitions. @@ -149,9 +154,16 @@ // Implementation detail: internal macro to create static category and add begin // event if the category is enabled. Also adds the end event when the scope // ends. +#if defined(USE_TTRACE_TRACE_EVENT_SKIA) +#define TTRACE_TRACE_EVENT(tracer, category_group, name) \ + INTERNAL_TRACE_EVENT_UID(tracer).TTraceBegin(category_group, name); +#else +#define TTRACE_TRACE_EVENT(tracer, category_group, name) +#endif #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ skia::tracing_internals::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ + TTRACE_TRACE_EVENT(tracer, category_group, name) \ do { \ if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ SkEventTracer::Handle h = skia::tracing_internals::AddTraceEvent( \ @@ -334,9 +346,17 @@ AddTraceEvent( class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { public: // Note: members of data_ intentionally left uninitialized. See Initialize. +#if defined(USE_TTRACE_TRACE_EVENT_SKIA) + ScopedTracer() : p_data_(NULL), use_ttrace_(false) {} +#else ScopedTracer() : p_data_(nullptr) {} +#endif ~ScopedTracer() { +#if defined(USE_TTRACE_TRACE_EVENT_SKIA) + if (use_ttrace_) + TTRACE_WEB_TRACE_EVENT_END(); +#endif if (p_data_ && *data_.category_group_enabled) TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( data_.category_group_enabled, data_.name, data_.event_handle); @@ -351,6 +371,12 @@ class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { p_data_ = &data_; } +#if defined(USE_TTRACE_TRACE_EVENT_SKIA) + void TTraceBegin(const char* category_group, const char* name) { + use_ttrace_ = TTRACE_WEB_TRACE_EVENT_BEGIN(category_group, name); + } +#endif + private: ScopedTracer(const ScopedTracer&) = delete; ScopedTracer& operator=(const ScopedTracer&) = delete; @@ -367,6 +393,9 @@ class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { }; Data* p_data_; Data data_; +#if defined(USE_TTRACE_TRACE_EVENT_SKIA) + bool use_ttrace_; +#endif }; } // namespace tracing_internals diff --git a/tizen_src/build/BUILD.gn b/tizen_src/build/BUILD.gn index ce7e0ba..bee9081 100644 --- a/tizen_src/build/BUILD.gn +++ b/tizen_src/build/BUILD.gn @@ -2,8 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//tizen_src/build/config/tizen_features.gni") import("//tizen_src/build/config/linux/pkg_config.gni") +import("//tizen_src/build/config/tizen_features.gni") config("evas") { ldflags = [ "-levas" ] @@ -179,6 +179,13 @@ config("ui-gadget-public") { } } +tizen_pkg_config("libttrace") { + packages = [] + if (is_tizen) { + packages = [ "ttrace" ] + } +} + config("capi-appfw-application") { if (is_tizen) { ldflags = [ "-lcapi-appfw-application" ] diff --git a/tizen_src/build/common.sh b/tizen_src/build/common.sh index deca03d..a8ebf16 100755 --- a/tizen_src/build/common.sh +++ b/tizen_src/build/common.sh @@ -242,6 +242,11 @@ function setupAndExecuteTargetBuild() { --skip-gn) ARGS+=(--define "_skip_gn 1") ;; + --ttrace) + ARGS[$count]=--define + count=$(( $count + 1 )) + ARGS[$count]="_ttrace 1" + ;; --component-build) ARGS+=(--define "component_build 1") ;; diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index 3b4e9c1..eb89768 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -49,12 +49,20 @@ config("tizen_feature_flags") { defines += [ "WAYLAND_BRINGUP" ] } if (tizen_product_tv) { - defines += [ - "OS_TIZEN_TV_PRODUCT", - ] + defines += [ "OS_TIZEN_TV_PRODUCT" ] } if (tizen_multimedia) { defines += [ "TIZEN_MULTIMEDIA" ] } + if (use_ttrace) { + defines += [ "USE_TTRACE" ] + if (use_ttrace_chrome_trace) { + defines += [ + "USE_TTRACE_TRACE_EVENT_SKIA", + "USE_TTRACE_TRACE_EVENT_V8", + "USE_TTRACE_TRACE_EVENT_WEBCORE", + ] + } + } } } diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index 5e1ec9a..de32d58 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -22,6 +22,9 @@ declare_args() { use_cairo = false use_pango = false + use_ttrace = false + use_ttrace_chrome_trace = false + werror = false tizen_clang_base_path = "//tizen_src/buildtools/llvm" @@ -49,6 +52,15 @@ declare_args() { tizen_web_speech_recognition = false } +if (use_ttrace) { + use_ttrace_chrome_trace = true +} + +# Enable ttrace except chrome trace log for TV profile by default +if (tizen_product_tv) { + use_ttrace = true +} + if (is_tizen && tizen_multimedia_support) { tizen_multimedia_eme_support = true } else { diff --git a/tizen_src/chromium_impl/base/BUILD.gn b/tizen_src/chromium_impl/base/BUILD.gn new file mode 100644 index 0000000..0864461 --- /dev/null +++ b/tizen_src/chromium_impl/base/BUILD.gn @@ -0,0 +1,11 @@ +# Copyright (c) 2021 samsung electronics. all rights reserved. +# use of this source code is governed by a bsd-style license that can be +# found in the license file. + +static_library("trace_event_ttrace") { + configs += [ "//tizen_src/build:libttrace" ] + sources = [ + "//tizen_src/chromium_impl/base/trace_event/trace_event_ttrace.cc", + "//tizen_src/chromium_impl/base/trace_event/ttrace.h", + ] +} diff --git a/tizen_src/chromium_impl/base/base_efl.gni b/tizen_src/chromium_impl/base/base_efl.gni index 61a9e08..83210b2 100644 --- a/tizen_src/chromium_impl/base/base_efl.gni +++ b/tizen_src/chromium_impl/base/base_efl.gni @@ -3,6 +3,13 @@ # found in the LICENSE file. import("//build/config/ui.gni") +import("//tizen_src/build/config/tizen_features.gni") + +external_base_public_deps = [] +if (use_ttrace) { + external_base_public_deps += + [ "//tizen_src/chromium_impl/base:trace_event_ttrace" ] +} external_base_configs = [ "//tizen_src/build:ecore", @@ -13,4 +20,5 @@ external_base_sources = [ "//tizen_src/chromium_impl/base/message_loop/message_pump_ecore.h", "//tizen_src/chromium_impl/base/message_loop/message_pump_for_ui_efl.cc", "//tizen_src/chromium_impl/base/message_loop/message_pump_for_ui_efl.h", + "//tizen_src/chromium_impl/base/trace_event/ttrace.h", ] diff --git a/tizen_src/chromium_impl/base/trace_event/trace_event_ttrace.cc b/tizen_src/chromium_impl/base/trace_event/trace_event_ttrace.cc new file mode 100644 index 0000000..0802abd --- /dev/null +++ b/tizen_src/chromium_impl/base/trace_event/trace_event_ttrace.cc @@ -0,0 +1,37 @@ +// Copyright 2021 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ttrace.h" + +#if defined(USE_TTRACE) +#include +#include + +bool TraceEventTTraceBegin(uint64_t tag, + const char* category_group, + const char* name) { + bool result = false; + std::string tokens[] = {"!disabled", "!debug", "blink", "cc", "gpu", + "media", "sandbox_ipc", "skia", "v8"}; + for (int i = 0; i < 9; i++) { + const char* category_group_token = tokens[i].c_str(); + if (category_group_token[0] == '!') { + category_group_token++; + if ((*category_group_token == '*') || + strstr(category_group, category_group_token)) + return false; + } else { + if ((*category_group_token == '*') || + strstr(category_group, category_group_token)) { + result = true; + break; + } + } + } + + if (result) + traceBegin(tag, "[%s]%s", category_group, name); + return result; +} +#endif diff --git a/tizen_src/chromium_impl/base/trace_event/ttrace.h b/tizen_src/chromium_impl/base/trace_event/ttrace.h new file mode 100644 index 0000000..e90f737 --- /dev/null +++ b/tizen_src/chromium_impl/base/trace_event/ttrace.h @@ -0,0 +1,38 @@ +// Copyright 2021 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TRACE_EVENT_TTRACE_H_ +#define BASE_TRACE_EVENT_TTRACE_H_ + +#ifdef USE_TTRACE +#include + +bool TraceEventTTraceBegin(uint64_t tag, + const char* category_group, + const char* name); + +#define __TTRACE_WEB_SCOPE_VAR_HELPER(A, B) A##B +#define __TTRACE_WEB_SCOPE_VAR(V, L) __TTRACE_WEB_SCOPE_VAR_HELPER(V, L) +#define TTRACE_WEB_SCOPE(...) \ + TTraceWrapper __TTRACE_WEB_SCOPE_VAR(ttrace, __LINE__)(TTRACE_TAG_WEB, \ + __VA_ARGS__) +#define TTRACE_WEB_MARK(...) traceMark(TTRACE_TAG_WEB, __VA_ARGS__) +#define TTRACE_WEB_ASYNC_BEGIN(uid, ...) \ + traceAsyncBegin(TTRACE_TAG_WEB, uid, __VA_ARGS__) +#define TTRACE_WEB_ASYNC_END(uid, ...) \ + traceAsyncEnd(TTRACE_TAG_WEB, uid, __VA_ARGS__) + +#define TTRACE_WEB_TRACE_EVENT_BEGIN(category_group, name) \ + TraceEventTTraceBegin(TTRACE_TAG_WEB, category_group, name) +#define TTRACE_WEB_TRACE_EVENT_END() traceEnd(TTRACE_TAG_WEB) +#else +#define TTRACE_WEB_SCOPE(...) +#define TTRACE_WEB_MARK(...) +#define TTRACE_WEB_ASYNC_BEGIN(...) +#define TTRACE_WEB_ASYNC_END(...) +#endif + +#define TTRACE_WEB TTRACE_WEB_SCOPE + +#endif // BASE_TRACE_EVENT_TTRACE_H_ diff --git a/tizen_src/ewk/efl_integration/public/ewk_view.cc b/tizen_src/ewk/efl_integration/public/ewk_view.cc index 9392ea8..0e7b349 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_view.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_view.cc @@ -24,6 +24,7 @@ #include #include "authentication_challenge_popup.h" +#include "base/trace_event/ttrace.h" #include "content/public/browser/navigation_controller.h" #include "cookie_manager.h" #include "eweb_view.h" @@ -133,6 +134,7 @@ Ewk_Context *ewk_view_context_get(const Evas_Object *view) Eina_Bool ewk_view_url_set(Evas_Object* view, const char* url_string) { + TTRACE_WEB("ewk_view_url_set url: %s", url_string); EWK_VIEW_IMPL_GET_OR_RETURN(view, impl, false); EINA_SAFETY_ON_NULL_RETURN_VAL(url_string, false); GURL url(url_string); diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc index 2d6149d..67a2e18 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc @@ -5,6 +5,7 @@ #include "web_contents_delegate_efl.h" #include "base/strings/utf_string_conversions.h" +#include "base/trace_event/ttrace.h" #include "browser/favicon/favicon_database.h" #include "browser/input_picker/color_chooser_efl.h" #include "browser/javascript_dialog_manager_efl.h" @@ -567,9 +568,7 @@ void WebContentsDelegateEfl::DidRenderFrame() { (web_view_->GetProgressValue() > 0.1)) { did_first_visually_non_empty_paint_ = false; did_render_frame_ = true; -#if defined(USE_TTRACE) TTRACE_WEB("WebContentsDelegateEfl::DidRenderFrame"); -#endif LOG(INFO) << "WebContentsDelegateEfl::DidRenderFrame"; // "frame,rendered" message is triggered as soon as rendering of a frame diff --git a/v8/BUILD.gn b/v8/BUILD.gn index be07049..53d0a15 100644 --- a/v8/BUILD.gn +++ b/v8/BUILD.gn @@ -9,6 +9,7 @@ import("//build/config/host_byteorder.gni") import("//build/config/mips.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build_overrides/build.gni") +import("//tizen_src/build/config/tizen_features.gni") if (is_android) { import("//build/config/android/rules.gni") @@ -5495,6 +5496,9 @@ v8_component("v8_libbase") { "pthread", ] } + if (use_ttrace) { + deps += [ "//tizen_src/chromium_impl/base:trace_event_ttrace" ] + } } else if (current_os == "aix") { sources += [ "src/base/debug/stack_trace_posix.cc", diff --git a/v8/src/tracing/trace-event.h b/v8/src/tracing/trace-event.h index ed53d55..61df648 100644 --- a/v8/src/tracing/trace-event.h +++ b/v8/src/tracing/trace-event.h @@ -18,10 +18,14 @@ #include "base/trace_event/common/trace_event_common.h" #endif // !defined(V8_USE_PERFETTO) +#include "build/build_config.h" #include "include/v8-platform.h" #include "src/base/atomicops.h" #include "src/base/macros.h" +#if BUILDFLAG(IS_EFL) +#include "base/trace_event/ttrace.h" +#endif // This header file defines implementation details of how the trace macros in // trace_event_common.h collect and store trace events. Anything not // implementation-specific should go in trace_macros_common.h instead of here. @@ -192,18 +196,24 @@ enum CategoryGroupEnabledFlags { // Implementation detail: internal macro to create static category and add begin // event if the category is enabled. Also adds the end event when the scope // ends. +#if defined(USE_TTRACE_TRACE_EVENT_V8) +#define TTRACE_TRACE_EVENT(tracer, category_group, name) \ + INTERNAL_TRACE_EVENT_UID(tracer).TTraceBegin(category_group, name); +#else +#define TTRACE_TRACE_EVENT(tracer, category_group, name) +#endif #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ v8::internal::tracing::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ + TTRACE_TRACE_EVENT(tracer, category_group, name) \ if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ uint64_t h = v8::internal::tracing::AddTraceEvent( \ TRACE_EVENT_PHASE_COMPLETE, \ INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ v8::internal::tracing::kGlobalScope, v8::internal::tracing::kNoId, \ v8::internal::tracing::kNoId, TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \ - INTERNAL_TRACE_EVENT_UID(tracer) \ - .Initialize(INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ - h); \ + INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \ + INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \ } #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \ @@ -562,9 +572,16 @@ static V8_INLINE uint64_t AddTraceEventWithTimestamp( class ScopedTracer { public: // Note: members of data_ intentionally left uninitialized. See Initialize. +#if defined(USE_TTRACE_TRACE_EVENT_V8) + ScopedTracer() : p_data_(nullptr), use_ttrace_(false) {} +#else ScopedTracer() : p_data_(nullptr) {} +#endif ~ScopedTracer() { +#if defined(USE_TTRACE_TRACE_EVENT_V8) + if (use_ttrace_) TTRACE_WEB_TRACE_EVENT_END(); +#endif if (p_data_ && base::Relaxed_Load(reinterpret_cast( data_.category_group_enabled))) { TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( @@ -572,6 +589,12 @@ class ScopedTracer { } } +#if defined(USE_TTRACE_TRACE_EVENT_V8) + void TTraceBegin(const char* category_group, const char* name) { + use_ttrace_ = TTRACE_WEB_TRACE_EVENT_BEGIN(category_group, name); + } +#endif + void Initialize(const uint8_t* category_group_enabled, const char* name, uint64_t event_handle) { data_.category_group_enabled = category_group_enabled; @@ -593,6 +616,9 @@ class ScopedTracer { }; Data* p_data_; Data data_; +#if defined(USE_TTRACE_TRACE_EVENT_V8) + bool use_ttrace_; +#endif }; #ifdef V8_RUNTIME_CALL_STATS -- 2.7.4 From 139dd4101cddf1c842679cf14a2f910889f22073 Mon Sep 17 00:00:00 2001 From: Suhaspoornachandra Date: Wed, 25 Jan 2023 14:52:59 +0530 Subject: [PATCH 11/16] [M108 Migration][MM] Migrate Tbm feature for Tizen Multimedia This commit migrates below patches and their fixup's 1) Add Tbm Surface support 2) Add support for tbm buffer handling 3) [MM] Handle TBM on video frame drop 4) [MM] Fix memory leak during playing video using TBM 5) [MM] Fix the crash when player is destroyed before tbm media packet (partial) Reference: https://review.tizen.org/gerrit/269846/ https://review.tizen.org/gerrit/270726/ https://review.tizen.org/gerrit/272817/ https://review.tizen.org/gerrit/273650/ https://review.tizen.org/gerrit/274633/ https://review.tizen.org/gerrit/279208/ https://review.tizen.org/gerrit/282988/ Change-Id: Id65cfea36a7469c81c764d5d84d0ff9f84013244 Signed-off-by: Suhaspoornachandra --- cc/layers/video_layer_impl.cc | 97 +++++++++++++++ cc/layers/video_layer_impl.h | 16 +++ .../public/remoting_proto_enum_utils.cc | 3 + components/viz/common/features.cc | 2 + content/renderer/render_thread_impl.cc | 3 + gpu/GLES2/gl2chromium_autogen.h | 2 + gpu/command_buffer/build_gles2_cmd_buffer.py | 11 ++ gpu/command_buffer/client/gles2_c_lib_autogen.h | 18 +++ gpu/command_buffer/client/gles2_implementation.cc | 70 ++++++++++- gpu/command_buffer/client/gles2_implementation.h | 7 ++ .../client/gles2_implementation_autogen.h | 7 ++ gpu/command_buffer/client/gles2_interface.h | 1 + .../client/gles2_interface_autogen.h | 5 + .../client/gles2_interface_stub_autogen.h | 5 + .../client/gles2_interface_stub_impl_autogen.h | 8 ++ .../client/gles2_trace_implementation_autogen.h | 5 + .../gles2_trace_implementation_impl_autogen.h | 14 +++ gpu/command_buffer/client/gpu_control.h | 14 +++ gpu/command_buffer/gles2_cmd_buffer_functions.txt | 4 + gpu/ipc/client/command_buffer_proxy_impl.cc | 49 ++++++++ gpu/ipc/client/command_buffer_proxy_impl.h | 8 ++ .../gpu_memory_buffer_factory_native_pixmap.cc | 11 +- media/base/video_frame.cc | 138 +++++++++++++++++++++ media/base/video_frame.h | 51 ++++++++ media/base/video_frame_layout.cc | 3 + media/base/video_types.cc | 13 ++ media/base/video_types.h | 7 +- media/capture/mojom/BUILD.gn | 9 ++ media/capture/mojom/video_capture_types.mojom | 3 + .../mojom/video_capture_types_mojom_traits.cc | 9 ++ media/mojo/mojom/renderer_extensions.mojom | 9 ++ media/renderers/paint_canvas_video_renderer.cc | 39 +++++- media/renderers/video_resource_updater.cc | 14 ++- media/renderers/video_resource_updater.h | 4 +- media/video/gpu_memory_buffer_video_frame_pool.cc | 3 + services/viz/public/mojom/BUILD.gn | 10 ++ .../openscreen/src/cast/streaming/remoting.proto | 1 + tizen_src/build/config/BUILD.gn | 6 +- tizen_src/build/gn_chromiumefl.sh | 2 +- .../chromium_impl/content/browser/browser_efl.gni | 7 -- .../content/browser/media/tizen_renderer_impl.cc | 47 ++++++- .../content/browser/media/tizen_renderer_impl.h | 7 ++ .../media/tizen/media_player_renderer_client.cc | 28 +++++ .../media/tizen/media_player_renderer_client.h | 12 ++ .../filters/media_player_bridge_capi_adapter.cc | 13 +- .../filters/media_player_bridge_capi_adapter.h | 2 + .../media/filters/media_player_esplusplayer.cc | 29 +++++ .../media/filters/media_player_esplusplayer.h | 13 ++ .../media/filters/media_player_registry.cc | 41 ++++++ .../media/filters/media_player_registry.h | 42 +++++++ tizen_src/chromium_impl/media/media_efl.gni | 2 + tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h | 35 ++++++ tizen_src/chromium_impl/ui/ui_efl.gni | 1 + ui/gfx/gpu_memory_buffer.h | 10 ++ ui/gfx/mojom/BUILD.gn | 10 ++ ui/gfx/mojom/buffer_types.mojom | 52 ++++++++ ui/gfx/mojom/buffer_types_mojom_traits.cc | 63 ++++++++++ ui/gfx/mojom/buffer_types_mojom_traits.h | 61 +++++++++ ui/gl/gl_image_egl.cc | 33 +++++ ui/gl/gl_image_egl.h | 11 ++ ui/gl/gl_image_native_pixmap.cc | 20 +++ ui/gl/gl_image_native_pixmap.h | 18 +++ 62 files changed, 1217 insertions(+), 21 deletions(-) create mode 100644 tizen_src/chromium_impl/media/filters/media_player_registry.cc create mode 100644 tizen_src/chromium_impl/media/filters/media_player_registry.h create mode 100644 tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index a6ced88..96080d7 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc @@ -25,6 +25,12 @@ #include "media/renderers/video_resource_updater.h" #include "ui/gfx/color_space.h" +#if defined(TIZEN_TBM_SUPPORT) +#include "components/viz/common/quads/tile_draw_quad.h" +#include "components/viz/service/display/skia_renderer.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#endif + namespace cc { // static @@ -57,6 +63,9 @@ VideoLayerImpl::VideoLayerImpl( } VideoLayerImpl::~VideoLayerImpl() { +#if defined(TIZEN_TBM_SUPPORT) + ReleaseResources(); +#endif if (!provider_client_impl_->Stopped()) { // In impl side painting, we may have a pending and active layer // associated with the video provider at the same time. Both have a ref @@ -107,6 +116,63 @@ bool VideoLayerImpl::WillDraw(DrawMode draw_mode, return false; } +#if defined(TIZEN_TBM_SUPPORT) + if (frame_->IsTBMBackend()) { + context_provider_ = layer_tree_impl()->context_provider(); + if (!context_provider_) + return false; + // Pass a VideoFrame reference to OnVideoCompositingFinished() callback to + // ensure that VideoFrame object is valid. + // OnVideoCompositingFinished() callback is invoked when finish to use the + // resource on browser process. + // After OnVideoCompositingFinished() is invoked, VideoFrame object can be + // destroyed. + frame_->SetContextProvider(context_provider_); + gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); + frame_->CreateTbmTextureIfNeeded(gl); + const gpu::MailboxHolder& mailbox_holder = frame_->mailbox_holder(0); + auto transferable_resource = viz::TransferableResource::MakeGpu( + mailbox_holder.mailbox, GL_LINEAR, mailbox_holder.texture_target, + mailbox_holder.sync_token, frame_->visible_rect().size(), + viz::RGBA_8888, false); + resource_id_ = resource_provider->ImportResource( + transferable_resource, + base::BindOnce(&VideoLayerImpl::OnVideoCompositingFinished, + base::Unretained(this), frame_)); +#if defined(_DEBUG_TBM_VIDEO_RENDERING) && _DEBUG_TBM_VIDEO_RENDERING + LOG(INFO) << " Video frame > " + << ", texture_id:" << frame_->GetTbmTexture() + << ", resource_id:" << resource_id_ + << ", size:" << frame_->visible_rect().size().ToString(); +#endif + +#if defined(_DEBUG_TBM_VIDEO_RENDERING_FPS) && _DEBUG_TBM_VIDEO_RENDERING_FPS + static media::VideoFrame* prev_frame = 0; + static int new_frame_cnt = 0; + static int frame_cnt = 0; + static base::TimeTicks last_tick = base::TimeTicks::Now(); + const base::TimeTicks now = base::TimeTicks::Now(); + const base::TimeDelta interval = now - last_tick; + + if (prev_frame != frame_.get()) + new_frame_cnt++; + prev_frame = frame_.get(); + frame_cnt++; + if (interval >= base::TimeDelta::FromSeconds(1)) { + printf("VideoTBM[Draw] > [FPS]%.1f/%.1f\n", + new_frame_cnt / interval.InSecondsF(), + frame_cnt / interval.InSecondsF()); + LOG(INFO) << "VideoTBM[Draw] > [FPS]" + << (new_frame_cnt / interval.InSecondsF()) << "/" + << (frame_cnt / interval.InSecondsF()); + last_tick = now; + frame_cnt = 0; + new_frame_cnt = 0; + } +#endif + } +#endif + if (!updater_) { const LayerTreeSettings& settings = layer_tree_impl()->settings(); // TODO(sergeyu): Pass RasterContextProvider when it's available. Then @@ -121,7 +187,11 @@ bool VideoLayerImpl::WillDraw(DrawMode draw_mode, settings.resource_settings.use_r16_texture, layer_tree_impl()->max_texture_size()); } +#if defined(TIZEN_TBM_SUPPORT) + updater_->ObtainFrameResources(frame_, resource_id_); +#else updater_->ObtainFrameResources(frame_); +#endif return true; } @@ -195,6 +265,23 @@ void VideoLayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) { provider_client_impl_->ReleaseLock(); } +#if defined(TIZEN_TBM_SUPPORT) +void VideoLayerImpl::OnVideoCompositingFinished( + const scoped_refptr video_frame, + const gpu::SyncToken& sync_token, + bool lost_resource) { +#if defined(USE_TTRACE) + TTRACE_WEB("VideoLayerImpl::OnVideoCompositingFinished"); +#endif +#if defined(_DEBUG_TBM_VIDEO_RENDERING) && _DEBUG_TBM_VIDEO_RENDERING + LOG(INFO) + << "OnVideoCompositingFinished > resource was removed in ResourceProvider" + << ", tbm:" << video_frame->GetTbmBuffer().tbm_surface + << ", txt:" << video_frame->GetTbmTexture(); +#endif +} +#endif + SimpleEnclosedRegion VideoLayerImpl::VisibleOpaqueRegion() const { // If we don't have a frame yet, then we don't have an opaque region. if (!provider_client_impl_->HasCurrentFrame()) @@ -203,6 +290,16 @@ SimpleEnclosedRegion VideoLayerImpl::VisibleOpaqueRegion() const { } void VideoLayerImpl::ReleaseResources() { +#if defined(TIZEN_TBM_SUPPORT) + scoped_refptr last_frame = frame_; + if (!frame_) + last_frame = provider_client_impl_->AcquireLockAndCurrentFrame(); + if (last_frame) + last_frame->ReleaseTbm(); + last_frame = nullptr; + if (!frame_) + provider_client_impl_->ReleaseLock(); +#endif updater_ = nullptr; } diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h index 3bad972..99c89dc 100644 --- a/cc/layers/video_layer_impl.h +++ b/cc/layers/video_layer_impl.h @@ -13,6 +13,10 @@ #include "components/viz/common/resources/release_callback.h" #include "media/base/video_transformation.h" +#if defined(TIZEN_TBM_SUPPORT) +#include "components/viz/common/gpu/context_provider.h" +#endif + namespace media { class VideoFrame; class VideoResourceUpdater; @@ -64,12 +68,24 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { const char* LayerTypeAsString() const override; +#if defined(TIZEN_TBM_SUPPORT) + void OnVideoCompositingFinished( + const scoped_refptr video_frame, + const gpu::SyncToken& sync_token, + bool lost_resource); +#endif + scoped_refptr provider_client_impl_; scoped_refptr frame_; media::VideoTransformation video_transform_; +#if defined(TIZEN_TBM_SUPPORT) + scoped_refptr context_provider_; + viz::ResourceId resource_id_; +#endif + std::unique_ptr updater_; }; diff --git a/components/cast_streaming/public/remoting_proto_enum_utils.cc b/components/cast_streaming/public/remoting_proto_enum_utils.cc index 9a173e6..98af814 100644 --- a/components/cast_streaming/public/remoting_proto_enum_utils.cc +++ b/components/cast_streaming/public/remoting_proto_enum_utils.cc @@ -374,6 +374,9 @@ absl::optional ToMediaVideoPixelFormat( CASE_RETURN_OTHER(PIXEL_FORMAT_P016LE); CASE_RETURN_OTHER(PIXEL_FORMAT_XR30); CASE_RETURN_OTHER(PIXEL_FORMAT_XB30); +#if defined(TIZEN_TBM_SUPPORT) + CASE_RETURN_OTHER(PIXEL_FORMAT_TBM_SURFACE); +#endif // PIXEL_FORMAT_UYVY, PIXEL_FORMAT_RGB32 and PIXEL_FORMAT_Y8 are deprecated. case openscreen::cast::VideoDecoderConfig_Format_PIXEL_FORMAT_RGB32: return absl::nullopt; diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index dbd3021..4d16116 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc @@ -331,6 +331,8 @@ bool UseSurfaceLayerForVideo() { return true; } return base::FeatureList::IsEnabled(kUseSurfaceLayerForVideoDefault); +#elif defined(TIZEN_MULTIMEDIA) + return false; #else return true; #endif diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 17b6280..617b57f 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -1147,6 +1147,9 @@ RenderThreadImpl::SharedMainThreadContextProvider() { .status_values[gpu::GPU_FEATURE_TYPE_CANVAS_OOP_RASTERIZATION] == gpu::kGpuFeatureStatusEnabled; bool support_gles2_interface = false; +#if defined(TIZEN_TBM_SUPPORT) + support_gles2_interface = true; +#endif bool support_grcontext = !support_oop_rasterization; // Enable automatic flushes to improve canvas throughput. // See https://crbug.com/880901 diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index efcb0d37..014d040 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -348,6 +348,8 @@ #define glCoverageModulationCHROMIUM GLES2_GET_FUN(CoverageModulationCHROMIUM) #define glGetGraphicsResetStatusKHR GLES2_GET_FUN(GetGraphicsResetStatusKHR) #define glBlendBarrierKHR GLES2_GET_FUN(BlendBarrierKHR) +#define glCreateTizenImageCHROMIUM GLES2_GET_FUN(CreateTizenImageCHROMIUM) +#define glDestroyTizenImageCHROMIUM GLES2_GET_FUN(DestroyTizenImageCHROMIUM) #define glBindFragDataLocationIndexedEXT \ GLES2_GET_FUN(BindFragDataLocationIndexedEXT) #define glBindFragDataLocationEXT GLES2_GET_FUN(BindFragDataLocationEXT) diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index b8bef5e..849dc9b 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -3958,6 +3958,17 @@ _FUNCTION_INFO = { 'extension': True, 'trace_level': 2, }, + 'CreateTizenImageCHROMIUM': { + 'type': 'NoCommand', + 'cmd_args':'gfx::TbmBufferHandle handle, GLsizei width,' + ' GLsizei height, GLenum internalformat', + 'result': ['GLuint'], + 'extension': True, + }, + 'DestroyTizenImageCHROMIUM': { + 'type': 'NoCommand', + 'extension': True, + }, 'InitializeDiscardableTextureCHROMIUM': { 'type': 'Custom', 'cmd_args': 'GLuint texture_id, uint32_t shm_id, ' diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 7114150..dc682bd 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -1601,6 +1601,16 @@ GLenum GL_APIENTRY GLES2GetGraphicsResetStatusKHR() { void GL_APIENTRY GLES2BlendBarrierKHR() { gles2::GetGLContext()->BlendBarrierKHR(); } +GLuint GL_APIENTRY GLES2CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle, + GLsizei width, + GLsizei height, + GLenum internalformat) { + return gles2::GetGLContext()->CreateTizenImageCHROMIUM(handle, width, height, + internalformat); +} +void GL_APIENTRY GLES2DestroyTizenImageCHROMIUM(GLuint image_id) { + gles2::GetGLContext()->DestroyTizenImageCHROMIUM(image_id); +} void GL_APIENTRY GLES2BindFragDataLocationIndexedEXT(GLuint program, GLuint colorNumber, GLuint index, @@ -2986,6 +2996,14 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast(glBlendBarrierKHR), }, { + "glCreateTizenImageCHROMIUM", + reinterpret_cast(glCreateTizenImageCHROMIUM), + }, + { + "glDestroyTizenImageCHROMIUM", + reinterpret_cast(glDestroyTizenImageCHROMIUM), + }, + { "glBindFragDataLocationIndexedEXT", reinterpret_cast( glBindFragDataLocationIndexedEXT), diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 9aed697..d66cb81 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -108,6 +108,10 @@ !ptr || \ (ptr[0] == static_cast(0) || ptr[0] == static_cast(-1))); +#if defined(TIZEN_TBM_SUPPORT) +#include "base/logging.h" +#endif + namespace gpu { namespace gles2 { @@ -244,7 +248,9 @@ GLES2Implementation::GLES2Implementation( aggressively_free_resources_(false), cached_extension_string_(nullptr) { DCHECK(helper); - +#if defined(TIZEN_TBM_SUPPORT) + LOG(INFO) << __FUNCTION__ << " " << this; +#endif std::stringstream ss; ss << std::hex << this; this_in_hex_ = ss.str(); @@ -324,6 +330,9 @@ GLES2Implementation::~GLES2Implementation() { // shared memory (mapped_memory_) which will free the memory used // by the queries. The GPU process when validating that memory is still // shared will fail and abort (ie, it will stop running). +#if defined(TIZEN_TBM_SUPPORT) + LOG(INFO) << __FUNCTION__ << " " << this; +#endif WaitForCmd(); query_tracker_.reset(); @@ -6899,6 +6908,65 @@ bool GLES2Implementation::CanDecodeWithHardwareAcceleration( return false; } +#if defined(TIZEN_TBM_SUPPORT) +GLuint GLES2Implementation::CreateTizenImageCHROMIUMHelper( + gfx::TbmBufferHandle buffer_handle, + GLsizei width, + GLsizei height, + GLenum internalformat) { + if (width <= 0) { + SetGLError(GL_INVALID_VALUE, "glCreateTizenImageCHROMIUM", "width <= 0"); + return 0; + } + + if (height <= 0) { + SetGLError(GL_INVALID_VALUE, "glCreateTizenImageCHROMIUM", "height <= 0"); + return 0; + } + + int32_t image_id = gpu_control_->CreateEGLImage(buffer_handle, width, height, + internalformat); + if (image_id < 0) { + SetGLError(GL_OUT_OF_MEMORY, "glCreateTizenImageCHROMIUM", "image_id < 0"); + return 0; + } + return image_id; +} +#endif + +GLuint GLES2Implementation::CreateTizenImageCHROMIUM( + gfx::TbmBufferHandle buffer_handle, + GLsizei width, + GLsizei height, + GLenum internalformat) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG( + "[" << GetLogPrefix() << "] glCreateTizenImageCHROMIUM(" << buffer_handle + << ", " << width << ", " << height << ", " + << GLES2Util::GetStringTextureInternalFormat(internalformat) << ")"); +#if defined(TIZEN_TBM_SUPPORT) + GLuint image_id = CreateTizenImageCHROMIUMHelper(buffer_handle, width, height, + internalformat); + CheckGLError(); + return image_id; +#else + return 0; +#endif +} + +void GLES2Implementation::DestroyTizenImageCHROMIUM(GLuint image_id) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDestroyTizenImageCHROMIUM(" + << image_id << ")"); +#if defined(TIZEN_TBM_SUPPORT) + // Flush the command stream to make sure all pending commands + // that may refer to the image_id are executed on the service side. + helper_->CommandBufferHelper::Flush(); + gpu_control_->DestroyEGLImage(image_id); + CheckGLError(); +#endif +} + bool GLES2Implementation::ValidateSize(const char* func, GLsizeiptr size) { if (size < 0) { SetGLError(GL_INVALID_VALUE, func, "size < 0"); diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index cf8daae..24934f9 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -523,6 +523,13 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface, const GLuint* baseInstances, GLsizei drawcount); +#if defined(TIZEN_TBM_SUPPORT) + GLuint CreateTizenImageCHROMIUMHelper(gfx::TbmBufferHandle buffer_handle, + GLsizei width, + GLsizei height, + GLenum internalformat); +#endif + // Helper for GetVertexAttrib bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32_t* param); diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index f1c6a51..7e96128 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -1127,6 +1127,13 @@ GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; +GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle, + GLsizei width, + GLsizei height, + GLenum internalformat) override; + +void DestroyTizenImageCHROMIUM(GLuint image_id) override; + void BindFragDataLocationIndexedEXT(GLuint program, GLuint colorNumber, GLuint index, diff --git a/gpu/command_buffer/client/gles2_interface.h b/gpu/command_buffer/client/gles2_interface.h index bcc3cd1..aa59036 100644 --- a/gpu/command_buffer/client/gles2_interface.h +++ b/gpu/command_buffer/client/gles2_interface.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "gpu/command_buffer/client/interface_base.h" +#include "ui/gfx/tbm_buffer_handle.h" namespace cc { class ClientTransferCacheEntry; diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index d24bf67..ab5f1ca 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -835,6 +835,11 @@ virtual void ContextVisibilityHintCHROMIUM(GLboolean visibility) = 0; virtual void CoverageModulationCHROMIUM(GLenum components) = 0; virtual GLenum GetGraphicsResetStatusKHR() = 0; virtual void BlendBarrierKHR() = 0; +virtual GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle, + GLsizei width, + GLsizei height, + GLenum internalformat) = 0; +virtual void DestroyTizenImageCHROMIUM(GLuint image_id) = 0; virtual void BindFragDataLocationIndexedEXT(GLuint program, GLuint colorNumber, GLuint index, diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index c799d22..cb8e5d0 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -811,6 +811,11 @@ void ContextVisibilityHintCHROMIUM(GLboolean visibility) override; void CoverageModulationCHROMIUM(GLenum components) override; GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; +GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle, + GLsizei width, + GLsizei height, + GLenum internalformat) override; +void DestroyTizenImageCHROMIUM(GLuint image_id) override; void BindFragDataLocationIndexedEXT(GLuint program, GLuint colorNumber, GLuint index, diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 0dc071a..2dd74a0 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -1088,6 +1088,14 @@ GLenum GLES2InterfaceStub::GetGraphicsResetStatusKHR() { return 0; } void GLES2InterfaceStub::BlendBarrierKHR() {} +GLuint GLES2InterfaceStub::CreateTizenImageCHROMIUM( + gfx::TbmBufferHandle /* handle */, + GLsizei /* width */, + GLsizei /* height */, + GLenum /* internalformat */) { + return 0; +} +void GLES2InterfaceStub::DestroyTizenImageCHROMIUM(GLuint /* image_id */) {} void GLES2InterfaceStub::BindFragDataLocationIndexedEXT( GLuint /* program */, GLuint /* colorNumber */, diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 2103e9e..63b3b61 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -811,6 +811,11 @@ void ContextVisibilityHintCHROMIUM(GLboolean visibility) override; void CoverageModulationCHROMIUM(GLenum components) override; GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; +GLuint CreateTizenImageCHROMIUM(gfx::TbmBufferHandle handle, + GLsizei width, + GLsizei height, + GLenum internalformat) override; +void DestroyTizenImageCHROMIUM(GLuint image_id) override; void BindFragDataLocationIndexedEXT(GLuint program, GLuint colorNumber, GLuint index, diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index e22cb21..1a6c4c5 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -2313,6 +2313,20 @@ void GLES2TraceImplementation::BlendBarrierKHR() { gl_->BlendBarrierKHR(); } +GLuint GLES2TraceImplementation::CreateTizenImageCHROMIUM( + gfx::TbmBufferHandle handle, + GLsizei width, + GLsizei height, + GLenum internalformat) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateTizenImageCHROMIUM"); + return gl_->CreateTizenImageCHROMIUM(handle, width, height, internalformat); +} + +void GLES2TraceImplementation::DestroyTizenImageCHROMIUM(GLuint image_id) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DestroyTizenImageCHROMIUM"); + gl_->DestroyTizenImageCHROMIUM(image_id); +} + void GLES2TraceImplementation::BindFragDataLocationIndexedEXT( GLuint program, GLuint colorNumber, diff --git a/gpu/command_buffer/client/gpu_control.h b/gpu/command_buffer/client/gpu_control.h index eadc592..a45ac1a 100644 --- a/gpu/command_buffer/client/gpu_control.h +++ b/gpu/command_buffer/client/gpu_control.h @@ -18,6 +18,10 @@ #include "gpu/gpu_export.h" #include "ui/gfx/overlay_transform.h" +#if defined(TIZEN_TBM_SUPPORT) +#include "ui/gfx/tbm_buffer_handle.h" +#endif + extern "C" typedef struct _ClientBuffer* ClientBuffer; extern "C" typedef struct _ClientGpuFence* ClientGpuFence; @@ -47,6 +51,16 @@ class GPU_EXPORT GpuControl { virtual const Capabilities& GetCapabilities() const = 0; +#if defined(TIZEN_TBM_SUPPORT) + virtual int32_t CreateEGLImage(gfx::TbmBufferHandle buffer_handle, + size_t width, + size_t height, + unsigned internalformat) { + return -1; + } + virtual void DestroyEGLImage(int32_t image_id) {} +#endif + // Runs |callback| when a query created via glCreateQueryEXT() has cleared // passed the glEndQueryEXT() point. virtual void SignalQuery(uint32_t query, base::OnceClosure callback) = 0; diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index a2801cd..15dae8d 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt @@ -348,6 +348,10 @@ GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void); // Extension KHR_blend_equation_advanced GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void); +// for tizen +GL_APICALL GLuint GL_APIENTRY glCreateTizenImageCHROMIUM (gfx::TbmBufferHandle handle, GLsizei width, GLsizei height, GLenum internalformat); +GL_APICALL void GL_APIENTRY glDestroyTizenImageCHROMIUM (GLuint image_id); + // Extension EXT_blend_func_extended GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLidProgram program, GLuint colorNumber, GLuint index, const char* name); GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLidProgram program, GLuint colorNumber, const char* name); diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc index 682ed9f..a6af84d 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc @@ -415,6 +415,55 @@ const gpu::Capabilities& CommandBufferProxyImpl::GetCapabilities() const { return capabilities_; } +#if defined(TIZEN_TBM_SUPPORT) +int32_t CommandBufferProxyImpl::CreateEGLImage( + gfx::TbmBufferHandle buffer_handle, + size_t width, + size_t height, + unsigned internalformat) { + CheckLock(); + base::AutoLock lock(last_state_lock_); + if (last_state_.error != gpu::error::kNoError) + return -1; + + int32_t new_id = channel_->ReserveImageId(); + + auto params = mojom::CreateImageParams::New(); + params->id = new_id; + params->size = gfx::Size(width, height); + params->format = gfx::BufferFormat::RGBA_8888; + params->plane = gfx::BufferPlane::DEFAULT; + params->image_release_count = 0; + + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::NATIVE_PIXMAP; + handle.tbm_surface = reinterpret_cast(buffer_handle.tbm_surface); + handle.media_packet = reinterpret_cast(buffer_handle.media_packet); + handle.player_id = buffer_handle.player_id; + handle.key_num = buffer_handle.key_num; + for (int i = 0; i < handle.key_num; ++i) { + handle.key[i] = buffer_handle.key[i]; + handle.strides[i] = buffer_handle.strides[i]; + LOG(ERROR) << "exported key values " << handle.key[i]; + } + handle.width = width; + handle.height = height; + + params->gpu_memory_buffer = std::move(handle); + command_buffer_->CreateImage(std::move(params)); + return new_id; +} + +void CommandBufferProxyImpl::DestroyEGLImage(int32_t image_id) { + CheckLock(); + base::AutoLock lock(last_state_lock_); + if (last_state_.error != gpu::error::kNoError) + return; + + command_buffer_->DestroyImage(image_id); +} +#endif + void CommandBufferProxyImpl::SetLock(base::Lock* lock) { lock_ = lock; } diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h index 80369c9..969320f 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/gpu/ipc/client/command_buffer_proxy_impl.h @@ -163,6 +163,14 @@ class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer, return shared_state_shm_; } +#if defined(TIZEN_TBM_SUPPORT) + int32_t CreateEGLImage(gfx::TbmBufferHandle buffer_handle, + size_t width, + size_t height, + unsigned internalformat) override; + void DestroyEGLImage(int32_t image_id) override; +#endif + private: typedef std::map> TransferBufferMap; typedef std::unordered_map SignalTaskMap; diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc index 2dff68b..cdd61b8 100644 --- a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc +++ b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc @@ -129,7 +129,15 @@ GpuMemoryBufferFactoryNativePixmap::CreateImageForGpuMemoryBuffer( SurfaceHandle surface_handle) { if (handle.type != gfx::NATIVE_PIXMAP) return nullptr; - +#if defined(TIZEN_TBM_SUPPORT) + scoped_refptr image( + new gl::GLImageNativePixmap(size, format)); + if (!image->Initialize(handle)) { + LOG(ERROR) << "Failed to create GLImage"; + return nullptr; + } + return image; +#else scoped_refptr pixmap; // If CreateGpuMemoryBuffer was used to allocate this buffer then avoid @@ -180,6 +188,7 @@ GpuMemoryBufferFactoryNativePixmap::CreateImageForGpuMemoryBuffer( NOTREACHED(); return nullptr; } +#endif } bool GpuMemoryBufferFactoryNativePixmap::SupportsCreateAnonymousImage() const { diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 4aa077a..ef1213f 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -31,6 +31,13 @@ #if BUILDFLAG(IS_MAC) #include "ui/gfx/mac/io_surface.h" #endif +#if defined(TIZEN_TBM_SUPPORT) +#include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/trace_event.h" +#include "gpu/GLES2/gl2extchromium.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#include "media/base/bind_to_current_loop.h" +#endif namespace media { @@ -79,6 +86,10 @@ std::string VideoFrame::StorageTypeToString( case VideoFrame::STORAGE_DMABUFS: return "DMABUFS"; #endif +#if defined(TIZEN_TBM_SUPPORT) + case VideoFrame::STORAGE_TBM_SURFACE: + return "TBM_SURFACE"; +#endif case VideoFrame::STORAGE_GPU_MEMORY_BUFFER: return "GPU_MEMORY_BUFFER"; } @@ -164,6 +175,9 @@ gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) { case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_RGBAF16: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif break; } } @@ -197,6 +211,9 @@ static bool RequiresEvenSizeAllocation(VideoPixelFormat format) { case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_RGBAF16: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif return false; case PIXEL_FORMAT_NV12: case PIXEL_FORMAT_NV21: @@ -354,6 +371,34 @@ scoped_refptr VideoFrame::CreateZeroInitializedFrame( } // static +#if defined(TIZEN_TBM_SUPPORT) +scoped_refptr VideoFrame::WrapTBMSurface( + const gfx::Size& size, + base::TimeDelta timestamp, + gfx::TbmBufferHandle handle) { + const VideoPixelFormat format = PIXEL_FORMAT_TBM_SURFACE; + const StorageType storage = STORAGE_TBM_SURFACE; + const gfx::Rect visible_rect = gfx::Rect(size); + if (!IsValidConfig(format, storage, size, visible_rect, size)) { + LOG(ERROR) << __FUNCTION__ << " WrapTBMSurface Invalid config." + << ConfigToString(format, storage, size, visible_rect, size); + return nullptr; + } + + auto layout = VideoFrameLayout::Create(format, size); + if (!layout) { + LOG(ERROR) << "Invalid layout."; + return nullptr; + } + + scoped_refptr frame( + new VideoFrame(*layout, storage, gfx::Rect(size), size, timestamp)); + frame->buffer_handle_ = handle; + return frame; +} +#endif + +// static scoped_refptr VideoFrame::WrapNativeTextures( VideoPixelFormat format, const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes], @@ -1086,6 +1131,9 @@ int VideoFrame::BytesPerElement(VideoPixelFormat format, size_t plane) { return 1; case PIXEL_FORMAT_MJPEG: return 0; +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif case PIXEL_FORMAT_UNKNOWN: break; } @@ -1269,7 +1317,11 @@ uint8_t* VideoFrame::GetWritableVisibleData(size_t plane) { const gpu::MailboxHolder& VideoFrame::mailbox_holder( size_t texture_index) const { +#if defined(TIZEN_TBM_SUPPORT) + DCHECK(IsTBMBackend() || HasTextures()); +#else DCHECK(HasTextures()); +#endif DCHECK(IsValidPlane(format(), texture_index)); return wrapped_frame_ ? wrapped_frame_->mailbox_holder(texture_index) : mailbox_holders_[texture_index]; @@ -1330,7 +1382,11 @@ void VideoFrame::AddDestructionObserver(base::OnceClosure callback) { } gpu::SyncToken VideoFrame::UpdateReleaseSyncToken(SyncTokenClient* client) { +#if defined(TIZEN_TBM_SUPPORT) + DCHECK(IsTBMBackend() || HasTextures()); +#else DCHECK(HasTextures()); +#endif if (wrapped_frame_) { return wrapped_frame_->UpdateReleaseSyncToken(client); } @@ -1390,6 +1446,11 @@ VideoFrame::VideoFrame(const VideoFrameLayout& layout, #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) dmabuf_fds_(base::MakeRefCounted()), #endif +#if defined(TIZEN_TBM_SUPPORT) + texture_id_(0), + gl_(nullptr), + image_id_(0), +#endif timestamp_(timestamp), unique_id_(g_unique_id_generator.GetNext()) { DCHECK(IsValidConfigInternal(format(), frame_control_type, coded_size(), @@ -1631,4 +1692,81 @@ std::vector VideoFrame::CalculatePlaneSize() const { return plane_size; } +#if defined(TIZEN_TBM_SUPPORT) +void ReleaseTbmTexture(scoped_refptr task_runner, + gpu::gles2::GLES2Interface* gl, + uint32_t texture, + uint32_t image, + scoped_refptr context_provider, + const gpu::SyncToken& release_sync_point) { +#if defined(USE_TTRACE) + TTRACE(TTRACE_TAG_WEB, "ReleaseTbmTexture"); +#endif + DCHECK(task_runner->BelongsToCurrentThread()); + const uint32_t target = GL_TEXTURE_EXTERNAL_OES; + LOG(INFO) << "VideoFrame > --ReleaseTbmTexture >" + << ", img:" << image << ", txt:" << texture; + if (release_sync_point.HasData()) + gl->WaitSyncTokenCHROMIUM(release_sync_point.GetConstData()); + if (image) { + gl->BindTexture(target, texture); + gl->ReleaseTexImage2DCHROMIUM(target, image); + gl->DestroyTizenImageCHROMIUM(image); + } + gl->DeleteTextures(1, &texture); +} + +void VideoFrame::ReleaseTbm() { + if (mailbox_holders_and_gmb_release_cb_) { + gpu::SyncToken release_sync_token; + { + // To ensure that changes to |release_sync_token_| are visible on this + // thread (imply a memory barrier). + base::AutoLock locker(release_sync_token_lock_); + release_sync_token = release_sync_token_; + } + std::move(mailbox_holders_and_gmb_release_cb_) + .Run(release_sync_token, std::move(gpu_memory_buffer_)); + } +} + +unsigned VideoFrame::CreateTbmTextureIfNeeded(gpu::gles2::GLES2Interface* gl) { +#if defined(USE_TTRACE) + TTRACE(TTRACE_TAG_WEB, "VideoFrameCompositor::CreateTbmTextureIfNeeded"); +#endif + base::AutoLock autolock(tbm_lock_); + if (!gl || texture_id_) + return (gl_ == gl) ? texture_id_ : 0; + + gl_ = gl; + unsigned image = gl->CreateTizenImageCHROMIUM( + buffer_handle_, visible_rect().width(), visible_rect().height(), GL_RGBA); + gl->GenTextures(1, &texture_id_); + gl->BindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_); + gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + gl->TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + gl->BindTexImage2DCHROMIUM(GL_TEXTURE_EXTERNAL_OES, image); + + LOG(INFO) << "CreateTbmTextureIfNeeded img:" << image + << ", txt:" << texture_id_; + + gpu::Mailbox mailbox; + gl->ProduceTextureDirectCHROMIUM(texture_id_, mailbox.name); + gl->ShallowFlushCHROMIUM(); + gpu::SyncToken sync_token; + gl->GenSyncTokenCHROMIUM(sync_token.GetData()); + mailbox_holders_[kARGBPlane] = + gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_EXTERNAL_OES); + + SetReleaseMailboxCB(base::BindOnce(ReleaseTbmTexture, + base::ThreadTaskRunnerHandle::Get(), gl, + texture_id_, image, context_provider_)); + return texture_id_; +} +#endif + } // namespace media diff --git a/media/base/video_frame.h b/media/base/video_frame.h index 8c6d873..ffeb81e 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h @@ -50,8 +50,25 @@ class GpuMemoryBuffer; struct GpuMemoryBufferHandle; } +#if defined(TIZEN_TBM_SUPPORT) +#include +#include +#include +#include "components/viz/common/gpu/context_provider.h" +#include "ui/gfx/tbm_buffer_handle.h" +#define _DEBUG_TBM_VIDEO_RENDERING 0 +#define _DEBUG_TBM_VIDEO_RENDERING_FPS 0 +namespace gpu { +namespace gles2 { +class GLES2Interface; +} +} // namespace gpu +#endif + namespace media { +constexpr auto TBM_BO_NUM_MAX = 4; + class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { public: static constexpr size_t kFrameSizeAlignment = 16; @@ -92,7 +109,12 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { STORAGE_DMABUFS = 5, // Each plane is stored into a DmaBuf. #endif STORAGE_GPU_MEMORY_BUFFER = 6, +#if defined(TIZEN_TBM_SUPPORT) + STORAGE_TBM_SURFACE = 7, + STORAGE_MAX = STORAGE_TBM_SURFACE, +#else STORAGE_MAX = STORAGE_GPU_MEMORY_BUFFER, +#endif }; // CB to be called on the mailbox backing this frame and its GpuMemoryBuffers @@ -330,6 +352,25 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { const gfx::Rect& visible_rect, const gfx::Size& natural_size); +#if defined(TIZEN_TBM_SUPPORT) + // Needed when we have video-frame content in tbm surface. + static scoped_refptr WrapTBMSurface(const gfx::Size& size, + base::TimeDelta timestamp, + gfx::TbmBufferHandle handle); + bool IsTBMBackend() const { return storage_type_ == STORAGE_TBM_SURFACE; } + unsigned GetTbmTexture() { return texture_id_; } + unsigned CreateTbmTextureIfNeeded(gpu::gles2::GLES2Interface* gl); + void ReleaseTbm(); + void SetTbmTexture(unsigned texture) { texture_id_ = texture; } + gfx::TbmBufferHandle GetTbmBuffer() { return buffer_handle_; } + unsigned GetImageID() { return image_id_; } + void SetImageID(unsigned image_id) { image_id_ = image_id; } + void SetContextProvider( + scoped_refptr context_provider) { + context_provider_ = context_provider; + } +#endif + // Creates a frame which indicates end-of-stream. static scoped_refptr CreateEOSFrame(); @@ -776,6 +817,16 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe { std::vector done_callbacks_; +#if defined(TIZEN_TBM_SUPPORT) + base::Lock tbm_lock_; + mutable base::Lock tbm_map_lock_; + gfx::TbmBufferHandle buffer_handle_; + unsigned texture_id_; + gpu::gles2::GLES2Interface* gl_; + unsigned image_id_; + scoped_refptr context_provider_; +#endif + base::TimeDelta timestamp_; base::Lock release_sync_token_lock_; diff --git a/media/base/video_frame_layout.cc b/media/base/video_frame_layout.cc index b3307c3..47bbbffa 100644 --- a/media/base/video_frame_layout.cc +++ b/media/base/video_frame_layout.cc @@ -85,6 +85,9 @@ size_t VideoFrameLayout::NumPlanes(VideoPixelFormat format) { case PIXEL_FORMAT_UNKNOWN: // Note: PIXEL_FORMAT_UNKNOWN is used for end-of-stream frame. // Set its NumPlanes() to zero to avoid NOTREACHED(). +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif return 0; } NOTREACHED() << "Unsupported video frame format: " << format; diff --git a/media/base/video_types.cc b/media/base/video_types.cc index ea148df..4edcc27 100644 --- a/media/base/video_types.cc +++ b/media/base/video_types.cc @@ -85,6 +85,10 @@ std::string VideoPixelFormatToString(VideoPixelFormat format) { return "PIXEL_FORMAT_YUV422AP10"; case PIXEL_FORMAT_YUV444AP10: return "PIXEL_FORMAT_YUV444AP10"; +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: + return "PIXEL_FORMAT_TBM_SURFACE"; +#endif } NOTREACHED() << "Invalid VideoPixelFormat provided: " << format; return ""; @@ -161,6 +165,9 @@ bool IsYuvPlanar(VideoPixelFormat format) { case PIXEL_FORMAT_XB30: case PIXEL_FORMAT_BGRA: case PIXEL_FORMAT_RGBAF16: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif return false; } return false; @@ -239,6 +246,9 @@ bool IsOpaque(VideoPixelFormat format) { case PIXEL_FORMAT_P016LE: case PIXEL_FORMAT_XR30: case PIXEL_FORMAT_XB30: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif return true; case PIXEL_FORMAT_I420A: case PIXEL_FORMAT_ARGB: @@ -258,6 +268,9 @@ bool IsOpaque(VideoPixelFormat format) { size_t BitDepth(VideoPixelFormat format) { switch (format) { case PIXEL_FORMAT_UNKNOWN: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif NOTREACHED(); [[fallthrough]]; case PIXEL_FORMAT_I420: diff --git a/media/base/video_types.h b/media/base/video_types.h index 7f44dbf..d7dad6d 100644 --- a/media/base/video_types.h +++ b/media/base/video_types.h @@ -88,9 +88,14 @@ enum VideoPixelFormat { PIXEL_FORMAT_YUV422AP10 = 37, PIXEL_FORMAT_YUV444AP10 = 38, - // Please update UMA histogram enumeration when adding new formats here. +// Please update UMA histogram enumeration when adding new formats here. +#if defined(TIZEN_TBM_SUPPORT) + PIXEL_FORMAT_TBM_SURFACE = 39, + PIXEL_FORMAT_MAX = PIXEL_FORMAT_TBM_SURFACE, +#else PIXEL_FORMAT_MAX = PIXEL_FORMAT_YUV444AP10, // Must always be equal to largest entry logged. +#endif }; // These values are persisted to logs. Entries should not be renumbered and diff --git a/media/capture/mojom/BUILD.gn b/media/capture/mojom/BUILD.gn index db44033..65cd420 100644 --- a/media/capture/mojom/BUILD.gn +++ b/media/capture/mojom/BUILD.gn @@ -4,6 +4,15 @@ import("//mojo/public/tools/bindings/mojom.gni") +if (use_aura) { + import("//tizen_src/build/config/tizen_features.gni") +} + +enabled_features = [] +if (tizen_tbm_support) { + enabled_features += [ "tizen_tbm_support" ] +} + mojom("video_capture") { generate_java = true sources = [ "video_capture.mojom" ] diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom index d8814af..e58304e 100644 --- a/media/capture/mojom/video_capture_types.mojom +++ b/media/capture/mojom/video_capture_types.mojom @@ -44,6 +44,9 @@ enum VideoCapturePixelFormat { [MinVersion=1] YUV420AP10, [MinVersion=1] YUV422AP10, [MinVersion=1] YUV444AP10, + + [EnableIf=tizen_tbm_support] + TBM_SURFACE, }; [Stable, Extensible] diff --git a/media/capture/mojom/video_capture_types_mojom_traits.cc b/media/capture/mojom/video_capture_types_mojom_traits.cc index 2dd7014..aa05fa7 100644 --- a/media/capture/mojom/video_capture_types_mojom_traits.cc +++ b/media/capture/mojom/video_capture_types_mojom_traits.cc @@ -159,6 +159,10 @@ EnumTraits (mojo_base.mojom.UnguessableToken request_token); + + [EnableIf=tizen_multimedia] + OnTbmBufferExhausted(gfx.mojom.TbmBufferHandle tbm_buffer_handle); }; // Extension of the mojo::RendererClient communication layer for media flinging, diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index ce72cf6..c2c53c0 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc @@ -982,6 +982,9 @@ void PaintCanvasVideoRenderer::Paint( if (!video_frame.get() || video_frame->natural_size().IsEmpty() || !(media::IsYuvPlanar(video_frame->format()) || video_frame->format() == PIXEL_FORMAT_Y16 || +#if defined(TIZEN_TBM_SUPPORT) + video_frame->IsTBMBackend() || +#endif video_frame->format() == PIXEL_FORMAT_ARGB || video_frame->format() == PIXEL_FORMAT_XRGB || video_frame->format() == PIXEL_FORMAT_ABGR || @@ -1873,7 +1876,11 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( // |video_frame| is software. // Holding |video_frame| longer than this call when using GPUVideoDecoder // could cause problems since the pool of VideoFrames has a fixed size. - if (video_frame->HasTextures()) { + if (video_frame->HasTextures() +#if defined(TIZEN_TBM_SUPPORT) + && !video_frame->IsTBMBackend() +#endif + ) { DCHECK(raster_context_provider); bool supports_oop_raster = raster_context_provider->ContextCapabilities().supports_oop_raster; @@ -2003,8 +2010,38 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( cc::PaintImage::GetNextContentId()); } else { cache_.emplace(video_frame->unique_id()); +#if defined(TIZEN_TBM_SUPPORT) + gpu::gles2::GLES2Interface* gl = raster_context_provider->ContextGL(); + unsigned source_texture = 0; + gl->GenTextures(1, &source_texture); + DCHECK(source_texture); + gl->BindTexture(GL_TEXTURE_2D, source_texture); + + CopyMailboxToTexture( + gl, video_frame->coded_size(), video_frame->visible_rect(), + video_frame->mailbox_holder(0).mailbox, + video_frame->mailbox_holder(0).sync_token, GL_TEXTURE_2D, + source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 0, false, false); + + GrGLTextureInfo source_texture_info; + source_texture_info.fID = source_texture; + source_texture_info.fTarget = GL_TEXTURE_2D; + source_texture_info.fFormat = GL_RGBA8_OES; + GrBackendTexture source_backend_texture( + video_frame->coded_size().width(), video_frame->coded_size().height(), + GrMipMapped::kNo, source_texture_info); + + paint_image_builder.set_image( + SkImage::MakeFromAdoptedTexture( + raster_context_provider->GrContext(), source_backend_texture, + kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, + kPremul_SkAlphaType, video_frame->ColorSpace().ToSkColorSpace()), + cc::PaintImage::GetNextContentId()); + +#else paint_image_builder.set_paint_image_generator( sk_make_sp(video_frame)); +#endif } cache_->paint_image = paint_image_builder.TakePaintImage(); diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index 7ded363..9b419ca 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc @@ -207,6 +207,9 @@ VideoFrameResourceType ExternalResourceTypeForHardwarePlanes( case PIXEL_FORMAT_YUV422AP10: case PIXEL_FORMAT_YUV444AP10: case PIXEL_FORMAT_UNKNOWN: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif break; } return VideoFrameResourceType::NONE; @@ -550,7 +553,16 @@ VideoResourceUpdater::~VideoResourceUpdater() { } void VideoResourceUpdater::ObtainFrameResources( - scoped_refptr video_frame) { + scoped_refptr video_frame, + viz::ResourceId external_resource_id) { +#if defined(TIZEN_TBM_SUPPORT) + if (video_frame->IsTBMBackend()) { + frame_resources_.emplace_back(external_resource_id, + video_frame->coded_size()); + frame_resource_type_ = VideoFrameResourceType::RGBA; + return; + } +#endif if (video_frame->metadata().overlay_plane_id.has_value()) { // This is a hole punching VideoFrame, there is nothing to display. overlay_plane_id_ = *video_frame->metadata().overlay_plane_id; diff --git a/media/renderers/video_resource_updater.h b/media/renderers/video_resource_updater.h index 9ada870..e3a0783 100644 --- a/media/renderers/video_resource_updater.h +++ b/media/renderers/video_resource_updater.h @@ -108,7 +108,9 @@ class MEDIA_EXPORT VideoResourceUpdater // 2. AppendQuads(): Add DrawQuads to CompositorFrame for video. // 3. ReleaseFrameResources(): After the CompositorFrame has been submitted, // remove imported resources from viz::ClientResourceProvider. - void ObtainFrameResources(scoped_refptr video_frame); + void ObtainFrameResources( + scoped_refptr video_frame, + viz::ResourceId resource_id = viz::kInvalidResourceId); void ReleaseFrameResources(); // Appends a quad representing |frame| to |render_pass|. // At most one quad is expected to be appended, this is enforced by the users diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 098650d..d402e0f 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc @@ -790,6 +790,9 @@ void GpuMemoryBufferVideoFramePool::PoolImpl::CreateHardwareFrame( case PIXEL_FORMAT_YUV422AP10: case PIXEL_FORMAT_YUV444AP10: case PIXEL_FORMAT_UNKNOWN: +#if defined(TIZEN_TBM_SUPPORT) + case PIXEL_FORMAT_TBM_SURFACE: +#endif if (is_software_backed_video_frame) { UMA_HISTOGRAM_ENUMERATION( "Media.GpuMemoryBufferVideoFramePool.UnsupportedFormat", diff --git a/services/viz/public/mojom/BUILD.gn b/services/viz/public/mojom/BUILD.gn index d0884a9..b71d563 100644 --- a/services/viz/public/mojom/BUILD.gn +++ b/services/viz/public/mojom/BUILD.gn @@ -3,6 +3,11 @@ # found in the LICENSE file. import("//build/config/chromeos/ui_mode.gni") import("//mojo/public/tools/bindings/mojom.gni") + +if (use_efl) { + import("//tizen_src/build/config/tizen_features.gni") +} + mojom("mojom") { generate_java = true sources = [ @@ -607,6 +612,11 @@ mojom("mojom") { ] }, ] + + enabled_features = [] + if (tizen_tbm_support) { + enabled_features += [ "tizen_tbm_support" ] + } } mojom("resource_format") { generate_java = true diff --git a/third_party/openscreen/src/cast/streaming/remoting.proto b/third_party/openscreen/src/cast/streaming/remoting.proto index 399c97b..af8bbfa 100644 --- a/third_party/openscreen/src/cast/streaming/remoting.proto +++ b/third_party/openscreen/src/cast/streaming/remoting.proto @@ -231,6 +231,7 @@ message VideoDecoderConfig { PIXEL_FORMAT_P016LE = 29; PIXEL_FORMAT_XR30 = 30; PIXEL_FORMAT_XB30 = 31; + PIXEL_FORMAT_TBM_SURFACE = 32; }; // Proto version of Chrome's media::ColorSpace. diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index eb89768..c8ad9c5 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -17,9 +17,6 @@ config("tizen_feature_flags") { defines += [ "EFL_BETA_API_SUPPORT" ] } } - if (tizen_tbm_support) { - defines += [ "TIZEN_TBM_SUPPORT" ] - } if (ewk_bringup) { defines += [ "EWK_BRINGUP" ] } @@ -33,6 +30,9 @@ config("tizen_feature_flags") { if (use_wayland) { defines += [ "USE_WAYLAND" ] } + if (tizen_tbm_support) { + defines += [ "TIZEN_TBM_SUPPORT" ] + } if (tizen_multimedia_support) { defines += [ "TIZEN_MULTIMEDIA_SUPPORT", diff --git a/tizen_src/build/gn_chromiumefl.sh b/tizen_src/build/gn_chromiumefl.sh index fd9662f..275bef8 100755 --- a/tizen_src/build/gn_chromiumefl.sh +++ b/tizen_src/build/gn_chromiumefl.sh @@ -222,7 +222,7 @@ add_tizen_flags() { ADDITIONAL_GN_PARAMETERS+="tizen_multimedia=true proprietary_codecs=true tizen_web_speech_recognition=true - tizen_tbm_support=false + tizen_tbm_support=true " } diff --git a/tizen_src/chromium_impl/content/browser/browser_efl.gni b/tizen_src/chromium_impl/content/browser/browser_efl.gni index 2586fa5..260330f 100644 --- a/tizen_src/chromium_impl/content/browser/browser_efl.gni +++ b/tizen_src/chromium_impl/content/browser/browser_efl.gni @@ -155,13 +155,6 @@ if (tizen_multimedia) { ] } -if (tizen_tbm_support) { - external_content_browser_efl_sources += [ - "//tizen_src/chromium_impl/content/browser/media/browser_mediapacket_manager.cc", - "//tizen_src/chromium_impl/content/browser/media/browser_mediapacket_manager.h", - ] -} - if (tizen_web_speech_recognition) { external_content_browser_efl_sources += [ "//tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.cc", diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc index 35b74aa..e5d1313 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc @@ -25,8 +25,24 @@ #include "tizen_src/chromium_impl/content/browser/media/media_player_renderer_web_contents_observer.h" #include "tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h" #include "tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h" +#include "tizen_src/chromium_impl/media/filters/media_player_registry.h" #include "tizen_src/chromium_impl/media/filters/media_player_tizen.h" +#if defined(TIZEN_TBM_SUPPORT) +namespace media { +void DestroyMediaPacket(void* media_packet, int player_id) { + MediaPlayerTizen* player = + MediaPlayerRegistry::GetInstance()->GetMediaPlayer(player_id); + if (!player) { + // TODO: All media packets should be removed before player is destroyed. + LOG(WARNING) << __func__ + << " player already destroyed. player_id: " << player_id; + return; + } + player->DestroyMediaPacket(media_packet); +} +} // namespace media +#endif namespace content { class TizenRendererImpl::RendererClientInternal final @@ -100,6 +116,14 @@ class TizenRendererImpl::RendererClientInternal final renderer_->OnBufferUpdate(time); } +#if defined(TIZEN_TBM_SUPPORT) + void OnNewTbmFrameAvailable(uint32_t player_id, + const gfx::TbmBufferHandle& tbm_handle, + base::TimeDelta timestamp) override { + DCHECK(type_ == media::DemuxerStream::VIDEO); + renderer_->OnNewTbmFrameAvailable(player_id, tbm_handle, timestamp); + } +#else void OnNewFrameAvailable(uint32_t playerId, base::UnsafeSharedMemoryRegion frame, uint32_t size, @@ -109,6 +133,7 @@ class TizenRendererImpl::RendererClientInternal final renderer_->OnNewFrameAvailable(playerId, std::move(frame), size, timestamp, width, height); } +#endif private: media::DemuxerStream::Type type_; @@ -242,11 +267,17 @@ void TizenRendererImpl::SetStreamInfo() { media::DemuxerStream::VIDEO, this); GetPlayer()->SetStreamInfo(media::DemuxerStream::VIDEO, video_stream_, video_renderer_client_.get()); - +#if defined(TIZEN_TBM_SUPPORT) + media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer() + ->SetFrameAvailableCallback( + base::BindRepeating(&TizenRendererImpl::OnNewTbmFrameAvailable, + base::Unretained(this))); +#else // Will be removed later by using |ClientExtention| interface. media::MediaPlayerESPlusPlayer::GetMediaPlayerESPlusPlayer() ->SetFrameAvailableCallback(base::BindRepeating( &TizenRendererImpl::OnNewFrameAvailable, base::Unretained(this))); +#endif } } @@ -451,4 +482,18 @@ void TizenRendererImpl::OnBufferUpdate(base::TimeDelta time) { client_extension_->OnBufferUpdate(time); } +#if defined(TIZEN_TBM_SUPPORT) +void TizenRendererImpl::OnNewTbmFrameAvailable(uint32_t player_id, + gfx::TbmBufferHandle tbm_handle, + base::TimeDelta timestamp) { + client_extension_->OnNewTbmFrameAvailable(player_id, tbm_handle, timestamp); +} + +void TizenRendererImpl::OnTbmBufferExhausted( + const gfx::TbmBufferHandle& tbm_handle) { + media_player_->DestroyMediaPacket( + reinterpret_cast(tbm_handle.media_packet)); +} +#endif + } // namespace content diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h index f7c469f..fbb96a8 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h @@ -98,6 +98,13 @@ class CONTENT_EXPORT TizenRendererImpl uint32_t width, uint32_t height); +#if defined(TIZEN_TBM_SUPPORT) + void OnNewTbmFrameAvailable(uint32_t player_id, + gfx::TbmBufferHandle tbm_handle, + base::TimeDelta timestamp); + void OnTbmBufferExhausted(const gfx::TbmBufferHandle& tbm_handle) override; +#endif + private: class RendererClientInternal; const float kDefaultVolume = 1.0; diff --git a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc index 4756451..0ae0b6c 100644 --- a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc +++ b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc @@ -134,4 +134,32 @@ void MediaPlayerRendererClient::OnBufferUpdate(base::TimeDelta time) { } #endif +#if defined(TIZEN_TBM_SUPPORT) +void MediaPlayerRendererClient::OnTbmBufferExhausted( + media::VideoFrame* video_frame, + void* media_packet, + int player_id) { + gfx::TbmBufferHandle tbm_handle; + tbm_handle.media_packet = reinterpret_cast(media_packet); + tbm_handle.player_id = player_id; + renderer_extension_remote_->OnTbmBufferExhausted(tbm_handle); +} + +void MediaPlayerRendererClient::OnNewTbmFrameAvailable( + uint32_t playerId, + const gfx::TbmBufferHandle& tbm_buffer_handle, + base::TimeDelta timestamp) { + gfx::Size size(tbm_buffer_handle.width, tbm_buffer_handle.height); + scoped_refptr video_frame = + media::VideoFrame::WrapTBMSurface(size, timestamp, tbm_buffer_handle); + video_frame->AddDestructionObserver(base::BindOnce( + &MediaPlayerRendererClient::OnTbmBufferExhausted, + weak_factory_.GetWeakPtr(), base::Unretained(video_frame.get()), + const_cast((const void*)tbm_buffer_handle.media_packet), + tbm_buffer_handle.player_id)); + + sink_->PaintSingleFrame(std::move(video_frame)); +} +#endif + } // namespace content diff --git a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h index 930fbb6..f601a44 100644 --- a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h +++ b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h @@ -23,6 +23,10 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#if defined(TIZEN_TBM_SUPPORT) +#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h" +#endif + namespace content { // MediaPlayerRendererClient lives in Renderer process and mirrors a @@ -69,6 +73,14 @@ class CONTENT_EXPORT MediaPlayerRendererClient base::TimeDelta timestamp, uint32_t width, uint32_t height) override; +#if defined(TIZEN_TBM_SUPPORT) + void OnNewTbmFrameAvailable(uint32_t playerId, + const gfx::TbmBufferHandle& tbm_buffer_handle, + base::TimeDelta timestamp) override; + void OnTbmBufferExhausted(media::VideoFrame* video_frame, + void* media_packet, + int player_id); +#endif private: void OnRemoteRendererInitialized(media::PipelineStatus status); diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.cc b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.cc index a122ed2..45e9b99 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.cc @@ -9,14 +9,21 @@ #include "base/logging.h" #include "media/base/renderer_client.h" #include "media/base/tizen/media_player_bridge_capi.h" +#include "tizen_src/chromium_impl/media/filters/media_player_registry.h" namespace media { MediaPlayerBridgeCapiAdapter::MediaPlayerBridgeCapiAdapter(const GURL& url, double volume) - : url_(url), volume_(volume) {} + : url_(url), volume_(volume) { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this); +} -MediaPlayerBridgeCapiAdapter::~MediaPlayerBridgeCapiAdapter() {} +MediaPlayerBridgeCapiAdapter::~MediaPlayerBridgeCapiAdapter() { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + MediaPlayerRegistry::GetInstance()->UnregisterMediaPlayer(player_id_); +} bool MediaPlayerBridgeCapiAdapter::CreatePlayer() { if (media_player_) @@ -193,7 +200,7 @@ void MediaPlayerBridgeCapiAdapter::OnNewTbmBufferAvailable( void* media_packet = reinterpret_cast(tbm_handle.media_packet); tbm_handle.media_packet = reinterpret_cast(media_packet); - tbm_handle.player_handle = reinterpret_cast(this); + tbm_handle.player_id = player_id_; tbm_handle.width = width_; tbm_handle.height = height_; diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h index 3b348fe..26df8d0 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h @@ -112,6 +112,8 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiAdapter : public MediaPlayerTizen, bool is_initialized_ = false; bool is_prepared_ = false; + int player_id_ = 0; + int width_ = 0; int height_ = 0; }; diff --git a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc index b5f83e3..baab703 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc @@ -14,6 +14,7 @@ #include "media/base/decoder_buffer.h" #include "media/base/renderer_client.h" #include "third_party/libyuv/include/libyuv/convert.h" +#include "tizen_src/chromium_impl/media/filters/media_player_registry.h" namespace media { using player_buffer_size_t = unsigned long long; @@ -125,6 +126,8 @@ MediaPlayerESPlusPlayer::~MediaPlayerESPlusPlayer() { LOG(INFO) << "(" << static_cast(this) << ") " << __func__; weak_factory_.InvalidateWeakPtrs(); + MediaPlayerRegistry::GetInstance()->UnregisterMediaPlayer(player_id_); + int error = esplusplayer_destroy(esplayer_); if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) LOG(ERROR) << "esplusplayer_destroy failed, error #" @@ -181,6 +184,8 @@ void MediaPlayerESPlusPlayer::Initialize(VideoRendererSink* sink) { return; } + player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this); + LOG(INFO) << "(" << static_cast(this) << ") " << __func__ << " state:" << GetString(GetPlayerState()); @@ -506,6 +511,20 @@ base::TimeDelta MediaPlayerESPlusPlayer::GetCurrentTime() { return current_position_; } +#if defined(TIZEN_TBM_SUPPORT) +void MediaPlayerESPlusPlayer::DestroyMediaPacket(void* media_packet) { + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::DestroyMediaPacket, + weak_factory_.GetWeakPtr(), media_packet)); + return; + } + + esplusplayer_decoded_buffer_destroy( + esplayer_, static_cast(media_packet)); +} +#endif + esplusplayer_state MediaPlayerESPlusPlayer::GetPlayerState() { return (esplayer_ ? esplusplayer_get_state(esplayer_) : ESPLUSPLAYER_STATE_NONE); @@ -911,6 +930,15 @@ void MediaPlayerESPlusPlayer::OnFrameReady( << ", duration:" << packet->duration << ", Player(" << esplayer_ << ", state:" << GetString(GetPlayerState()); +#if defined(TIZEN_TBM_SUPPORT) + gfx::TbmBufferHandle tbm_handle; + tbm_handle.tbm_surface = reinterpret_cast(tbm_surface); + tbm_handle.media_packet = reinterpret_cast(packet); + tbm_handle.player_id = player_id_; + tbm_handle.width = width; + tbm_handle.height = height; + data_cb_.Run(0, tbm_handle, timestamp); +#else base::UnsafeSharedMemoryRegion shared_memory; uint32_t shared_memory_size = suf_info.planes[0].size + (suf_info.planes[0].size / 2); @@ -994,6 +1022,7 @@ void MediaPlayerESPlusPlayer::OnFrameReady( sink_->PaintSingleFrame(video_frame); } +#endif } void MediaPlayerESPlusPlayer::OnFlushComplete() { diff --git a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h index a557153..3992847 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h +++ b/tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h @@ -31,6 +31,10 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen { public: static MediaPlayerESPlusPlayer* GetMediaPlayerESPlusPlayer(); +#if defined(TIZEN_TBM_SUPPORT) + using DataRequestCB = base::RepeatingCallback< + void(uint32_t, gfx::TbmBufferHandle, base::TimeDelta)>; +#else using DataRequestCB = base::RepeatingCallback; +#endif + bool CreatePlayer() override; void Initialize(VideoRendererSink* sink) override; bool IsInitialized() override; @@ -65,6 +71,10 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen { void SetFrameAvailableCallback(const DataRequestCB& datacb) override; +#if defined(TIZEN_TBM_SUPPORT) + void DestroyMediaPacket(void* media_packet) override; +#endif + // Callback handler void OnReadyToPrepare(const esplusplayer_stream_type stream_type); void OnPrepareComplete(bool result); @@ -157,6 +167,9 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen { bool should_set_playback_rate_ = false; base::OnceClosure flush_cb_; + + int player_id_ = 0; + DataRequestCB data_cb_; VideoRendererSink* sink_; diff --git a/tizen_src/chromium_impl/media/filters/media_player_registry.cc b/tizen_src/chromium_impl/media/filters/media_player_registry.cc new file mode 100644 index 0000000..0f21b49 --- /dev/null +++ b/tizen_src/chromium_impl/media/filters/media_player_registry.cc @@ -0,0 +1,41 @@ +// Copyright 2022 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tizen_src/chromium_impl/media/filters/media_player_registry.h" + +#include "base/logging.h" +#include "base/process/process_handle.h" + +namespace media { + +MediaPlayerRegistry* MediaPlayerRegistry::GetInstance() { + return base::Singleton::get(); +} + +MediaPlayerRegistry::MediaPlayerRegistry() { + next_media_player_id_ = base::GetCurrentProcId(); +} + +MediaPlayerRegistry::~MediaPlayerRegistry() {} + +int MediaPlayerRegistry::RegisterMediaPlayer(MediaPlayerTizen* player) { + LOG(INFO) << __func__ << " player id: " << next_media_player_id_; + media_players_[next_media_player_id_] = player; + return next_media_player_id_++; +} + +void MediaPlayerRegistry::UnregisterMediaPlayer(int player_id) { + LOG(INFO) << __func__ << " player id: " << player_id; + media_players_.erase(player_id); +} + +MediaPlayerTizen* MediaPlayerRegistry::GetMediaPlayer(int player_id) { + std::map::iterator iter = + media_players_.find(player_id); + if (iter != media_players_.end()) + return iter->second; + return nullptr; +} + +} // namespace media diff --git a/tizen_src/chromium_impl/media/filters/media_player_registry.h b/tizen_src/chromium_impl/media/filters/media_player_registry.h new file mode 100644 index 0000000..0576fba --- /dev/null +++ b/tizen_src/chromium_impl/media/filters/media_player_registry.h @@ -0,0 +1,42 @@ +// Copyright 2022 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_FILTERS_MEDIA_PLAYER_REGISTRY_H_ +#define MEDIA_FILTERS_MEDIA_PLAYER_REGISTRY_H_ + +#include + +#include "base/memory/singleton.h" +#include "media/base/media_export.h" + +namespace media { + +class MediaPlayerTizen; + +class MEDIA_EXPORT MediaPlayerRegistry { + public: + static MediaPlayerRegistry* GetInstance(); + + int RegisterMediaPlayer(MediaPlayerTizen* player); + void UnregisterMediaPlayer(int player_id); + + MediaPlayerTizen* GetMediaPlayer(int player_id); + + private: + MediaPlayerRegistry(); + ~MediaPlayerRegistry(); + + MediaPlayerRegistry(const MediaPlayerRegistry&) = delete; + MediaPlayerRegistry& operator=(const MediaPlayerRegistry&) = delete; + + int next_media_player_id_; + + std::map media_players_; + + friend struct base::DefaultSingletonTraits; +}; + +} // namespace media + +#endif // MEDIA_FILTERS_MEDIA_PLAYER_REGISTRY_H_ diff --git a/tizen_src/chromium_impl/media/media_efl.gni b/tizen_src/chromium_impl/media/media_efl.gni index e158e8a..ff1ba71 100644 --- a/tizen_src/chromium_impl/media/media_efl.gni +++ b/tizen_src/chromium_impl/media/media_efl.gni @@ -104,6 +104,8 @@ if (tizen_multimedia) { "//tizen_src/chromium_impl/media/filters/media_player_bridge_capi_adapter.h", "//tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc", "//tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h", + "//tizen_src/chromium_impl/media/filters/media_player_registry.cc", + "//tizen_src/chromium_impl/media/filters/media_player_registry.h", "//tizen_src/chromium_impl/media/filters/media_player_tizen.h", ] diff --git a/tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h b/tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h new file mode 100644 index 0000000..4e82dcd --- /dev/null +++ b/tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h @@ -0,0 +1,35 @@ +// Copyright 2014 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_TBM_BUFFER_HANDLE_H +#define UI_GFX_TBM_BUFFER_HANDLE_H + +#include +#include "ui/gfx/gfx_export.h" + +#if defined(TIZEN_TBM_SUPPORT) +#include +#include +#include +#endif + +namespace gfx { + +struct GFX_EXPORT TbmBufferHandle { + TbmBufferHandle() {} +#if defined(TIZEN_TBM_SUPPORT) + uint32_t tbm_surface{0}; + uint32_t media_packet{0}; + int32_t player_id = 0; + int32_t key_num = 0; + int32_t key[4]; + int32_t strides[4]; + int32_t width = 0; + int32_t height = 0; +#endif +}; + +} // namespace gfx + +#endif diff --git a/tizen_src/chromium_impl/ui/ui_efl.gni b/tizen_src/chromium_impl/ui/ui_efl.gni index bb54b8b..3f2beaa 100644 --- a/tizen_src/chromium_impl/ui/ui_efl.gni +++ b/tizen_src/chromium_impl/ui/ui_efl.gni @@ -62,6 +62,7 @@ external_ui_gfx_sources = [ "//tizen_src/chromium_impl/ui/display/device_display_info_efl.cc", "//tizen_src/chromium_impl/ui/display/device_display_info_efl.h", "//tizen_src/chromium_impl/ui/display/device_display_info_observer_efl.h", + "//tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h", ] # For //ui/gfx/x target diff --git a/ui/gfx/gpu_memory_buffer.h b/ui/gfx/gpu_memory_buffer.h index 8ad8af9..13b77ba 100644 --- a/ui/gfx/gpu_memory_buffer.h +++ b/ui/gfx/gpu_memory_buffer.h @@ -85,6 +85,16 @@ struct GFX_EXPORT GpuMemoryBufferHandle { #elif BUILDFLAG(IS_ANDROID) base::android::ScopedHardwareBufferHandle android_hardware_buffer; #endif +#if defined(TIZEN_TBM_SUPPORT) + uint32_t tbm_surface{0}; + uint32_t media_packet{0}; + int32_t player_id = 0; + int32_t key_num = 0; + int32_t key[4]; + int32_t strides[4]; + int32_t width = 0; + int32_t height = 0; +#endif }; // This interface typically correspond to a type of shared memory that is also diff --git a/ui/gfx/mojom/BUILD.gn b/ui/gfx/mojom/BUILD.gn index 3c8d0eb..91a2f6e 100644 --- a/ui/gfx/mojom/BUILD.gn +++ b/ui/gfx/mojom/BUILD.gn @@ -4,6 +4,9 @@ import("//build/config/ozone.gni") import("//mojo/public/tools/bindings/mojom.gni") +if (use_efl) { + import("//tizen_src/build/config/tizen_features.gni") +} mojom("mojom") { generate_java = true @@ -49,6 +52,9 @@ mojom("mojom") { if (ozone_platform_x11) { enabled_features += [ "enable_x11_params" ] } + if (tizen_tbm_support) { + enabled_features += [ "tizen_tbm_support" ] + } shared_cpp_typemaps = [ { @@ -84,6 +90,10 @@ mojom("mojom") { mojom = "gfx.mojom.GpuMemoryBufferType" cpp = "::gfx::GpuMemoryBufferType" }, + { + mojom = "gfx.mojom.TbmBufferHandle" + cpp = "::gfx::TbmBufferHandle" + }, ] traits_headers = [ "buffer_types_mojom_traits.h" ] diff --git a/ui/gfx/mojom/buffer_types.mojom b/ui/gfx/mojom/buffer_types.mojom index 4fa5ca2..4e989d4 100644 --- a/ui/gfx/mojom/buffer_types.mojom +++ b/ui/gfx/mojom/buffer_types.mojom @@ -65,5 +65,57 @@ struct GpuMemoryBufferHandle { GpuMemoryBufferId id; uint32 offset; uint32 stride; + + [EnableIf=tizen_tbm_support] + uint32 tbm_surface; + + [EnableIf=tizen_tbm_support] + uint32 media_packet; + + [EnableIf=tizen_tbm_support] + int32 player_id; + + [EnableIf=tizen_tbm_support] + int32 key_num; + + [EnableIf=tizen_tbm_support] + array key; + + [EnableIf=tizen_tbm_support] + array strides; + + [EnableIf=tizen_tbm_support] + int32 width; + + [EnableIf=tizen_tbm_support] + int32 height; + GpuMemoryBufferPlatformHandle? platform_handle; }; + +// gfx::TbmBufferHandle +struct TbmBufferHandle { + [EnableIf=tizen_tbm_support] + uint32 tbm_surface; + + [EnableIf=tizen_tbm_support] + uint32 media_packet; + + [EnableIf=tizen_tbm_support] + int32 player_id; + + [EnableIf=tizen_tbm_support] + int32 key_num; + + [EnableIf=tizen_tbm_support] + array key; + + [EnableIf=tizen_tbm_support] + array strides; + + [EnableIf=tizen_tbm_support] + int32 width; + + [EnableIf=tizen_tbm_support] + int32 height; +}; diff --git a/ui/gfx/mojom/buffer_types_mojom_traits.cc b/ui/gfx/mojom/buffer_types_mojom_traits.cc index 0f6ffe1..9b7d0e4 100644 --- a/ui/gfx/mojom/buffer_types_mojom_traits.cc +++ b/ui/gfx/mojom/buffer_types_mojom_traits.cc @@ -98,7 +98,21 @@ bool StructTraitsoffset = data.offset(); out->stride = data.stride(); +#if defined(TIZEN_TBM_SUPPORT) + out->tbm_surface = data.tbm_surface(); + out->media_packet = data.media_packet(); + out->player_id = data.player_id(); + out->key_num = data.key_num(); + out->width = data.width(); + out->height = data.height(); + base::span key(out->key); + if (!data.ReadKey(&key)) + return false; + base::span strides(out->strides); + if (!data.ReadStrides(&strides)) + return false; +#endif gfx::mojom::GpuMemoryBufferPlatformHandlePtr platform_handle; if (!data.ReadPlatformHandle(&platform_handle)) { return false; @@ -168,4 +182,53 @@ bool StructTraits StructTraits< + gfx::mojom::GpuMemoryBufferHandleDataView, + gfx::GpuMemoryBufferHandle>::key(const gfx::GpuMemoryBufferHandle& input) { + return input.key; +} + +// static +base::span StructTraits< + gfx::mojom::GpuMemoryBufferHandleDataView, + gfx::GpuMemoryBufferHandle>::strides(const gfx::GpuMemoryBufferHandle& + input) { + return input.strides; +} + +bool StructTraits:: + Read(gfx::mojom::TbmBufferHandleDataView data, gfx::TbmBufferHandle* out) { + out->tbm_surface = data.tbm_surface(); + out->media_packet = data.media_packet(); + out->player_id = data.player_id(); + out->key_num = data.key_num(); + out->width = data.width(); + out->height = data.height(); + base::span key(out->key); + if (!data.ReadKey(&key)) + return false; + + base::span strides(out->strides); + if (!data.ReadStrides(&strides)) + return false; + return true; +} + +// static +base::span +StructTraits::key( + const gfx::TbmBufferHandle& input) { + return input.key; +} + +// static +base::span +StructTraits::strides(const gfx::TbmBufferHandle& input) { + return input.strides; +} +#endif + } // namespace mojo diff --git a/ui/gfx/mojom/buffer_types_mojom_traits.h b/ui/gfx/mojom/buffer_types_mojom_traits.h index fc160f3..0f62f6c 100644 --- a/ui/gfx/mojom/buffer_types_mojom_traits.h +++ b/ui/gfx/mojom/buffer_types_mojom_traits.h @@ -16,6 +16,10 @@ #include "ui/gfx/mojom/buffer_types.mojom-shared.h" #include "ui/gfx/mojom/native_handle_types.mojom.h" +#if defined(TIZEN_TBM_SUPPORT) +#include "tizen_src/chromium_impl/ui/gfx/tbm_buffer_handle.h" +#endif + namespace mojo { template <> @@ -233,6 +237,31 @@ struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS) static uint32_t stride(const gfx::GpuMemoryBufferHandle& handle) { return handle.stride; } +#if defined(TIZEN_TBM_SUPPORT) + static uint32_t tbm_surface(const gfx::GpuMemoryBufferHandle& handle) { + return handle.tbm_surface; + } + static uint32_t media_packet(const gfx::GpuMemoryBufferHandle& handle) { + return handle.media_packet; + } + static int32_t player_id(const gfx::GpuMemoryBufferHandle& handle) { + return handle.player_id; + } + + static int32_t key_num(const gfx::GpuMemoryBufferHandle& handle) { + return handle.key_num; + } + static base::span key(const gfx::GpuMemoryBufferHandle& input); + static base::span strides( + const gfx::GpuMemoryBufferHandle& input); + + static int32_t width(const gfx::GpuMemoryBufferHandle& handle) { + return handle.width; + } + static int32_t height(const gfx::GpuMemoryBufferHandle& handle) { + return handle.height; + } +#endif static mojo::StructPtr platform_handle(gfx::GpuMemoryBufferHandle& handle); @@ -240,6 +269,38 @@ struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS) gfx::GpuMemoryBufferHandle* handle); }; +#if defined(TIZEN_TBM_SUPPORT) +template <> +struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS) + StructTraits { + static uint32_t tbm_surface(const gfx::TbmBufferHandle& handle) { + return handle.tbm_surface; + } + static uint32_t media_packet(const gfx::TbmBufferHandle& handle) { + return handle.media_packet; + } + static int32_t player_id(const gfx::TbmBufferHandle& handle) { + return handle.player_id; + } + + static int32_t key_num(const gfx::TbmBufferHandle& handle) { + return handle.key_num; + } + static base::span key(const gfx::TbmBufferHandle& input); + static base::span strides(const gfx::TbmBufferHandle& input); + + static int32_t width(const gfx::TbmBufferHandle& handle) { + return handle.width; + } + static int32_t height(const gfx::TbmBufferHandle& handle) { + return handle.height; + } + + static bool Read(gfx::mojom::TbmBufferHandleDataView data, + gfx::TbmBufferHandle* handle); +}; +#endif + template <> struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS) EnumTraits { diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc index 84635e5..d72f414 100644 --- a/ui/gl/gl_image_egl.cc +++ b/ui/gl/gl_image_egl.cc @@ -9,6 +9,12 @@ #include "ui/gl/gl_enums.h" #include "ui/gl/gl_surface_egl.h" +#if defined(TIZEN_TBM_SUPPORT) +namespace media { +void DestroyMediaPacket(void* media_packet_handle, int player_id); +} +#endif + namespace gl { GLImageEGL::GLImageEGL(const gfx::Size& size) @@ -23,6 +29,10 @@ GLImageEGL::~GLImageEGL() { GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(), egl_image_); if (result == EGL_FALSE) DLOG(ERROR) << "Error destroying EGLImage: " << ui::GetLastEGLErrorString(); + +#if defined(TIZEN_TBM_SUPPORT) + media::DestroyMediaPacket(media_packet_, player_id_); +#endif } bool GLImageEGL::Initialize(EGLContext context, @@ -39,6 +49,29 @@ bool GLImageEGL::Initialize(EGLContext context, return success; } +#if defined(TIZEN_TBM_SUPPORT) +bool GLImageEGL::Initialize(EGLenum target, + EGLClientBuffer buffer, + const EGLint* attrs, + void* media_packet, + int player_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); + media_packet_ = media_packet; + player_id_ = player_id; + + egl_image_ = eglCreateImageKHR(GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(), + EGL_NO_CONTEXT, target, buffer, attrs); + if (egl_image_ == EGL_NO_IMAGE_KHR) { + DLOG(ERROR) << "Error creating EGLImage: " << ui::GetLastEGLErrorString(); + media::DestroyMediaPacket(media_packet_, player_id_); + return false; + } + + return true; +} +#endif + gfx::Size GLImageEGL::GetSize() { return size_; } diff --git a/ui/gl/gl_image_egl.h b/ui/gl/gl_image_egl.h index 0afd7d4..d46ae79 100644 --- a/ui/gl/gl_image_egl.h +++ b/ui/gl/gl_image_egl.h @@ -18,6 +18,13 @@ namespace gl { class GL_EXPORT GLImageEGL : public GLImage { public: explicit GLImageEGL(const gfx::Size& size); +#if defined(TIZEN_TBM_SUPPORT) + bool Initialize(unsigned target, + void* buffer, + const EGLint* attrs, + void* media_packet, + int player_id); +#endif GLImageEGL(const GLImageEGL&) = delete; GLImageEGL& operator=(const GLImageEGL&) = delete; @@ -47,6 +54,10 @@ class GL_EXPORT GLImageEGL : public GLImage { const EGLint* attrs); raw_ptr egl_image_ /* EGLImageKHR */; +#if defined(TIZEN_TBM_SUPPORT) + void* media_packet_; + int player_id_; +#endif const gfx::Size size_; base::ThreadChecker thread_checker_; }; diff --git a/ui/gl/gl_image_native_pixmap.cc b/ui/gl/gl_image_native_pixmap.cc index e48a7d5..72b5fca 100644 --- a/ui/gl/gl_image_native_pixmap.cc +++ b/ui/gl/gl_image_native_pixmap.cc @@ -17,6 +17,11 @@ #include "ui/gl/gl_enums.h" #include "ui/gl/gl_surface_egl.h" +#if defined(TIZEN_TBM_SUPPORT) +#include "ui/gfx/gpu_memory_buffer.h" +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 +#endif + #define FOURCC(a, b, c, d) \ ((static_cast(a)) | (static_cast(b) << 8) | \ (static_cast(c) << 16) | (static_cast(d) << 24)) @@ -138,6 +143,21 @@ GLImageNativePixmap::GLImageNativePixmap(const gfx::Size& size, GLImageNativePixmap::~GLImageNativePixmap() {} +#if defined(TIZEN_TBM_SUPPORT) +bool GLImageNativePixmap::Initialize(const gfx::GpuMemoryBufferHandle& handle) { + EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; + tbm_surface_h surface = reinterpret_cast(handle.tbm_surface); + if (!GLImageEGL::Initialize(EGL_NATIVE_SURFACE_TIZEN, + static_cast(surface), attrs, + reinterpret_cast(handle.media_packet), + handle.player_id)) { + return false; + } + + return true; +} +#endif + bool GLImageNativePixmap::Initialize(scoped_refptr pixmap) { DCHECK(!pixmap_); if (GLInternalFormat(format_) == GL_NONE) { diff --git a/ui/gl/gl_image_native_pixmap.h b/ui/gl/gl_image_native_pixmap.h index ea5c883..fbe3dfc9 100644 --- a/ui/gl/gl_image_native_pixmap.h +++ b/ui/gl/gl_image_native_pixmap.h @@ -13,6 +13,15 @@ #include "ui/gl/gl_export.h" #include "ui/gl/gl_image_egl.h" +#if defined(TIZEN_TBM_SUPPORT) +#include +#include +#include +namespace gfx { +struct GpuMemoryBufferHandle; +} +#endif + namespace gl { class GL_EXPORT GLImageNativePixmap : public gl::GLImageEGL { @@ -21,6 +30,9 @@ class GL_EXPORT GLImageNativePixmap : public gl::GLImageEGL { gfx::BufferFormat format, gfx::BufferPlane plane = gfx::BufferPlane::DEFAULT); +#if defined(TIZEN_TBM_SUPPORT) + bool Initialize(const gfx::GpuMemoryBufferHandle& handle); +#endif // Create an EGLImage from a given NativePixmap. bool Initialize(scoped_refptr pixmap); bool InitializeForOverlay(scoped_refptr pixmap); @@ -53,6 +65,12 @@ class GL_EXPORT GLImageNativePixmap : public gl::GLImageEGL { bool has_image_flush_external_; bool has_image_dma_buf_export_; bool did_initialize_; +#if defined(TIZEN_TBM_SUPPORT) + tbm_bufmgr bufmgr_; + tbm_surface_h tbm_surf_; + tbm_bo bos_[4] = {0}; + tbm_surface_info_s tbmsi_; +#endif }; } // namespace gl -- 2.7.4 From 075464657be3de22a8af1fa73df9b24887dbc620 Mon Sep 17 00:00:00 2001 From: Gajendra N Date: Fri, 27 Jan 2023 11:53:38 +0530 Subject: [PATCH 12/16] [M108 Migration][SAM] Migrate SAM score improvement patches Improves MCD Score from 2.08 to 3.33. Reduces LOC for WebContentsDelegateEfl by ~280 lines. Reduces LOC for ContentBrowserClientEfl by ~85 lines. References: https://review.tizen.org/gerrit/275891 https://review.tizen.org/gerrit/275576 https://review.tizen.org/gerrit/275660 https://review.tizen.org/gerrit/276084 Change-Id: Ic034b902c7ccf9d74c100641aadbf604763c5f95 Signed-off-by: Gajendra N --- tizen_src/ewk/efl_integration/BUILD.gn | 14 +- .../{ => browser}/autofill_popup_view_efl.cc | 0 .../{ => browser}/autofill_popup_view_efl.h | 0 .../notification/notification_controller_efl.cc | 1 + .../browser/policy_response_delegate_efl.cc | 3 +- .../browser/web_view_browser_message_filter.cc | 1 + .../ewk/efl_integration/browser_context_efl.h | 2 +- .../efl_integration/content_browser_client_efl.cc | 257 +++++++++-------- .../efl_integration/content_browser_client_efl.h | 82 +++--- .../efl_integration/context_menu_controller_efl.cc | 3 + .../{browser => }/download_manager_delegate_efl.cc | 2 +- .../{browser => }/download_manager_delegate_efl.h | 0 tizen_src/ewk/efl_integration/eweb_view.cc | 2 + tizen_src/ewk/efl_integration/eweb_view.h | 2 +- .../{browser => }/login_delegate_efl.cc | 0 .../{browser => }/login_delegate_efl.h | 0 .../private/ewk_auth_challenge_private.h | 2 +- .../ewk_context_form_autofill_profile_private.cc | 1 + .../efl_integration/web_contents_delegate_efl.cc | 276 +----------------- .../efl_integration/web_contents_delegate_efl.h | 137 +++------ .../efl_integration/web_contents_observer_efl.cc | 318 +++++++++++++++++++++ .../efl_integration/web_contents_observer_efl.h | 99 +++++++ 22 files changed, 652 insertions(+), 550 deletions(-) rename tizen_src/ewk/efl_integration/{ => browser}/autofill_popup_view_efl.cc (100%) rename tizen_src/ewk/efl_integration/{ => browser}/autofill_popup_view_efl.h (100%) rename tizen_src/ewk/efl_integration/{browser => }/download_manager_delegate_efl.cc (98%) rename tizen_src/ewk/efl_integration/{browser => }/download_manager_delegate_efl.h (100%) rename tizen_src/ewk/efl_integration/{browser => }/login_delegate_efl.cc (100%) rename tizen_src/ewk/efl_integration/{browser => }/login_delegate_efl.h (100%) create mode 100644 tizen_src/ewk/efl_integration/web_contents_observer_efl.cc create mode 100644 tizen_src/ewk/efl_integration/web_contents_observer_efl.h diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index bfbb46a..feee814 100755 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -185,21 +185,17 @@ shared_library("chromium-ewk") { sources = [ "authentication_challenge_popup.cc", "authentication_challenge_popup.h", - "autofill_popup_view_efl.cc", - "autofill_popup_view_efl.h", + "browser/autofill_popup_view_efl.cc", + "browser/autofill_popup_view_efl.h", "browser/background_sync_controller_efl.cc", "browser/background_sync_controller_efl.h", "browser/browsing_data_remover_efl.cc", "browser/browsing_data_remover_efl.h", - "browser/download_manager_delegate_efl.cc", - "browser/download_manager_delegate_efl.h", "browser/intercept_request_params.h", "browser/javascript_dialog_manager_efl.cc", "browser/javascript_dialog_manager_efl.h", "browser/javascript_modal_dialog_efl.cc", "browser/javascript_modal_dialog_efl.h", - "browser/login_delegate_efl.cc", - "browser/login_delegate_efl.h", "browser/mime_override_manager_efl.cc", "browser/mime_override_manager_efl.h", "browser/navigation_policy_handler_efl.cc", @@ -245,6 +241,8 @@ shared_library("chromium-ewk") { "devtools_delegate_efl.h", "devtools_manager_delegate_efl.cc", "devtools_manager_delegate_efl.h", + "download_manager_delegate_efl.cc", + "download_manager_delegate_efl.h", "efl_webprocess_main.cc", "efl_webprocess_main.h", "eweb_context.cc", @@ -260,6 +258,8 @@ shared_library("chromium-ewk") { "http_user_agent_settings_efl.h", "locale_efl.cc", "locale_efl.h", + "login_delegate_efl.cc", + "login_delegate_efl.h", "network_delegate_efl.cc", "network_delegate_efl.h", "notification_permission_popup.cc", @@ -578,6 +578,8 @@ shared_library("chromium-ewk") { "renderer/render_thread_observer_efl.h", "renderer/tizen_extensible.cc", "renderer/tizen_extensible.h", + "web_contents_observer_efl.cc", + "web_contents_observer_efl.h", "wrt/dynamicplugin.cc", "wrt/dynamicplugin.h", "wrt/v8widget.cc", diff --git a/tizen_src/ewk/efl_integration/autofill_popup_view_efl.cc b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc similarity index 100% rename from tizen_src/ewk/efl_integration/autofill_popup_view_efl.cc rename to tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc diff --git a/tizen_src/ewk/efl_integration/autofill_popup_view_efl.h b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h similarity index 100% rename from tizen_src/ewk/efl_integration/autofill_popup_view_efl.h rename to tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h diff --git a/tizen_src/ewk/efl_integration/browser/notification/notification_controller_efl.cc b/tizen_src/ewk/efl_integration/browser/notification/notification_controller_efl.cc index fedc587..f88b03c 100644 --- a/tizen_src/ewk/efl_integration/browser/notification/notification_controller_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/notification/notification_controller_efl.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "browser_context_efl.h" #include "common/web_contents_utils.h" #include "content/common/paths_efl.h" #include "content/public/browser/browser_thread.h" diff --git a/tizen_src/ewk/efl_integration/browser/policy_response_delegate_efl.cc b/tizen_src/ewk/efl_integration/browser/policy_response_delegate_efl.cc index 0378c0d..bf8ea0f 100644 --- a/tizen_src/ewk/efl_integration/browser/policy_response_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/policy_response_delegate_efl.cc @@ -10,6 +10,7 @@ #include "browser/mime_override_manager_efl.h" #include "browser/network_service/browser_url_loader_throttle_efl.h" #include "browser/policy_response_params.h" +#include "browser_context_efl.h" #include "common/web_contents_utils.h" #include "content/public/browser/render_frame_host.h" #include "eweb_view.h" @@ -17,7 +18,7 @@ #include "private/ewk_policy_decision_private.h" #include "services/network/public/cpp/data_element.h" #include "services/network/public/cpp/features.h" -#include "services/network/public/mojom/url_response_head.mojom-forward.h" +#include "services/network/public/mojom/url_response_head.mojom.h" using web_contents_utils::WebViewFromWebContents; diff --git a/tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc b/tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc index 3dc018f..7850c2e 100644 --- a/tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc +++ b/tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc @@ -14,6 +14,7 @@ #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "eweb_view.h" #include "ipc_message_start_ewk.h" diff --git a/tizen_src/ewk/efl_integration/browser_context_efl.h b/tizen_src/ewk/efl_integration/browser_context_efl.h index 1f88ac0..bef9a1e 100644 --- a/tizen_src/ewk/efl_integration/browser_context_efl.h +++ b/tizen_src/ewk/efl_integration/browser_context_efl.h @@ -9,7 +9,6 @@ #include "base/files/scoped_temp_dir.h" #include "base/synchronization/lock.h" -#include "browser/download_manager_delegate_efl.h" #include "browser/geolocation/geolocation_permission_context_efl.h" #include "browser/ssl_host_state_delegate_efl.h" #include "components/visitedlink/browser/visitedlink_delegate.h" @@ -17,6 +16,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/storage_partition.h" +#include "download_manager_delegate_efl.h" #include "url_request_context_getter_efl.h" class CookieManager; diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc index 23882ee..837b144 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc @@ -14,6 +14,7 @@ #include "browser/quota_permission_context_efl.h" #include "browser/render_message_filter_efl.h" #include "browser/web_view_browser_message_filter.h" +#include "browser_context_efl.h" #include "browser_main_parts_efl.h" #include "command_line_efl.h" #include "common/content_switches_efl.h" @@ -23,6 +24,8 @@ #include "components/error_page/common/localized_error.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/web_contents.h" @@ -76,43 +79,8 @@ void PlatformLanguageChanged(keynode_t* keynode, void* data) { } #endif // BUILDFLAG(IS_TIZEN) -} // namespace - -ContentBrowserClientEfl::ContentBrowserClientEfl() - : browser_main_parts_efl_(nullptr), - notification_controller_(new NotificationControllerEfl), - accept_langs_(kDefaultAcceptLanguages) { -#if BUILDFLAG(IS_TIZEN) - PlatformLanguageChanged(nullptr, this); - vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, this); -#endif -} - -ContentBrowserClientEfl::~ContentBrowserClientEfl() { -#if BUILDFLAG(IS_TIZEN) - vconf_ignore_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged); -#endif -} - -void ContentBrowserClientEfl::SetBrowserContext(BrowserContext* context) { - browser_context_.reset(context); -} - -void ContentBrowserClientEfl::CleanUpBrowserContext() { - browser_context_.reset(nullptr); - shutting_down_ = true; -} - -std::unique_ptr -ContentBrowserClientEfl::CreateBrowserMainParts(bool is_integration_test) { - auto browser_main_parts = std::make_unique(); - browser_main_parts_efl_ = browser_main_parts.get(); - return browser_main_parts; -} - -void ContentBrowserClientEfl::AppendExtraCommandLineSwitchesInternal( - base::CommandLine* command_line, - int child_process_id) { +void AppendExtraCommandLineSwitchesInternal(base::CommandLine* command_line, + int child_process_id) { if (!command_line->HasSwitch(switches::kProcessType)) return; @@ -159,6 +127,129 @@ void ContentBrowserClientEfl::AppendExtraCommandLineSwitchesInternal( widget_encoded_bundle); } +void DispatchPopupBlockedOnUIThread(int render_process_id, + const GURL& target_url) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + std::unique_ptr widgets( + RenderWidgetHost::GetRenderWidgetHosts()); + RenderWidgetHost* widget = NULL; + + while ((widget = widgets->GetNextHost())) + if (widget->GetProcess()->GetID() == render_process_id) + break; + + // It may happen that this message will be handled on ui thread after view + // was closed. In such case ignore do nothing. + if (!widget) + return; + RenderViewHost* vh = RenderViewHost::From(widget); + if (!vh) + return; + + WebContents* content = WebContents::FromRenderViewHost(vh); + if (!content) + return; + + EWebView* wv = WebViewFromWebContents(content); + wv->SmartCallback().call( + target_url.spec().c_str()); +} + +} // namespace + +AcceptLanguagesHelper::AcceptLanguagesHelper() + : accept_langs_(kDefaultAcceptLanguages) {} + +AcceptLanguagesHelper::~AcceptLanguagesHelper() {} + +std::string AcceptLanguagesHelper::GetAcceptLangs() { + if (!preferred_langs_.empty()) + return preferred_langs_; + + return accept_langs_; +} + +void AcceptLanguagesHelper::SetAcceptLangs(const std::string& accept_langs) { + if (accept_langs.empty() || accept_langs_ == accept_langs) + return; + + accept_langs_ = accept_langs; + if (preferred_langs_.empty()) + NotifyAcceptLangsChanged(); +} + +void AcceptLanguagesHelper::SetPreferredLangs( + const std::string& preferred_langs) { + if (preferred_langs_ == preferred_langs) + return; + + preferred_langs_ = preferred_langs; + NotifyAcceptLangsChanged(); +} + +void AcceptLanguagesHelper::AddAcceptLangsChangedCallback( + AcceptLangsChangedCallback callback) { + if (callback) + accept_langs_changed_callbacks_.push_back(std::move(callback)); +} + +void AcceptLanguagesHelper::RemoveAcceptLangsChangedCallback( + AcceptLangsChangedCallback callback) { +#if !defined(EWK_BRINGUP) // FIXME: m94 bringup + for (size_t i = 0; i < accept_langs_changed_callbacks_.size(); ++i) { + if (accept_langs_changed_callbacks_[i] == callback) { + accept_langs_changed_callbacks_.erase( + accept_langs_changed_callbacks_.begin() + i); + return; + } + } +#endif +} + +void AcceptLanguagesHelper::NotifyAcceptLangsChanged() { + std::vector callbacks; + callbacks.swap(accept_langs_changed_callbacks_); + + for (auto& callback : callbacks) { + if (preferred_langs_.empty()) + std::move(callback).Run(accept_langs_); + else + std::move(callback).Run(preferred_langs_); + } +} + +ContentBrowserClientEfl::ContentBrowserClientEfl() + : notification_controller_(new NotificationControllerEfl), + accept_langs_helper_(new AcceptLanguagesHelper) { +#if BUILDFLAG(IS_TIZEN) + PlatformLanguageChanged(nullptr, this); + vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, this); +#endif +} + +ContentBrowserClientEfl::~ContentBrowserClientEfl() { +#if BUILDFLAG(IS_TIZEN) + vconf_ignore_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged); +#endif +} + +void ContentBrowserClientEfl::SetBrowserContext(BrowserContext* context) { + browser_context_.reset(context); +} + +void ContentBrowserClientEfl::CleanUpBrowserContext() { + browser_context_.reset(nullptr); + shutting_down_ = true; +} + +std::unique_ptr +ContentBrowserClientEfl::CreateBrowserMainParts(bool is_integration_test) { + auto browser_main_parts = std::make_unique(); + browser_main_parts_efl_ = browser_main_parts.get(); + return browser_main_parts; +} + void ContentBrowserClientEfl::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { @@ -192,10 +283,9 @@ bool ContentBrowserClientEfl::CanCreateWindow( #if !defined(EWK_BRINGUP) // FIXME: m67 bringup if (!user_gesture) { *no_javascript_access = true; - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&ContentBrowserClientEfl::DispatchPopupBlockedOnUIThread, - render_process_id, target_url)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::BindOnce(&DispatchPopupBlockedOnUIThread, + render_process_id, target_url)); return false; } #endif @@ -218,36 +308,6 @@ bool ContentBrowserClientEfl::CanCreateWindow( return policy_decision->CanCreateWindow(); } -void ContentBrowserClientEfl::DispatchPopupBlockedOnUIThread( - int render_process_id, - const GURL& target_url) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - std::unique_ptr widgets( - RenderWidgetHost::GetRenderWidgetHosts()); - RenderWidgetHost* widget = NULL; - - while ((widget = widgets->GetNextHost())) - if (widget->GetProcess()->GetID() == render_process_id) - break; - - // It may happen that this message will be handled on ui thread after view - // was closed. In such case ignore do nothing. - if (!widget) - return; - RenderViewHost* vh = RenderViewHost::From(widget); - if (!vh) - return; - - WebContents* content = WebContents::FromRenderViewHost(vh); - if (!content) - return; - - EWebView* wv = WebViewFromWebContents(content); - wv->SmartCallback().call( - target_url.spec().c_str()); -} - bool ContentBrowserClientEfl::HasErrorPage(int http_status_code) { // Use an internal error page, if we have one for the status code. return error_page::LocalizedError::HasStrings( @@ -287,12 +347,6 @@ void ContentBrowserClientEfl::AllowCertificateError( #endif // !defined(EWK_BRINGUP) } -PlatformNotificationService* -ContentBrowserClientEfl::GetPlatformNotificationService( - BrowserContext* browser_context) { - return notification_controller_.get(); -} - NotificationControllerEfl* ContentBrowserClientEfl::GetNotificationController() const { return notification_controller_.get(); @@ -455,61 +509,26 @@ std::string ContentBrowserClientEfl::GetUserAgent() { } std::string ContentBrowserClientEfl::GetAcceptLangs(BrowserContext* context) { - if (!preferred_langs_.empty()) - return preferred_langs_; - - return accept_langs_; + return accept_langs_helper_->GetAcceptLangs(); } void ContentBrowserClientEfl::SetAcceptLangs(const std::string& accept_langs) { - if (accept_langs.empty() || accept_langs_ == accept_langs) - return; - - accept_langs_ = accept_langs; - - if (preferred_langs_.empty()) - NotifyAcceptLangsChanged(); + accept_langs_helper_->SetAcceptLangs(accept_langs); } void ContentBrowserClientEfl::SetPreferredLangs( const std::string& preferred_langs) { - if (preferred_langs_ == preferred_langs) - return; - - preferred_langs_ = preferred_langs; - - NotifyAcceptLangsChanged(); + accept_langs_helper_->SetPreferredLangs(preferred_langs); } void ContentBrowserClientEfl::AddAcceptLangsChangedCallback( - AcceptLangsChangedCallback callback) { - if (callback) - accept_langs_changed_callbacks_.push_back(std::move(callback)); + AcceptLanguagesHelper::AcceptLangsChangedCallback callback) { + accept_langs_helper_->AddAcceptLangsChangedCallback(std::move(callback)); } void ContentBrowserClientEfl::RemoveAcceptLangsChangedCallback( - AcceptLangsChangedCallback callback) { -#if !defined(EWK_BRINGUP) // FIXME: m94 bringup - for (size_t i = 0; i < accept_langs_changed_callbacks_.size(); ++i) { - if (accept_langs_changed_callbacks_[i] == callback) { - accept_langs_changed_callbacks_.erase( - accept_langs_changed_callbacks_.begin() + i); - return; - } - } -#endif -} - -void ContentBrowserClientEfl::NotifyAcceptLangsChanged() { - std::vector callbacks; - callbacks.swap(accept_langs_changed_callbacks_); - - for (auto& callback : callbacks) { - if (preferred_langs_.empty()) - std::move(callback).Run(accept_langs_); - else - std::move(callback).Run(preferred_langs_); - } + AcceptLanguagesHelper::AcceptLangsChangedCallback callback) { + accept_langs_helper_->RemoveAcceptLangsChangedCallback(std::move(callback)); } std::unique_ptr ContentBrowserClientEfl::CreateLoginDelegate( diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.h b/tizen_src/ewk/efl_integration/content_browser_client_efl.h index 7b3f8f1..5ba1b1a 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.h +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.h @@ -21,35 +21,47 @@ namespace content { class BrowserMainPartsEfl; class NotificationControllerEfl; class SharedURLLoaderFactoryEfl; - #if defined(TIZEN_WEB_SPEECH_RECOGNITION) class SpeechRecognitionManagerDelegate; #endif - class WebContents; class WebContentsView; -class ContentBrowserClientEfl : public ContentBrowserClient { +class AcceptLanguagesHelper { public: - typedef void (*Notification_Show_Callback)(Ewk_Notification*, void*); - typedef void (*Notification_Cancel_Callback)(uint64_t, void*); + using AcceptLangsChangedCallback = + base::OnceCallback; + AcceptLanguagesHelper(); + ~AcceptLanguagesHelper(); + + void SetAcceptLangs(const std::string& accept_langs); + void SetPreferredLangs(const std::string& preferred_langs); + std::string GetAcceptLangs(); + void AddAcceptLangsChangedCallback(AcceptLangsChangedCallback callback); + void RemoveAcceptLangsChangedCallback(AcceptLangsChangedCallback callback); + + private: + void NotifyAcceptLangsChanged(); + std::string accept_langs_; + std::string preferred_langs_; + std::vector accept_langs_changed_callbacks_; +}; + +class ContentBrowserClientEfl : public ContentBrowserClient { + public: ContentBrowserClientEfl(); ~ContentBrowserClientEfl() override; ContentBrowserClientEfl(const ContentBrowserClientEfl&) = delete; ContentBrowserClientEfl& operator=(const ContentBrowserClientEfl&) = delete; - typedef base::OnceCallback - AcceptLangsChangedCallback; + // ContentBrowserClient implementations. std::unique_ptr CreateBrowserMainParts( bool is_integration_test) override; - // Allows the embedder to pass extra command line flags. - // switches::kProcessType will already be set at this point. void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; - bool CanCreateWindow(RenderFrameHost* opener, const GURL& opener_url, const GURL& opener_top_level_frame_url, @@ -80,46 +92,29 @@ class ContentBrowserClientEfl : public ContentBrowserClient { bool is_main_frame_request, bool strict_enforcement, base::OnceCallback callback) override; - - PlatformNotificationService* GetPlatformNotificationService( - BrowserContext* browser_context); - - NotificationControllerEfl* GetNotificationController() const; - bool AllowGetCookie(const GURL& url, const GURL& first_party, const net::CookieList& cookie_list, ResourceContext* context, int render_process_id, int render_frame_id); - bool AllowSetCookie(const GURL& url, const GURL& first_party, const net::CanonicalCookie& cookie, ResourceContext* context, int render_process_id, int render_frame_id); - void OverrideWebkitPrefs(WebContents* web_contents, blink::web_pref::WebPreferences* prefs); - void RenderProcessWillLaunch(RenderProcessHost* host) override; - void SetCertificatePem(const net::SSLInfo& ssl_info, int render_process_id, int render_view_id); - DevToolsManagerDelegate* GetDevToolsManagerDelegate(); - std::string GetApplicationLocale() override; - std::unique_ptr GetWebContentsViewDelegate( WebContents* web_contents) override; - - void SetBrowserContext(BrowserContext* context); - void CleanUpBrowserContext(); - - virtual std::unique_ptr CreateLoginDelegate( + std::unique_ptr CreateLoginDelegate( const net::AuthChallengeInfo& auth_info, WebContents* web_contents, const GlobalRequestID& request_id, @@ -128,15 +123,17 @@ class ContentBrowserClientEfl : public ContentBrowserClient { scoped_refptr response_headers, bool first_auth_attempt, LoginAuthRequiredCallback auth_required_callback) override; - std::string GetProduct() override; std::string GetUserAgent() override; - - std::string GetAcceptLangs(BrowserContext* context) override; + NotificationControllerEfl* GetNotificationController() const; + void SetBrowserContext(BrowserContext* context); + void CleanUpBrowserContext(); void SetAcceptLangs(const std::string& accept_langs); void SetPreferredLangs(const std::string& preferred_langs); - void AddAcceptLangsChangedCallback(AcceptLangsChangedCallback callback); - void RemoveAcceptLangsChangedCallback(AcceptLangsChangedCallback callback); + void AddAcceptLangsChangedCallback( + AcceptLanguagesHelper::AcceptLangsChangedCallback callback); + void RemoveAcceptLangsChangedCallback( + AcceptLanguagesHelper::AcceptLangsChangedCallback callback); std::vector> CreateThrottlesForNavigation( NavigationHandle* handle) override; std::vector> @@ -146,6 +143,7 @@ class ContentBrowserClientEfl : public ContentBrowserClient { const base::RepeatingCallback& wc_getter, content::NavigationUIData* navigation_ui_data, int frame_tree_node_id) override; + std::string GetAcceptLangs(BrowserContext* context) override; private: bool WillCreateURLLoaderFactory( @@ -162,33 +160,21 @@ class ContentBrowserClientEfl : public ContentBrowserClient { bool* bypass_redirect_checks, bool* disable_secure_dns, network::mojom::URLLoaderFactoryOverridePtr* factory_override) override; - scoped_refptr GetSystemSharedURLLoaderFactory() override; - static void SetCertificatePemOnUIThread(int render_process_id, int render_view_id, std::string certificate); - static void DispatchPopupBlockedOnUIThread(int render_process_id, - const GURL& target_url); - - void NotifyAcceptLangsChanged(); - void AppendExtraCommandLineSwitchesInternal(base::CommandLine* command_line, - int child_process_id); - - BrowserMainPartsEfl* browser_main_parts_efl_; - - std::unique_ptr notification_controller_; + BrowserMainPartsEfl* browser_main_parts_efl_ = nullptr; std::unique_ptr browser_context_; + std::unique_ptr notification_controller_; // URLLoaderFactory backed by the NetworkContext returned by GetContext(), so // consumers don't all need to create their own factory. scoped_refptr shared_url_loader_factory_; - std::string accept_langs_; - std::string preferred_langs_; - std::vector accept_langs_changed_callbacks_; + std::unique_ptr accept_langs_helper_; bool shutting_down_ = false; }; } // namespace content diff --git a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc index ede9214..d44cd99 100644 --- a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc +++ b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc @@ -10,17 +10,20 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "browser_context_efl.h" #include "common/web_contents_utils.h" #include "content/browser/selection/selection_controller_efl.h" #include "content/common/paths_efl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_process_host.h" #include "context_menu_controller_efl.h" #include "eweb_view.h" #include "net/base/filename_util.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "private/ewk_context_menu_private.h" +#include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard_helper_efl.h" diff --git a/tizen_src/ewk/efl_integration/browser/download_manager_delegate_efl.cc b/tizen_src/ewk/efl_integration/download_manager_delegate_efl.cc similarity index 98% rename from tizen_src/ewk/efl_integration/browser/download_manager_delegate_efl.cc rename to tizen_src/ewk/efl_integration/download_manager_delegate_efl.cc index 0d81672..c7dfc6e 100644 --- a/tizen_src/ewk/efl_integration/browser/download_manager_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/download_manager_delegate_efl.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "browser/download_manager_delegate_efl.h" +#include "download_manager_delegate_efl.h" #include "base/files/file_path.h" #include "base/path_service.h" diff --git a/tizen_src/ewk/efl_integration/browser/download_manager_delegate_efl.h b/tizen_src/ewk/efl_integration/download_manager_delegate_efl.h similarity index 100% rename from tizen_src/ewk/efl_integration/browser/download_manager_delegate_efl.h rename to tizen_src/ewk/efl_integration/download_manager_delegate_efl.h diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index 449ac1b..ead962c 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" +#include "browser/javascript_dialog_manager_efl.h" #include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h" #include "browser/navigation_policy_handler_efl.h" #include "browser/quota_permission_context_efl.h" @@ -21,6 +22,7 @@ #include "browser/selectpicker/popup_menu_item_private.h" #include "browser/web_view_browser_message_filter.h" #include "browser/web_view_evas_handler.h" +#include "browser_context_efl.h" #include "common/content_client_efl.h" #include "common/render_messages_ewk.h" #include "common/version_info.h" diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index bb7357b..3fd06db 100755 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -659,7 +659,7 @@ class EWebView { std::map hit_test_callback_; - content::ContentBrowserClientEfl::AcceptLangsChangedCallback + content::AcceptLanguagesHelper::AcceptLangsChangedCallback accept_langs_changed_callback_; std::unique_ptr host_; diff --git a/tizen_src/ewk/efl_integration/browser/login_delegate_efl.cc b/tizen_src/ewk/efl_integration/login_delegate_efl.cc similarity index 100% rename from tizen_src/ewk/efl_integration/browser/login_delegate_efl.cc rename to tizen_src/ewk/efl_integration/login_delegate_efl.cc diff --git a/tizen_src/ewk/efl_integration/browser/login_delegate_efl.h b/tizen_src/ewk/efl_integration/login_delegate_efl.h similarity index 100% rename from tizen_src/ewk/efl_integration/browser/login_delegate_efl.h rename to tizen_src/ewk/efl_integration/login_delegate_efl.h diff --git a/tizen_src/ewk/efl_integration/private/ewk_auth_challenge_private.h b/tizen_src/ewk/efl_integration/private/ewk_auth_challenge_private.h index ded617d..c5765e5 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_auth_challenge_private.h +++ b/tizen_src/ewk/efl_integration/private/ewk_auth_challenge_private.h @@ -7,7 +7,7 @@ #include "url/gurl.h" #include "net/base/auth.h" -#include "browser/login_delegate_efl.h" +#include "login_delegate_efl.h" /** * @brief Structure used to send credential for authentication challenge. * diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc b/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc index d68fe02..182d00a 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc +++ b/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc @@ -14,6 +14,7 @@ #include "base/guid.h" #include "base/strings/stringprintf.h" #include "browser/autofill/personal_data_manager_factory.h" +#include "browser_context_efl.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "eweb_view.h" #include "ewk_autofill_profile_private.h" diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc index 67a2e18..c1d6e59 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc @@ -6,28 +6,27 @@ #include "base/strings/utf_string_conversions.h" #include "base/trace_event/ttrace.h" -#include "browser/favicon/favicon_database.h" #include "browser/input_picker/color_chooser_efl.h" #include "browser/javascript_dialog_manager_efl.h" #include "browser/policy_response_delegate_efl.h" +#include "browser_context_efl.h" #include "common/render_messages_ewk.h" -#include "components/favicon/core/favicon_url.h" -#include "components/favicon_base/favicon_types.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_service.h" #include "content/browser/manifest/manifest_manager_host.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/content_switches_internal.h" #include "content/common/render_messages_efl.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/favicon_status.h" +#include "content/public/browser/file_select_listener.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_view_host.h" #include "eweb_view.h" #include "eweb_view_callbacks.h" #include "net/base/load_states.h" #include "net/http/http_response_headers.h" -#include "printing/metafile_skia.h" #include "private/ewk_certificate_private.h" #include "private/ewk_console_message_private.h" #include "private/ewk_custom_handlers_private.h" @@ -38,6 +37,7 @@ #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/manifest/manifest_util.h" #include "url/gurl.h" +#include "web_contents_observer_efl.h" #if BUILDFLAG(IS_TIZEN) #include @@ -68,23 +68,6 @@ using namespace ui; namespace content { -void WritePdfDataToFile(printing::MetafileSkia* metafile, - const base::FilePath& filename) { -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); -#endif - DCHECK(metafile); - base::File file(filename, - base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); - metafile->SaveTo(&file); - file.Close(); - delete metafile; -} - -static bool IsMainFrame(RenderFrameHost* render_frame_host) { - return !render_frame_host->GetParent(); -} - #if BUILDFLAG(IS_TIZEN) && defined(TIZEN_MULTIMEDIA_SUPPORT) static const MediaStreamDevice* GetRequestedVideoDevice( const std::string& device_id) { @@ -99,15 +82,9 @@ static const MediaStreamDevice* GetRequestedVideoDevice( #endif WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view) - : WebContentsObserver(&view->web_contents()), - web_view_(view), - is_fullscreen_(false), + : web_view_(view), web_contents_(view->web_contents()), - did_render_frame_(false), - did_first_visually_non_empty_paint_(false), - document_created_(false), - dialog_manager_(NULL), - weak_ptr_factory_(this) { + contents_observer_(std::make_unique(view, this)) { #if defined(TIZEN_AUTOFILL_SUPPORT) AutofillClientEfl::CreateForWebContents(&web_contents_); AutofillClientEfl* autofill_client = @@ -198,11 +175,6 @@ void WebContentsDelegateEfl::LoadingStateChanged(WebContents* source, web_view_->SmartCallback().call(); } -void WebContentsDelegateEfl::LoadProgressChanged(double progress) { - web_view_->SetProgressValue(progress); - web_view_->SmartCallback().call(&progress); -} - void WebContentsDelegateEfl::AddNewContents( WebContents* source, std::unique_ptr new_contents, @@ -362,107 +334,6 @@ void WebContentsDelegateEfl::OnAuthRequired(const std::string& realm, web_view_->InvokeAuthCallback(login_delegate, url, realm); } -void WebContentsDelegateEfl::DidStartNavigation( - NavigationHandle* navigation_handle) { - if (!navigation_handle->IsInMainFrame()) - return; - web_view_->SmartCallback().call(); -} - -void WebContentsDelegateEfl::DidRedirectNavigation( - NavigationHandle* navigation_handle) { - if (!navigation_handle->IsInMainFrame()) - return; - web_view_->SmartCallback().call(); -} - -void WebContentsDelegateEfl::DidFinishNavigation( - NavigationHandle* navigation_handle) { - if (!navigation_handle->HasCommitted()) - return; - - if (navigation_handle->IsInMainFrame()) { - web_view_->SmartCallback().call(); - - if (!navigation_handle->IsSameDocument() && - !navigation_handle->IsErrorPage()) - web_view_->SmartCallback().call(); - } else if (!navigation_handle->HasSubframeNavigationEntryCommitted()) { - return; - } - - if (navigation_handle->ShouldUpdateHistory()) - static_cast(web_contents_.GetBrowserContext()) - ->AddVisitedURLs(navigation_handle->GetRedirectChain()); -} - -void WebContentsDelegateEfl::DidFinishLoad(RenderFrameHost* render_frame_host, - const GURL& validated_url) { - if (!IsMainFrame(render_frame_host)) - return; - web_view_->SmartCallback().call(); - - web_contents_.Focus(); -} - -void WebContentsDelegateEfl::DidFailLoad(RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code) { - if (!IsMainFrame(render_frame_host)) - return; - - web_view_->InvokeLoadError(validated_url, error_code, - error_code == net::ERR_ABORTED); -} - -void WebContentsDelegateEfl::DidUpdateFaviconURL( - RenderFrameHost* render_frame_host, - const std::vector& candidates) { - // select and set proper favicon - for (const auto& favicon : candidates) { - if (!favicon->icon_url.is_valid()) - continue; - - if (favicon->icon_type == blink::mojom::FaviconIconType::kFavicon) { - NavigationEntry* entry = web_contents_.GetController().GetVisibleEntry(); - if (!entry) - return; - entry->GetFavicon().url = favicon->icon_url; - entry->GetFavicon().valid = true; - - // check/update the url and favicon url in favicon database - FaviconDatabase::Instance()->SetFaviconURLForPageURL(favicon->icon_url, - entry->GetURL()); - - // download favicon if there is no such in database - if (!FaviconDatabase::Instance()->ExistsForFaviconURL( - favicon->icon_url)) { - LOG(INFO) << "No favicon in database for URL: " - << favicon->icon_url.spec(); - favicon_downloader_.reset(new FaviconDownloader( - &web_contents_, favicon->icon_url, - base::BindOnce(&WebContentsDelegateEfl::DidDownloadFavicon, - weak_ptr_factory_.GetWeakPtr()))); - favicon_downloader_->Start(); - } else { - web_view_->SmartCallback().call(); - } - return; - } - } -} - -void WebContentsDelegateEfl::DidDownloadFavicon(bool success, - const GURL& icon_url, - const SkBitmap& bitmap) { - favicon_downloader_.reset(); - if (success) { - FaviconDatabase::Instance()->SetBitmapForFaviconURL(bitmap, icon_url); - // emit "icon,received" - web_view_->SmartCallback().call(); - } -} - void WebContentsDelegateEfl::RequestCertificateConfirm( WebContents* /*web_contents*/, int cert_error, @@ -536,16 +407,7 @@ void WebContentsDelegateEfl::ActivateContents(WebContents* contents) { void WebContentsDelegateEfl::SetContentSecurityPolicy( const std::string& policy, Ewk_CSP_Header_Type header_type) { - if (document_created_) { -#if !defined(EWK_BRINGUP) // FIXME: m94 bringup - RenderViewHost* rvh = web_contents_.GetRenderViewHost(); - rvh->Send(new EwkViewMsg_SetCSP(rvh->GetRoutingID(), policy, header_type)); -#endif - } else { - DCHECK(!pending_content_security_policy_.get()); - pending_content_security_policy_.reset( - new ContentSecurityPolicy(policy, header_type)); - } + contents_observer_->SetContentSecurityPolicy(policy, header_type); } void WebContentsDelegateEfl::FindReply(WebContents* web_contents, @@ -596,59 +458,6 @@ void WebContentsDelegateEfl::OnUpdateSettings(const Ewk_Settings* settings) { #endif } -bool WebContentsDelegateEfl::OnMessageReceived( - const IPC::Message& message, - RenderFrameHost* render_frame_host) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(WebContentsDelegateEfl, message) - IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_GetContentSecurityPolicy, - OnGetContentSecurityPolicy) - IPC_MESSAGE_HANDLER(EwkHostMsg_DidPrintPagesToPdf, - OnPrintedMetafileReceived) - IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage) - IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_WrtSyncMessage, - OnWrtPluginSyncMessage) - IPC_MESSAGE_HANDLER(EwkHostMsg_DidChangeContentsSize, - OnDidChangeContentsSize) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - return handled; -} - -bool WebContentsDelegateEfl::Send(IPC::Message* message) { - if (!web_contents_.GetRenderViewHost()) { - delete message; - return false; - } -#if !defined(EWK_BRINGUP) // FIXME: m94 bringup - return web_contents_.GetRenderViewHost()->Send(message); -#else - return false; -#endif -} - -void WebContentsDelegateEfl::OnWrtPluginMessage( - const Ewk_Wrt_Message_Data& data) { - std::unique_ptr p(new Ewk_Wrt_Message_Data); - p->type = data.type; - p->value = data.value; - p->id = data.id; - p->reference_id = data.reference_id; - - web_view_->SmartCallback().call( - p.get()); -} - -void WebContentsDelegateEfl::OnWrtPluginSyncMessage( - const Ewk_Wrt_Message_Data& data, - IPC::Message* reply) { - Ewk_Wrt_Message_Data tmp = data; - web_view_->SmartCallback().call(&tmp); - EwkHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value); - Send(reply); -} - void WebContentsDelegateEfl::DidFirstVisuallyNonEmptyPaint() { did_first_visually_non_empty_paint_ = true; web_view_->SmartCallback() @@ -659,62 +468,6 @@ void WebContentsDelegateEfl::DidStartLoading() { did_render_frame_ = false; } -void WebContentsDelegateEfl::OnGetContentSecurityPolicy( - IPC::Message* reply_msg) { - document_created_ = true; - if (!pending_content_security_policy_.get()) { - EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams( - reply_msg, std::string(), EWK_DEFAULT_POLICY); - } else { - EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams( - reply_msg, pending_content_security_policy_->policy, - pending_content_security_policy_->header_type); - pending_content_security_policy_.reset(); - } - Send(reply_msg); -} - -void WebContentsDelegateEfl::OnPrintedMetafileReceived( - const DidPrintPagesParams& params) { -#if !defined(EWK_BRINGUP) // FIXME: m85 bringup - base::SharedMemory shared_buf(params.metafile_data_handle, true); - if (!shared_buf.Map(params.data_size)) { - NOTREACHED() << "couldn't map"; - return; - } - - std::unique_ptr metafile( - new printing::MetafileSkia()); - if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) { - NOTREACHED() << "Invalid metafile header"; - return; - } - - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - base::BindOnce(&WritePdfDataToFile, metafile.release(), params.filename)); -#endif -} - -void WebContentsDelegateEfl::NavigationEntryCommitted( - const LoadCommittedDetails& load_details) { - web_view_->InvokeBackForwardListChangedCallback(); -} - -void WebContentsDelegateEfl::RenderViewCreated( - RenderViewHost* render_view_host) { - web_view_->RenderViewCreated(render_view_host); -} - -void WebContentsDelegateEfl::RenderProcessGone(base::TerminationStatus status) { - // See RenderWidgetHostViewEfl::RenderProcessGone. - if (status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION || - status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED || - status == base::TERMINATION_STATUS_PROCESS_CRASHED) { - web_view_->HandleRendererProcessCrash(); - } -} - bool WebContentsDelegateEfl::DidAddMessageToConsole( WebContents* source, blink::mojom::ConsoleMessageLevel level, @@ -780,11 +533,6 @@ bool WebContentsDelegateEfl::PreHandleGestureEvent( return false; } -void WebContentsDelegateEfl::TitleWasSet(NavigationEntry* entry) { - if (entry) - web_view_->GetBackForwardList()->UpdateItemWithEntry(entry); -} - void WebContentsDelegateEfl::RequestManifestInfo( Ewk_View_Request_Manifest_Callback callback, void* user_data) { @@ -814,12 +562,4 @@ void WebContentsDelegateEfl::OnDidGetManifest( } } -void WebContentsDelegateEfl::OnPageScaleFactorChanged(float page_scale_factor) { - web_view_->DidChangePageScaleFactor(page_scale_factor); -} - -void WebContentsDelegateEfl::OnDidChangeContentsSize(int width, int height) { - web_view_->DidChangeContentsSize(width, height); -} - } // namespace content diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h index ba107b6..add0161 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h @@ -2,39 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEB_CONTENTS_DELEGATE_EFL -#define WEB_CONTENTS_DELEGATE_EFL - -#include - -#include "browser/favicon/favicon_downloader.h" -#include "browser/javascript_dialog_manager_efl.h" -#include "browser_context_efl.h" -#include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" +#ifndef WEB_CONTENTS_DELEGATE_EFL_H_ +#define WEB_CONTENTS_DELEGATE_EFL_H_ + #include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" #include "eweb_view.h" #include "private/ewk_manifest_private.h" #include "public/ewk_view_internal.h" #include "third_party/blink/public/mojom/manifest/manifest.mojom.h" #include "ui/base/ime/text_input_type.h" -#include "url/gurl.h" -class DidPrintPagesParams; -class Ewk_Wrt_Message_Data; class JavaScriptDialogManagerEfl; namespace content { -class WebContentsDelegateEfl : public WebContentsDelegate, - public WebContentsObserver, - public IPC::Sender { +class WebContentsObserverEfl; + +class WebContentsDelegateEfl : public WebContentsDelegate { public: WebContentsDelegateEfl(EWebView*); - ~WebContentsDelegateEfl() override; + ~WebContentsDelegateEfl(); WebContentsDelegateEfl(const WebContentsDelegateEfl&) = delete; WebContentsDelegateEfl& operator=(const WebContentsDelegateEfl&) = delete; @@ -71,22 +58,6 @@ class WebContentsDelegateEfl : public WebContentsDelegate, void ExitFullscreenModeForTab(WebContents* web_contents) override; bool IsFullscreenForTabOrPending(const WebContents* web_contents) override; -#if defined(TIZEN_MULTIMEDIA_SUPPORT) - virtual bool CheckMediaAccessPermission(WebContents* web_contents, - const GURL& security_origin, - MediaStreamType type) override; - - virtual void RequestMediaAccessPermission( - WebContents* web_contents, - const MediaStreamRequest& request, - MediaResponseCallback callback) override; - - void RequestMediaAccessAllow(const MediaStreamRequest& request, - MediaResponseCallback callback); - - void RequestMediaAccessDeny(const MediaStreamRequest& request, - MediaResponseCallback callback); -#endif void RegisterProtocolHandler(RenderFrameHost* host, const std::string& protocol, const GURL& url, @@ -101,9 +72,7 @@ class WebContentsDelegateEfl : public WebContentsDelegate, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) override; - void DidRenderFrame() override; - void RequestCertificateConfirm( WebContents* web_contents, int cert_error, @@ -115,23 +84,14 @@ class WebContentsDelegateEfl : public WebContentsDelegate, JavaScriptDialogManager* GetJavaScriptDialogManager( WebContents* source) override; - void ActivateContents(WebContents* contents) override; - void OnUpdateSettings(const Ewk_Settings* settings); void SetContentSecurityPolicy(const std::string& policy, Ewk_CSP_Header_Type header_type); - void DidFirstVisuallyNonEmptyPaint() override; - void DidStartLoading() override; + void DidFirstVisuallyNonEmptyPaint(); + void DidStartLoading(); - bool OnMessageReceived(const IPC::Message& message, - RenderFrameHost* render_frame_host) override; - void OnPrintedMetafileReceived(const DidPrintPagesParams& params); - void NavigationEntryCommitted( - const LoadCommittedDetails& load_details) override; - void RenderViewCreated(RenderViewHost* render_view_host); - void RenderProcessGone(base::TerminationStatus status); bool DidAddMessageToConsole(WebContents* source, blink::mojom::ConsoleMessageLevel level, const std::u16string& message, @@ -143,8 +103,7 @@ class WebContentsDelegateEfl : public WebContentsDelegate, std::unique_ptr OpenColorChooser( WebContents* web_contents, SkColor color, - const std::vector& suggestions) - override; + const std::vector& suggestions); #if !defined(EWK_BRINGUP) // FIXME: m76 bringup void OpenDateTimeDialog(ui::TextInputType dialog_type, double dialog_value, @@ -155,53 +114,31 @@ class WebContentsDelegateEfl : public WebContentsDelegate, #endif bool PreHandleGestureEvent(WebContents* source, const blink::WebGestureEvent& event) override; + EWebView* web_view() const { return web_view_; } + WebContents& web_contents() const { return web_contents_; } - // WebContentsObserver--------------------------------------------------- - void DidStartNavigation(NavigationHandle* navigation_handle) override; - - void DidRedirectNavigation(NavigationHandle* navigation_handle) override; - - void DidFinishNavigation(NavigationHandle* navigation_handle) override; - - void LoadProgressChanged(double progress) override; - void DidFinishLoad(RenderFrameHost* render_frame_host, - const GURL& validated_url) override; - void OnPageScaleFactorChanged(float page_scale_factor) override; - - void DidFailLoad(RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code) override; - - void DidUpdateFaviconURL( - RenderFrameHost* render_frame_host, - const std::vector& candidates) override; - - void TitleWasSet(content::NavigationEntry* entry) override; - + void RequestManifestInfo(Ewk_View_Request_Manifest_Callback callback, + void* user_data); void OnAuthRequired(const std::string& realm, const GURL& url, LoginDelegateEfl* login_delegate); - // IPC::Sender----------------------------------------------------------- - bool Send(IPC::Message* message) override; - - void DidDownloadFavicon(bool success, - const GURL& icon_url, - const SkBitmap& bitmap); - - EWebView* web_view() const { return web_view_; } - WebContents& web_contents() const { return web_contents_; } +#if defined(TIZEN_MULTIMEDIA_SUPPORT) + virtual bool CheckMediaAccessPermission(WebContents* web_contents, + const GURL& security_origin, + MediaStreamType type) override; - void RequestManifestInfo(Ewk_View_Request_Manifest_Callback callback, - void* user_data); + virtual void RequestMediaAccessPermission( + WebContents* web_contents, + const MediaStreamRequest& request, + MediaResponseCallback callback) override; + void RequestMediaAccessAllow(const MediaStreamRequest& request, + MediaResponseCallback callback); + void RequestMediaAccessDeny(const MediaStreamRequest& request, + MediaResponseCallback callback); +#endif private: - void OnGetContentSecurityPolicy(IPC::Message* reply_msg); - void OnWrtPluginMessage(const Ewk_Wrt_Message_Data& data); - void OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data, - IPC::Message* reply); - void OnDidChangeContentsSize(int width, int height); - void OnDidGetManifest(Ewk_View_Request_Manifest_Callback callback, void* user_data, const GURL& manifest_url, @@ -211,26 +148,18 @@ class WebContentsDelegateEfl : public WebContentsDelegate, bool is_fullscreen_; WebContents& web_contents_; - bool did_render_frame_; - bool did_first_visually_non_empty_paint_; - - struct ContentSecurityPolicy { - ContentSecurityPolicy(const std::string& p, Ewk_CSP_Header_Type type) - : policy(p), header_type(type) {} - std::string policy; - Ewk_CSP_Header_Type header_type; - }; + bool did_render_frame_ = false; + bool did_first_visually_non_empty_paint_ = false; + std::unique_ptr contents_observer_; + void* ime_window_ = nullptr; GURL last_visible_url_; - std::unique_ptr pending_content_security_policy_; - bool document_created_; JavaScriptDialogManagerEfl* dialog_manager_ = nullptr; - std::unique_ptr favicon_downloader_; - base::WeakPtrFactory weak_ptr_factory_; + int rotation_ = -1; std::unique_ptr<_Ewk_Certificate_Policy_Decision> certificate_policy_decision_; }; } -#endif +#endif // WEB_CONTENTS_DELEGATE_EFL_H_ diff --git a/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc b/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc new file mode 100644 index 0000000..537b761 --- /dev/null +++ b/tizen_src/ewk/efl_integration/web_contents_observer_efl.cc @@ -0,0 +1,318 @@ +// Copyright 2022 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "web_contents_observer_efl.h" + +#include "base/task/bind_post_task.h" +#include "browser/favicon/favicon_database.h" +#include "browser/favicon/favicon_downloader.h" +#include "browser_context_efl.h" +#include "common/print_pages_params.h" +#include "common/render_messages_ewk.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/file_select_listener.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "eweb_view_callbacks.h" +#include "ipc/ipc_message_macros.h" +#include "printing/metafile_skia.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "url/gurl.h" + +#if defined(OS_TIZEN_TV_PRODUCT) +#if !defined(EWK_BRINGUP) +#include "devtools_port_manager.h" +#endif +#include "private/ewk_context_private.h" +#endif + +#if defined(TIZEN_AUTOFILL_SUPPORT) +#include "browser/autofill/autofill_client_efl.h" +using autofill::AutofillClientEfl; +#endif + +namespace content { + +static bool IsMainFrame(RenderFrameHost* render_frame_host) { + return !render_frame_host->GetParent(); +} + +WebContentsObserverEfl::WebContentsObserverEfl(EWebView* view, + WebContentsDelegateEfl* delegate) + : WebContentsObserver(&view->web_contents()), + web_view_(view), + web_contents_(view->web_contents()), + web_contents_delegate_(delegate), + weak_ptr_factory_(this) {} + +WebContentsObserverEfl::~WebContentsObserverEfl() = default; + +void WebContentsObserverEfl::SetContentSecurityPolicy( + const std::string& policy, + Ewk_CSP_Header_Type header_type) { + if (document_created_) { +#if !defined(EWK_BRINGUP) // FIXME: m94 bringup + RenderViewHost* rvh = web_contents_.GetRenderViewHost(); + rvh->Send(new EwkViewMsg_SetCSP(rvh->GetRoutingID(), policy, header_type)); +#endif + } else { + DCHECK(!pending_content_security_policy_.get()); + pending_content_security_policy_.reset( + new ContentSecurityPolicy(policy, header_type)); + } +} + +void WebContentsObserverEfl::DidStartNavigation( + NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame()) + return; + web_view_->SmartCallback().call(); +} + +void WebContentsObserverEfl::DidRedirectNavigation( + NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame()) + return; + web_view_->SmartCallback().call(); +} + +void WebContentsObserverEfl::DidFinishNavigation( + NavigationHandle* navigation_handle) { + if (!navigation_handle->HasCommitted()) + return; + + if (navigation_handle->IsInMainFrame()) { + web_view_->SmartCallback().call(); + + if (!navigation_handle->IsSameDocument() && + !navigation_handle->IsErrorPage()) + web_view_->SmartCallback().call(); + } else if (!navigation_handle->HasSubframeNavigationEntryCommitted()) { + return; + } + + if (navigation_handle->ShouldUpdateHistory()) + static_cast(web_contents_.GetBrowserContext()) + ->AddVisitedURLs(navigation_handle->GetRedirectChain()); +} + +void WebContentsObserverEfl::LoadProgressChanged(double progress) { + web_view_->SetProgressValue(progress); + web_view_->SmartCallback().call(&progress); +} + +void WebContentsObserverEfl::DidFinishLoad(RenderFrameHost* render_frame_host, + const GURL& validated_url) { + if (!IsMainFrame(render_frame_host)) + return; + web_view_->SmartCallback().call(); + + web_contents_.Focus(); +} + +void WebContentsObserverEfl::DidFailLoad(RenderFrameHost* render_frame_host, + const GURL& validated_url, + int error_code) { + if (!IsMainFrame(render_frame_host)) + return; + + web_view_->InvokeLoadError(validated_url, error_code, + error_code == net::ERR_ABORTED); +} + +void WebContentsObserverEfl::TitleWasSet(NavigationEntry* entry) { + if (entry) + web_view_->GetBackForwardList()->UpdateItemWithEntry(entry); +} + +void WebContentsObserverEfl::OnPageScaleFactorChanged(float page_scale_factor) { + web_view_->DidChangePageScaleFactor(page_scale_factor); +} + +void WebContentsObserverEfl::DidFirstVisuallyNonEmptyPaint() { + web_contents_delegate_->DidFirstVisuallyNonEmptyPaint(); +} + +void WebContentsObserverEfl::DidStartLoading() { + web_contents_delegate_->DidStartLoading(); +} + +void WebContentsObserverEfl::NavigationEntryCommitted( + const LoadCommittedDetails& load_details) { + web_view_->InvokeBackForwardListChangedCallback(); +} + +void WebContentsObserverEfl::PrimaryMainFrameRenderProcessGone( + base::TerminationStatus status) { + if (status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION || + status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED || + status == base::TERMINATION_STATUS_PROCESS_CRASHED) { + web_view_->HandleRendererProcessCrash(); + } +} + +void WebContentsObserverEfl::RenderViewCreated( + RenderViewHost* render_view_host) { + web_view_->RenderViewCreated(render_view_host); +} + +void WebContentsObserverEfl::DidUpdateFaviconURL( + RenderFrameHost* render_frame_host, + const std::vector& candidates) { + // select and set proper favicon + for (const auto& favicon : candidates) { + if (!favicon->icon_url.is_valid()) + continue; + + if (favicon->icon_type == blink::mojom::FaviconIconType::kFavicon) { + NavigationEntry* entry = web_contents_.GetController().GetVisibleEntry(); + if (!entry) + return; + entry->GetFavicon().url = favicon->icon_url; + entry->GetFavicon().valid = true; + + // check/update the url and favicon url in favicon database + FaviconDatabase::Instance()->SetFaviconURLForPageURL(favicon->icon_url, + entry->GetURL()); + + // download favicon if there is no such in database + if (!FaviconDatabase::Instance()->ExistsForFaviconURL( + favicon->icon_url)) { + LOG(INFO) << "No favicon in database for URL: " + << favicon->icon_url.spec(); + favicon_downloader_.reset(new FaviconDownloader( + &web_contents_, favicon->icon_url, + base::BindOnce(&WebContentsObserverEfl::DidDownloadFavicon, + weak_ptr_factory_.GetWeakPtr()))); + favicon_downloader_->Start(); + } else { + web_view_->SmartCallback().call(); + } + return; + } + } +} + +bool WebContentsObserverEfl::OnMessageReceived( + const IPC::Message& message, + RenderFrameHost* render_frame_host) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(WebContentsObserverEfl, message) + IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_GetContentSecurityPolicy, + OnGetContentSecurityPolicy) + IPC_MESSAGE_HANDLER(EwkHostMsg_DidPrintPagesToPdf, + OnPrintedMetafileReceived) + IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage) + IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_WrtSyncMessage, + OnWrtPluginSyncMessage) + IPC_MESSAGE_HANDLER(EwkHostMsg_DidChangeContentsSize, + OnDidChangeContentsSize) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; +} + +bool WebContentsObserverEfl::Send(IPC::Message* message) { + if (!web_contents_.GetRenderViewHost()) { + delete message; + return false; + } +#if !defined(EWK_BRINGUP) // FIXME: m94 bringup + return web_contents_.GetRenderViewHost()->Send(message); +#else + return false; +#endif +} + +void WebContentsObserverEfl::OnGetContentSecurityPolicy( + IPC::Message* reply_msg) { + document_created_ = true; + if (!pending_content_security_policy_.get()) { + EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams( + reply_msg, std::string(), EWK_DEFAULT_POLICY); + } else { + EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams( + reply_msg, pending_content_security_policy_->policy, + pending_content_security_policy_->header_type); + pending_content_security_policy_.reset(); + } + Send(reply_msg); +} + +void WebContentsObserverEfl::OnPrintedMetafileReceived( + const DidPrintPagesParams& params) { +#if !defined(EWK_BRINGUP) // FIXME: m85 bringup + base::SharedMemory shared_buf(params.metafile_data_handle, true); + if (!shared_buf.Map(params.data_size)) { + NOTREACHED() << "couldn't map"; + return; + } + + std::unique_ptr metafile( + new printing::MetafileSkia()); + if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) { + NOTREACHED() << "Invalid metafile header"; + return; + } + + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + base::BindOnce(&WritePdfDataToFile, metafile.release(), params.filename)); +#endif +} + +void WebContentsObserverEfl::OnWrtPluginMessage( + const Ewk_Wrt_Message_Data& data) { + std::unique_ptr p(new Ewk_Wrt_Message_Data); + p->type = data.type; + p->value = data.value; + p->id = data.id; + p->reference_id = data.reference_id; + + web_view_->SmartCallback().call( + p.get()); +} + +void WebContentsObserverEfl::OnWrtPluginSyncMessage( + const Ewk_Wrt_Message_Data& data, + IPC::Message* reply) { + Ewk_Wrt_Message_Data tmp = data; + web_view_->SmartCallback().call(&tmp); + EwkHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value); + Send(reply); +} + +void WebContentsObserverEfl::OnDidChangeContentsSize(int width, int height) { + web_view_->DidChangeContentsSize(width, height); +} + +void WebContentsObserverEfl::OnDidChangeFocusedNodeBounds( + const gfx::RectF& focused_node_bounds) { +#if defined(TIZEN_AUTOFILL_SUPPORT) + if (AutofillClientEfl* autofill_client = + AutofillClientEfl::FromWebContents(&web_contents_)) { + autofill_client->DidChangeFocusedNodeBounds(focused_node_bounds); + } +#endif +} + +void WebContentsObserverEfl::DidDownloadFavicon(bool success, + const GURL& icon_url, + const SkBitmap& bitmap) { + favicon_downloader_.reset(); + if (success) { + FaviconDatabase::Instance()->SetBitmapForFaviconURL(bitmap, icon_url); + // emit "icon,received" + web_view_->SmartCallback().call(); + } +} + +} // namespace content diff --git a/tizen_src/ewk/efl_integration/web_contents_observer_efl.h b/tizen_src/ewk/efl_integration/web_contents_observer_efl.h new file mode 100644 index 0000000..b870fa6 --- /dev/null +++ b/tizen_src/ewk/efl_integration/web_contents_observer_efl.h @@ -0,0 +1,99 @@ +// Copyright 2022 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEB_CONTENTS_OBSERVER_EFL_H_ +#define WEB_CONTENTS_OBSERVER_EFL_H_ + +#include + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/web_contents_observer.h" +#include "eweb_view.h" + +class DidPrintPagesParams; +class Ewk_Wrt_Message_Data; +class FaviconDownloader; +class GURL; +class SkBitmap; + +namespace gfx { +class Rect; +} + +namespace content { + +class WebContentsDelegateEfl; + +class WebContentsObserverEfl : public WebContentsObserver, public IPC::Sender { + public: + explicit WebContentsObserverEfl(EWebView* view, + WebContentsDelegateEfl* delegate); + WebContentsObserverEfl(const WebContentsObserverEfl&) = delete; + WebContentsObserverEfl& operator=(const WebContentsObserverEfl&) = delete; + ~WebContentsObserverEfl() override; + + void SetContentSecurityPolicy(const std::string& policy, + Ewk_CSP_Header_Type header_type); + + // IPC::Sender----------------------------------------------------------- + bool Send(IPC::Message* message) override; + + private: + // WebContentsObserver overrides: + void DidStartNavigation(NavigationHandle* navigation_handle) override; + void DidRedirectNavigation(NavigationHandle* navigation_handle) override; + void DidFinishNavigation(NavigationHandle* navigation_handle) override; + void LoadProgressChanged(double progress) override; + void DidFinishLoad(RenderFrameHost* render_frame_host, + const GURL& validated_url) override; + void DidFailLoad(RenderFrameHost* render_frame_host, + const GURL& validated_url, + int error_code) override; + void TitleWasSet(NavigationEntry* entry) override; + void OnPageScaleFactorChanged(float page_scale_factor) override; + void DidFirstVisuallyNonEmptyPaint() override; + void DidStartLoading() override; + void NavigationEntryCommitted( + const LoadCommittedDetails& load_details) override; + void PrimaryMainFrameRenderProcessGone( + base::TerminationStatus status) override; + void RenderViewCreated(RenderViewHost* render_view_host); + void DidUpdateFaviconURL( + RenderFrameHost* render_frame_host, + const std::vector& candidates) override; + bool OnMessageReceived(const IPC::Message& message, + RenderFrameHost* render_frame_host) override; + + // IPC message handlers: + void OnGetContentSecurityPolicy(IPC::Message* reply_msg); + void OnPrintedMetafileReceived(const DidPrintPagesParams& params); + void OnWrtPluginMessage(const Ewk_Wrt_Message_Data& data); + void OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data, + IPC::Message* reply); + void OnDidChangeContentsSize(int width, int height); + void OnDidChangeFocusedNodeBounds(const gfx::RectF& focused_node_bounds); + + void DidDownloadFavicon(bool success, + const GURL& icon_url, + const SkBitmap& bitmap); + + struct ContentSecurityPolicy { + ContentSecurityPolicy(const std::string& p, Ewk_CSP_Header_Type type) + : policy(p), header_type(type) {} + std::string policy; + Ewk_CSP_Header_Type header_type; + }; + + bool document_created_ = false; + EWebView* web_view_; + WebContents& web_contents_; + std::unique_ptr pending_content_security_policy_; + std::unique_ptr favicon_downloader_; + WebContentsDelegateEfl* web_contents_delegate_ = nullptr; + base::WeakPtrFactory weak_ptr_factory_; +}; + +} // namespace content + +#endif // WEB_CONTENTS_OBSERVER_EFL_H_ -- 2.7.4 From 36283f083ca4b9a8a6f4391e3bc67cca1c8ffdc5 Mon Sep 17 00:00:00 2001 From: "ayush.k123" Date: Fri, 27 Jan 2023 10:46:44 +0530 Subject: [PATCH 13/16] [M108 Migration][NativeControl] Refactor Permission Popup. This patch includes below changes: - Refactor Permission_popup. - Fix SetPopupTitle() hardcoding. - Permission popup is closed, When request is cancelled. - NULL checking while DeletePermissionRequest. Reference: https://review.tizen.org/gerrit/c/277643/ Change-Id: I87080ac0061bb9bdf42c8db6a09db6a51b2a6596 Signed-off-by: Ayush Kumar --- tizen_src/ewk/efl_integration/eweb_view.cc | 3 +- tizen_src/ewk/efl_integration/permission_popup.h | 9 +- .../efl_integration/permission_popup_manager.cc | 306 ++++++++------------- .../ewk/efl_integration/permission_popup_manager.h | 59 ++-- 4 files changed, 160 insertions(+), 217 deletions(-) mode change 100755 => 100644 tizen_src/ewk/efl_integration/permission_popup_manager.cc diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index ead962c..e28f0fe 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -1,4 +1,4 @@ -// Copyright 2014 Samsung Electronics. All rights reserved. +// Copyright 2014-2020 Samsung Electronics. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -289,7 +289,6 @@ EWebView::~EWebView() { old_context_ = nullptr; } - GetPermissionPopupManager()->DeleteAllPermissionRequest(); permission_popup_manager_.reset(); if (context_->GetImpl()->browser_context()->IsOffTheRecord()) diff --git a/tizen_src/ewk/efl_integration/permission_popup.h b/tizen_src/ewk/efl_integration/permission_popup.h index 32f07a0..a1b000b 100644 --- a/tizen_src/ewk/efl_integration/permission_popup.h +++ b/tizen_src/ewk/efl_integration/permission_popup.h @@ -1,4 +1,4 @@ -// Copyright 2015 Samsung Electronics. All rights reserved. +// Copyright 2015-2020 Samsung Electronics. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -19,12 +19,13 @@ class PermissionPopup { popup_message_ = message; } + PermissionPopup(const PermissionPopup&) = delete; + PermissionPopup& operator=(const PermissionPopup&) = delete; + virtual ~PermissionPopup() { } std::string GetMessage() const { return popup_message_; } - std::string GetOriginHost() const { - return std::string(ewk_security_origin_host_get(origin_)); - } + std::string GetOrigin() const { return origin_->GetURL().spec(); } virtual void SendDecidedPermission(Evas_Object*, bool decide) = 0; private: diff --git a/tizen_src/ewk/efl_integration/permission_popup_manager.cc b/tizen_src/ewk/efl_integration/permission_popup_manager.cc old mode 100755 new mode 100644 index 190f40b..2535b57 --- a/tizen_src/ewk/efl_integration/permission_popup_manager.cc +++ b/tizen_src/ewk/efl_integration/permission_popup_manager.cc @@ -1,254 +1,188 @@ -// Copyright 2015 Samsung Electronics. All rights reserved. +// Copyright 2015-2020 Samsung Electronics. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "permission_popup_manager.h" + #if BUILDFLAG(IS_TIZEN) #include #endif -#include -#include #include "base/strings/utf_string_conversions.h" -#include "eweb_view.h" #include "permission_popup.h" -#include "permission_popup_manager.h" -PermissionPopupManager::PermissionPopupManager(Evas_Object* eweb_view) - : is_decided_(false) - , permission_popups_(0) - , eweb_view_(eweb_view) - , popup_(0) - , widget_win_(0) - , top_widget_(0) { -} +PermissionPopupManager::PermissionPopupManager(Evas_Object* evas_object) + : evas_object_(evas_object) {} PermissionPopupManager::~PermissionPopupManager() { - ClosePopup(); - DeleteAllPermissionRequest(); + CancelPermissionRequest(); } -void PermissionPopupManager::AddPermissionRequest(PermissionPopup* popup) { - permission_popups_ = eina_list_append(permission_popups_, popup); +void PermissionPopupManager::AddPermissionRequest( + PermissionPopup* permission_popup) { + permission_popups_ = eina_list_append(permission_popups_, permission_popup); ShowPermissionPopup(static_cast( eina_list_data_get(permission_popups_))); } -void PermissionPopupManager::DeletePermissionRequest(PermissionPopup* popup) { - permission_popups_ = eina_list_remove(permission_popups_, popup); - delete popup; +void PermissionPopupManager::CancelPermissionRequest() { + DeletePopup(); + DeleteAllPermissionRequests(); +} - if (eina_list_count(permission_popups_) == 0) +void PermissionPopupManager::DeleteAllPermissionRequests() { + if (!permission_popups_) return; - ShowPermissionPopup(static_cast( - eina_list_data_get(permission_popups_))); + void* data; + EINA_LIST_FREE(permission_popups_, data) { + auto permission_popup = static_cast(data); + permission_popup->SendDecidedPermission(evas_object_, false); + delete permission_popup; + } } -void PermissionPopupManager::DeleteAllPermissionRequest() { - void* data; - EINA_LIST_FREE(permission_popups_, data) - delete static_cast(data); +void PermissionPopupManager::DeletePermissionRequest( + PermissionPopup* permission_popup) { + permission_popups_ = eina_list_remove(permission_popups_, permission_popup); + delete permission_popup; } -Evas_Object* PermissionPopupManager::CreatePopup() { - top_widget_ = elm_object_top_widget_get(elm_object_parent_widget_get(eweb_view_)); - if (!top_widget_) - return 0; +void PermissionPopupManager::ShowPermissionPopup( + PermissionPopup* permission_popup) { + if (popup_ || !CreatePopup()) + return; + if (!SetupPopup(permission_popup)) { + DeletePopup(); + return; + } - widget_win_ = elm_win_add(top_widget_, "WebKit Permission Popup", ELM_WIN_BASIC); - if (!widget_win_) - return 0; + evas_object_show(popup_); +} - elm_win_alpha_set(widget_win_, EINA_TRUE); -#if !defined(WAYLAND_BRINGUP) - ecore_x_icccm_name_class_set(elm_win_xwindow_get(widget_win_), - "APP_POPUP", "APP_POPUP"); -#endif +void PermissionPopupManager::Decide(bool decision) { + DeletePopup(); - if (elm_win_wm_rotation_supported_get(top_widget_)) { - int preferredRotation = - elm_win_wm_rotation_preferred_rotation_get(top_widget_); - if (preferredRotation == -1) { - int rots[4] = {0, 90, 180, 270}; - elm_win_wm_rotation_available_rotations_set(widget_win_, rots, 4); - } - else { - elm_win_wm_rotation_available_rotations_set(widget_win_, - &preferredRotation, 1); - } - } + auto permission_popup = + static_cast(eina_list_data_get(permission_popups_)); + permission_popup->SendDecidedPermission(evas_object_, decision); + DeletePermissionRequest(permission_popup); + permission_popup = + static_cast(eina_list_data_get(permission_popups_)); + if (permission_popup) + ShowPermissionPopup(permission_popup); +} - Eina_Rectangle windowRect; - Ecore_Evas* ee = ecore_evas_ecore_evas_get( - evas_object_evas_get(eweb_view_)); - ecore_evas_geometry_get(ee, &windowRect.x, &windowRect.y, - &windowRect.w, &windowRect.h); - evas_object_resize(widget_win_, windowRect.w, windowRect.h); +void PermissionPopupManager::PermissionOkCallback(void* data, + Evas_Object* obj, + void* event_info) { + PermissionPopupManager* manager = static_cast(data); + manager->Decide(true); +} + +void PermissionPopupManager::PermissionCancelCallback(void* data, + Evas_Object* obj, + void* event_info) { + PermissionPopupManager* manager = static_cast(data); + manager->Decide(false); +} - Evas_Object* conformant = elm_conformant_add(widget_win_); +bool PermissionPopupManager::CreatePopup() { + top_widget_ = + elm_object_top_widget_get(elm_object_parent_widget_get(evas_object_)); + if (!top_widget_) + return false; + + Evas_Object* conformant = elm_conformant_add(top_widget_); if (!conformant) - return 0; + return false; - evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_win_resize_object_add(widget_win_, conformant); + evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_win_resize_object_add(top_widget_, conformant); evas_object_show(conformant); Evas_Object* layout = elm_layout_add(conformant); if (!layout) - return 0; + return false; elm_layout_theme_set(layout, "layout", "application", "default"); evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(layout); elm_object_content_set(conformant, layout); - elm_win_conformant_set(widget_win_, EINA_TRUE); - - evas_object_show(widget_win_); - - Evas_Object* popup = elm_popup_add(layout); - elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); - - return popup; -} - -static void permissionPopupFocusInCallback( - void* data, Evas_Object* obj, void* event_info) { - evas_object_smart_callback_del(obj, "focus,in", permissionPopupFocusInCallback); - - PermissionPopupManager* manager = static_cast(data); - if (!manager) - return; - manager->ClosePopup(); - - PermissionPopup* popup = manager->GetPermissionPopup(); - if (!popup) - return; - popup->SendDecidedPermission(manager->GetEwebView(), manager->IsDecided()); - manager->DeletePermissionRequest(popup); + popup_ = elm_popup_add(layout); + return !!popup_; } -static void permissionOkCallback(void* data, Evas_Object* obj, void* event_info) { - PermissionPopupManager* manager = static_cast(data); - if (!manager) +void PermissionPopupManager::DeletePopup() { + if (!popup_) return; - - evas_object_smart_callback_add(manager->GetTopWidget(), - "focus,in", permissionPopupFocusInCallback, data); - manager->HidePopup(); - manager->Decide(true); + evas_object_del(popup_); + popup_ = nullptr; } -static void permissionCancelCallback( - void* data, Evas_Object* obj, void* event_info) { - PermissionPopupManager* manager = static_cast(data); - if (!manager) - return; +bool PermissionPopupManager::SetupPopup(PermissionPopup* permission_popup) { + elm_popup_align_set(popup_, ELM_NOTIFY_ALIGN_FILL, 1.0); - evas_object_smart_callback_add(manager->GetTopWidget(), "focus,in", - permissionPopupFocusInCallback, data); - manager->HidePopup(); - manager->Decide(false); -} + if (!SetPopupText(permission_popup->GetMessage()) || + !SetPopupTitle(permission_popup->GetOrigin())) { + return false; + } #if BUILDFLAG(IS_TIZEN) -static void permissionHwBackKeyCallback( - void* data, Evas_Object* obj, void* event_info) { - PermissionPopupManager* manager = static_cast(data); - if (!manager) - return; - - evas_object_smart_callback_add(manager->GetTopWidget(), - "focus,in", permissionPopupFocusInCallback, data); - manager->HidePopup(); -} + eext_object_event_callback_add( + popup_, EEXT_CALLBACK_BACK, + &PermissionPopupManager::PermissionCancelCallback, this); #endif -void PermissionPopupManager::ShowPermissionPopup(PermissionPopup* popup) { - if (popup_) - return; - - popup_ = CreatePopup(); - - if (!popup_) - return; - - if (!SetLabelText(popup->GetMessage())) - return; + AddButtonToPopup("button1", "IDS_WEBVIEW_BUTTON_CANCEL_ABB4", + &PermissionPopupManager::PermissionCancelCallback, false); + AddButtonToPopup("button2", "IDS_WEBVIEW_BUTTON_OK_ABB4", + &PermissionPopupManager::PermissionOkCallback, true); -#if BUILDFLAG(IS_TIZEN) - eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, - permissionHwBackKeyCallback, this); -#endif - - Evas_Object* cancelButton = elm_button_add(popup_); - elm_object_style_set(cancelButton, "popup"); - elm_object_domain_translatable_part_text_set( - cancelButton, NULL, "WebKit", "Cancel"); - elm_object_part_content_set(popup_, "button1", cancelButton); - evas_object_smart_callback_add(cancelButton, "clicked", - permissionCancelCallback, this); - - Evas_Object* okButton = elm_button_add(popup_); - elm_object_style_set(okButton, "popup"); - elm_object_domain_translatable_part_text_set(okButton, NULL, "WebKit", "OK"); - elm_object_part_content_set(popup_, "button2", okButton); - evas_object_focus_set(okButton, true); - evas_object_smart_callback_add(okButton, "clicked", permissionOkCallback, this); - - elm_object_part_text_set(popup_, "title,text", GetTitle(popup).c_str()); - evas_object_show(popup_); + return true; } -std::string PermissionPopupManager::GetTitle(PermissionPopup* popup) { - std::string url = std::string(ewk_view_url_get(eweb_view_)); - - if (url.empty()) - url = std::string(ewk_view_title_get(eweb_view_)); +bool PermissionPopupManager::SetPopupTitle(const std::string& origin) { + // Empty origin is improper one. + if (origin.empty()) + return false; + std::string title = + dgettext("WebKit", "IDS_WEBVIEW_HEADER_MESSAGE_FROM_PS_M_WEBSITE"); - std::string popupTitle = std::string(dgettext( - "WebKit","IDS_WEBVIEW_HEADER_MESSAGE_FROM_PS_M_WEBSITE")); - std::string replaceStr = std::string("%s"); - size_t pos = popupTitle.find(replaceStr.c_str()); + const std::string replaceStr("%s"); + size_t pos = title.find(replaceStr); if (pos != std::string::npos) - popupTitle.replace(pos, replaceStr.length(), url.c_str()); - - return popupTitle; + title.replace(pos, replaceStr.length(), origin); + else + LOG(ERROR) << "Translation issue. " << title << " not found"; + elm_object_part_text_set(popup_, "title,text", title.c_str()); + return true; } -bool PermissionPopupManager::SetLabelText(const std::string& message) { +bool PermissionPopupManager::SetPopupText(const std::string& message) { if (message.empty()) return false; - - std::string labal_text = message; + std::string text = message; std::string replaceStr = std::string("\n"); - size_t pos = labal_text.find(replaceStr.c_str()); + size_t pos = text.find(replaceStr.c_str()); if (pos != std::string::npos) - labal_text.replace(pos, replaceStr.length(), "
"); - - elm_object_text_set(popup_, labal_text.c_str()); - + text.replace(pos, replaceStr.length(), "
"); + elm_object_text_set(popup_, text.c_str()); return true; } -void PermissionPopupManager::ClosePopup() { - if (!widget_win_) - return; - - evas_object_del(widget_win_); - popup_ = 0; - widget_win_ = 0; -} - -void PermissionPopupManager::HidePopup() { - if (popup_) - evas_object_hide(popup_); - - if (widget_win_) - evas_object_hide(widget_win_); -} - -PermissionPopup* PermissionPopupManager::GetPermissionPopup() { - return static_cast(eina_list_data_get(permission_popups_)); +void PermissionPopupManager::AddButtonToPopup(const char* name, + const char* text, + Evas_Smart_Cb callback, + bool focus) { + Evas_Object* button = elm_button_add(popup_); + elm_object_style_set(button, "popup"); + elm_object_domain_translatable_part_text_set(button, NULL, "WebKit", text); + elm_object_part_content_set(popup_, name, button); + evas_object_smart_callback_add(button, "clicked", callback, this); + if (focus) + evas_object_focus_set(button, true); } diff --git a/tizen_src/ewk/efl_integration/permission_popup_manager.h b/tizen_src/ewk/efl_integration/permission_popup_manager.h index 09fc2f5..83f9398 100644 --- a/tizen_src/ewk/efl_integration/permission_popup_manager.h +++ b/tizen_src/ewk/efl_integration/permission_popup_manager.h @@ -1,4 +1,4 @@ -// Copyright 2015 Samsung Electronics. All rights reserved. +// Copyright 2015-2020 Samsung Electronics. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,38 +6,47 @@ #define PermissionPopupManager_h #include -#include +#include -#include "permission_popup.h" +class PermissionPopup; class PermissionPopupManager { public: - PermissionPopupManager(Evas_Object* ); + PermissionPopupManager(Evas_Object* evas_object); ~PermissionPopupManager(); - bool IsDecided() const { return is_decided_; } - Evas_Object* GetEwebView() const { return eweb_view_; } - Evas_Object* GetTopWidget() const { return top_widget_; } - PermissionPopup* GetPermissionPopup(); - void AddPermissionRequest(PermissionPopup*); - void ClosePopup(); - void DeletePermissionRequest(PermissionPopup*); - void DeleteAllPermissionRequest(); - void HidePopup(); - void Decide(bool decided) { is_decided_ = decided; } + PermissionPopupManager(const PermissionPopupManager&) = delete; + PermissionPopupManager& operator=(const PermissionPopupManager&) = delete; + + void AddPermissionRequest(PermissionPopup* permission_popup); + void CancelPermissionRequest(); private: - bool SetLabelText(const std::string& message); - Evas_Object* CreatePopup(); - std::string GetTitle(PermissionPopup* popup); - void ShowPermissionPopup(PermissionPopup*); - - bool is_decided_; - Eina_List* permission_popups_; - Evas_Object* eweb_view_; - Evas_Object* popup_; - Evas_Object* widget_win_; - Evas_Object* top_widget_; + bool CreatePopup(); + bool SetupPopup(PermissionPopup* permission_popup); + void DeletePopup(); + bool SetPopupText(const std::string& message); + bool SetPopupTitle(const std::string& host); + void AddButtonToPopup(const char* name, + const char* text, + Evas_Smart_Cb callback, + bool focus); + void DeleteAllPermissionRequests(); + void DeletePermissionRequest(PermissionPopup* permission_popup); + void ShowPermissionPopup(PermissionPopup* permission_popup); + void Decide(bool decision); + + static void PermissionOkCallback(void* data, + Evas_Object* obj, + void* event_info); + static void PermissionCancelCallback(void* data, + Evas_Object* obj, + void* event_info); + + Eina_List* permission_popups_ = nullptr; + Evas_Object* popup_ = nullptr; + Evas_Object* top_widget_ = nullptr; + Evas_Object* evas_object_; }; #endif // PermissionPopupManager_h -- 2.7.4 From 9bbddf098cc162676d73b63c8394de57a3059d8b Mon Sep 17 00:00:00 2001 From: v-saha Date: Mon, 30 Jan 2023 17:25:51 +0530 Subject: [PATCH 14/16] [M108 Migration] Toggle screencast off in Web inspector by default When web inspector is launched & screencast is enabled by default, it occupies a large amount of space & is tangential to the earlier layouts we show to the user Reference: https://review.tizen.org/gerrit/278284 Change-Id: Iae31c76d277ca1015ba335ce57c79cf9d86b20fc Signed-off-by: v-saha --- .../devtools-frontend/src/front_end/panels/screencast/ScreencastApp.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/devtools-frontend/src/front_end/panels/screencast/ScreencastApp.ts b/third_party/devtools-frontend/src/front_end/panels/screencast/ScreencastApp.ts index 0c7eba2..6ef70c4 100644 --- a/third_party/devtools-frontend/src/front_end/panels/screencast/ScreencastApp.ts +++ b/third_party/devtools-frontend/src/front_end/panels/screencast/ScreencastApp.ts @@ -27,7 +27,7 @@ export class ScreencastApp implements Common.App.App, private screenCaptureModel?: SDK.ScreenCaptureModel.ScreenCaptureModel; private screencastView?: ScreencastView; constructor() { - this.enabledSetting = Common.Settings.Settings.instance().createSetting('screencastEnabled', true); + this.enabledSetting = Common.Settings.Settings.instance().createSetting('screencastEnabled', false); this.toggleButton = new UI.Toolbar.ToolbarToggle(i18nString(UIStrings.toggleScreencast), 'largeicon-phone'); this.toggleButton.setToggled(this.enabledSetting.get()); this.toggleButton.setEnabled(false); -- 2.7.4 From 0b215f76773ca207354e0f70b6d4e60e35202ad5 Mon Sep 17 00:00:00 2001 From: v-saha Date: Fri, 20 Jan 2023 11:58:15 +0530 Subject: [PATCH 15/16] [M108 Migration][API] Bring up autofill This patch migrates Autofill feature base code. References: https://review.tizen.org/gerrit/273586 https://review.tizen.org/gerrit/282263 Change-Id: Ie0dd8d81050e78dc812a8b6059aa2f6d795f8173 Signed-off-by: v-saha Signed-off-by: Ayush Kumar --- components/autofill/core/browser/BUILD.gn | 7 + .../autofill/core/browser/personal_data_manager.cc | 6 + .../autofill/core/common/autofill_switches.cc | 4 + .../autofill/core/common/autofill_switches.h | 7 + components/password_manager/core/browser/BUILD.gn | 8 +- .../renderer_host/render_process_host_impl.cc | 7 + .../renderer_host/render_widget_host_impl.cc | 12 + .../renderer_host/render_widget_host_impl.h | 2 + .../renderer_host/render_widget_host_view_aura.cc | 14 + .../renderer_host/render_widget_host_view_aura.h | 1 + .../renderer_host/render_widget_host_view_base.h | 1 + content/public/browser/content_browser_client.h | 10 + content/public/browser/web_contents_delegate.h | 2 + .../public/mojom/widget/platform_widget.mojom | 3 + .../renderer/core/frame/web_frame_widget_impl.cc | 15 + .../renderer/core/frame/web_frame_widget_impl.h | 2 + .../blink/renderer/platform/widget/widget_base.cc | 5 + .../blink/renderer/platform/widget/widget_base.h | 3 + .../renderer/platform/widget/widget_base_client.h | 2 + tizen_src/build/config/BUILD.gn | 3 + tizen_src/build/config/tizen_features.gni | 8 + .../chromium_impl/content/browser/browser_efl.gni | 1 + .../rwhv_aura_offscreen_helper_efl.cc | 12 +- .../renderer_host/rwhv_aura_offscreen_helper_efl.h | 2 + tizen_src/ewk/efl_integration/BUILD.gn | 12 +- .../autocomplete_history_manager_factory.cc | 66 ++++ .../autocomplete_history_manager_factory.h | 53 +++ .../browser/autofill/autofill_client_efl.cc | 380 ++++++++++++++++----- .../browser/autofill/autofill_client_efl.h | 169 ++++++--- .../autofill/personal_data_manager_factory.cc | 37 +- .../autofill/personal_data_manager_factory.h | 20 +- .../browser/autofill_popup_view_efl.cc | 140 +++++--- .../browser/autofill_popup_view_efl.h | 19 +- .../password_manager/password_helper_efl.cc | 106 ++++++ .../browser/password_manager/password_helper_efl.h | 43 +++ .../password_manager_client_efl.cc | 327 +++++++++++++++--- .../password_manager/password_manager_client_efl.h | 158 ++++++--- .../password_manager/password_store_factory.cc | 56 ++- .../password_manager/password_store_factory.h | 5 +- .../browser/webdata/web_data_service.cc | 16 +- .../browser/webdata/web_data_service.h | 3 - .../browser/webdata/web_data_service_factory.cc | 97 ++---- .../browser/webdata/web_data_service_factory.h | 33 +- .../ewk/efl_integration/browser_context_efl.cc | 25 +- tizen_src/ewk/efl_integration/command_line_efl.cc | 1 + .../efl_integration/content_browser_client_efl.cc | 36 ++ .../efl_integration/content_browser_client_efl.h | 7 + tizen_src/ewk/efl_integration/eweb_context.cc | 56 ++- tizen_src/ewk/efl_integration/eweb_context.h | 5 + .../ewk_context_form_autofill_profile_private.cc | 53 ++- .../efl_integration/private/ewk_context_private.cc | 10 + .../efl_integration/private/ewk_context_private.h | 4 + .../ewk/efl_integration/public/ewk_context.cc | 29 +- .../renderer/content_renderer_client_efl.cc | 29 +- .../renderer/render_frame_observer_efl.cc | 12 + .../renderer/render_frame_observer_efl.h | 22 +- .../efl_integration/web_contents_delegate_efl.cc | 47 ++- .../efl_integration/web_contents_delegate_efl.h | 5 +- ui/base/resource/resource_bundle.cc | 10 + 59 files changed, 1709 insertions(+), 519 deletions(-) create mode 100644 tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.cc create mode 100644 tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.h create mode 100644 tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.cc create mode 100644 tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.h diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 3181e98..444cae5 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn @@ -595,6 +595,13 @@ static_library("browser") { "//ui/native_theme:native_theme_browser", ] } + + if (use_efl) { + sources += [ + "logging/stub_log_manager.cc", + "logging/stub_log_manager.h", + ] + } } if (is_android) { diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 2482bb5..b056cd0 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc @@ -1033,7 +1033,13 @@ void PersonalDataManager::AddOfferDataForTest( void PersonalDataManager:: RemoveAutofillProfileByGUIDAndBlankCreditCardReference( const std::string& guid) { +#if defined(TIZEN_AUTOFILL_SUPPORT) + // TODO(djmix.kim) : This is a temporary solution for tct. + // It will be removed after integrating autofill_profile_validator_factory. + database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid); +#else RemoveProfileFromDB(guid); +#endif // Reset the billing_address_id of any card that refered to this profile. for (CreditCard* credit_card : GetCreditCards()) { diff --git a/components/autofill/core/common/autofill_switches.cc b/components/autofill/core/common/autofill_switches.cc index e0558df..7c76ec8 100644 --- a/components/autofill/core/common/autofill_switches.cc +++ b/components/autofill/core/common/autofill_switches.cc @@ -35,5 +35,9 @@ const char kShowAutofillSignatures[] = "show-autofill-signatures"; // Use the sandbox Online Wallet service URL (for developer testing). const char kWalletServiceUseSandbox[] = "wallet-service-use-sandbox"; +#if BUILDFLAG(IS_EFL) +const char kDisableAutofill[] = "disable-autofill"; +#endif + } // namespace switches } // namespace autofill diff --git a/components/autofill/core/common/autofill_switches.h b/components/autofill/core/common/autofill_switches.h index cdcea30..2e5cf7c 100644 --- a/components/autofill/core/common/autofill_switches.h +++ b/components/autofill/core/common/autofill_switches.h @@ -20,6 +20,13 @@ extern const char kShowAutofillTypePredictions[]; extern const char kShowAutofillSignatures[]; extern const char kWalletServiceUseSandbox[]; +// As of today TIZEN_AUTOFILL_SUPPORT is restricted to +// tizen_src/ewk/efl_integration only. Move this switch under +// TIZEN_AUTOFILL_SUPPORT when possible. +#if BUILDFLAG(IS_EFL) +extern const char kDisableAutofill[]; +#endif + } // namespace switches } // namespace autofill diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index d1d8246..a5ebbf8 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn @@ -12,7 +12,7 @@ if (is_android) { config("password_reuse_detection_config") { defines = [] - if (!is_ios) { + if (!is_ios && !use_efl) { defines += [ "ON_FOCUS_PING_ENABLED" ] } } @@ -399,6 +399,12 @@ static_library("browser") { "password_store_signin_notifier_impl.h", ] } + if (use_efl) { + sources += [ + "stub_credentials_filter.cc", + "stub_credentials_filter.h", + ] + } } source_set("capabilities") { diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 8fa72fe..e2ff206 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -204,6 +204,10 @@ #include "url/gurl.h" #include "url/origin.h" +#if BUILDFLAG(IS_EFL) +#include "components/autofill/core/common/autofill_switches.h" +#endif + #if BUILDFLAG(IS_ANDROID) #include "base/android/child_process_binding_types.h" #include "content/browser/android/java_interfaces_impl.h" @@ -3432,6 +3436,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kLacrosUseChromeosProtectedMedia, switches::kLacrosUseChromeosProtectedAv1, #endif +#if BUILDFLAG(IS_EFL) + autofill::switches::kDisableAutofill, +#endif }; renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames, std::size(kSwitchNames)); diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index e12f71f..bb004e7 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -988,6 +988,18 @@ void RenderWidgetHostImpl::OnGetContentSnapshot(int request_id, return; view_->DidGetContentSnapshot(bitmap, request_id); } + +void RenderWidgetHostImpl::UpdateFocusedNodeBounds() { + blink_widget_->UpdateFocusedNodeBounds( + base::BindOnce(&RenderWidgetHostImpl::OnGetFocusedNodeBounds, + weak_factory_.GetWeakPtr())); +} + +void RenderWidgetHostImpl::OnGetFocusedNodeBounds(const gfx::RectF& rect) { + if (!view_) + return; + view_->OnGetFocusedNodeBounds(rect); +} #endif blink::VisualProperties RenderWidgetHostImpl::GetInitialVisualProperties() { diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index aa77594..9e17ce7 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -444,6 +444,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl float page_scale_factor, int request_id); void OnGetContentSnapshot(int request_id, const SkBitmap& bitmap); + void UpdateFocusedNodeBounds(); + void OnGetFocusedNodeBounds(const gfx::RectF& rect); #endif // Returns true if the RenderWidget is hidden. diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 366c8a7..ff3614d 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -817,6 +817,13 @@ bool RenderWidgetHostViewAura::IsMouseLocked() { } gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() { +#if BUILDFLAG(IS_EFL) + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOffscreenRendering) && + offscreen_helper_) { + return offscreen_helper_->GetVisibleViewportSize(); + } +#endif gfx::Rect requested_rect(GetRequestedRendererSize()); requested_rect.Inset(insets_); return requested_rect.size(); @@ -2244,6 +2251,13 @@ void RenderWidgetHostViewAura::OnRenderFrameMetadataChangedAfterActivation( } } +#if BUILDFLAG(IS_EFL) +void RenderWidgetHostViewAura::OnGetFocusedNodeBounds(const gfx::RectF& rect) { + if (offscreen_helper_) + offscreen_helper_->OnGetFocusedNodeBounds(rect); +} +#endif + //////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostViewAura, private: diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index cacda97..ddf75f1 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -425,6 +425,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura size_t offset, const gfx::Range& range) override; void TextInputStateChanged(const ui::mojom::TextInputState& params) override; + void OnGetFocusedNodeBounds(const gfx::RectF& rect) override; #endif protected: diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 0207afa..5de160f 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h @@ -280,6 +280,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView { virtual void DidHandleKeyEvent(blink::WebInputEvent::Type input_event, bool processed) {} virtual void DidGetContentSnapshot(const SkBitmap& bitmap, int request_id) {} + virtual void OnGetFocusedNodeBounds(const gfx::RectF&) {} #endif // This method will reset the fallback to the first surface after navigation. diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 9b6c2b8..26d9551 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -1242,6 +1242,16 @@ class CONTENT_EXPORT ContentBrowserClient { RenderFrameHost& render_frame_host, blink::AssociatedInterfaceRegistry& associated_registry); +#if BUILDFLAG(IS_EFL) + // Content was unable to bind a receiver for this associated interface, so the + // embedder should try. Returns true if the |handle| was actually taken and + // bound; false otherwise. + virtual bool BindAssociatedReceiverFromFrame( + RenderFrameHost* render_frame_host, + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle); +#endif + // Handles an unhandled incoming interface binding request from the GPU // process. Called on the IO thread. virtual void BindGpuHostReceiver(mojo::GenericPendingReceiver receiver) {} diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index d31f0a8..71eb7b4 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h @@ -512,6 +512,8 @@ class CONTENT_EXPORT WebContentsDelegate { #if BUILDFLAG(IS_EFL) virtual void DidRenderFrame() {} + virtual void OnDidChangeFocusedNodeBounds( + const gfx::RectF& focused_node_bounds) {} #endif #if BUILDFLAG(IS_ANDROID) diff --git a/third_party/blink/public/mojom/widget/platform_widget.mojom b/third_party/blink/public/mojom/widget/platform_widget.mojom index 4dfb64b..428275c 100644 --- a/third_party/blink/public/mojom/widget/platform_widget.mojom +++ b/third_party/blink/public/mojom/widget/platform_widget.mojom @@ -114,6 +114,9 @@ interface Widget { GetContentSnapshot(gfx.mojom.Rect snapshot_rect, float page_scale_factor) => (skia.mojom.BitmapN32? bitmap); + [EnableIf=is_efl] + UpdateFocusedNodeBounds() => (gfx.mojom.RectF rect); + // Informs the widget that it was hidden. This allows it to reduce its // resource utilization, and will cancel any pending // RecordContentToVisibleTimeRequest that was set with WasShown or diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index db9d088..9737478 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -4153,6 +4153,21 @@ void WebFrameWidgetImpl::GetContentSnapshot(const gfx::Rect& snapshot_rect, page_scale_factor * snapshot->width(), page_scale_factor * snapshot->height()); } + +gfx::RectF WebFrameWidgetImpl::UpdateFocusedNodeBounds() { + Element* element = FocusedElement(); + if (!element) + return gfx::RectF(); + + WebElement web_element = WebElement(element); + + if (!web_element.IsNull() && web_element.IsElementNode()) { + gfx::RectF focused_node_bounds_scaled = gfx::ScaleRect( + gfx::RectF(web_element.BoundsInWidget()), View()->PageScaleFactor()); + return focused_node_bounds_scaled; + } + return gfx::RectF(); +} #endif void WebFrameWidgetImpl::OrientationChanged() { diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index 57c0357..cffaa63 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h @@ -706,6 +706,8 @@ class CORE_EXPORT WebFrameWidgetImpl void GetContentSnapshot(const gfx::Rect& snapshot_rect, float page_scale_factor, SkBitmap* snapshot) override; + + gfx::RectF UpdateFocusedNodeBounds() override; #endif void OrientationChanged() override; void DidUpdateSurfaceAndScreen( diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index d2fca1a..59a7ed3 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc @@ -463,6 +463,11 @@ void WidgetBase::GetContentSnapshot(const gfx::Rect& snapshot_rect, &content_snapshot); std::move(callback).Run(content_snapshot); } + +void WidgetBase::UpdateFocusedNodeBounds( + UpdateFocusedNodeBoundsCallback callback) { + std::move(callback).Run(client_->UpdateFocusedNodeBounds()); +} #endif void WidgetBase::WasHidden() { diff --git a/third_party/blink/renderer/platform/widget/widget_base.h b/third_party/blink/renderer/platform/widget/widget_base.h index 1ba4b68..e175340 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.h +++ b/third_party/blink/renderer/platform/widget/widget_base.h @@ -140,6 +140,9 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget, void GetContentSnapshot(const gfx::Rect& snapshot_rect, float page_scale_factor, GetContentSnapshotCallback callback) override; + + void UpdateFocusedNodeBounds( + UpdateFocusedNodeBoundsCallback callback) override; #endif void WasHidden() override; void WasShown(bool was_evicted, diff --git a/third_party/blink/renderer/platform/widget/widget_base_client.h b/third_party/blink/renderer/platform/widget/widget_base_client.h index d952389..7fc0466 100644 --- a/third_party/blink/renderer/platform/widget/widget_base_client.h +++ b/third_party/blink/renderer/platform/widget/widget_base_client.h @@ -173,6 +173,8 @@ class WidgetBaseClient { virtual void GetContentSnapshot(const gfx::Rect& snapshot_rect, float page_scale_factor, SkBitmap* snapshot) {} + + virtual gfx::RectF UpdateFocusedNodeBounds() { return gfx::RectF(); } #endif // Convert screen coordinates to device emulated coordinates (scaled diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index c8ad9c5..fd06c45 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -54,6 +54,9 @@ config("tizen_feature_flags") { if (tizen_multimedia) { defines += [ "TIZEN_MULTIMEDIA" ] } + if (tizen_autofill_support) { + defines += [ "TIZEN_AUTOFILL_SUPPORT" ] + } if (use_ttrace) { defines += [ "USE_TTRACE" ] if (use_ttrace_chrome_trace) { diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index de32d58..f8df89b 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -50,6 +50,14 @@ declare_args() { tizen_multimedia = false tizen_tbm_support = false tizen_web_speech_recognition = false + + tizen_autofill_support = false +} + +if (tizen_product_tv) { + tizen_autofill_support = false +} else { + tizen_autofill_support = true } if (use_ttrace) { diff --git a/tizen_src/chromium_impl/content/browser/browser_efl.gni b/tizen_src/chromium_impl/content/browser/browser_efl.gni index 260330f..5338162 100644 --- a/tizen_src/chromium_impl/content/browser/browser_efl.gni +++ b/tizen_src/chromium_impl/content/browser/browser_efl.gni @@ -70,6 +70,7 @@ if (tizen_web_speech_recognition) { ############################################################################## external_content_browser_efl_deps = [ + "//components/autofill/core/common", "//tizen_src/chromium_impl/edje_resources:edje_resources_efl", "//tizen_src/chromium_impl/efl:window-factory", "//ui/gl:gl", diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc index edf0ed4..97a72d5 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc @@ -1095,9 +1095,10 @@ const gfx::Size RWHVAuraOffscreenHelperEfl::GetScrollableSize() const { if (scaled_contents_size_.width() > viewport_size.width()) { width = scaled_contents_size_.width() - viewport_size.width(); // When device scale factor is larger than 1.0, content size is ceiled up - // during converting pixel to dip in RenderWidgetHostViewEfl::GetViewBounds. - // So we ignore when scroll size is 1. It is also same for height. - // Please refer to https://review.tizen.org/gerrit/#/c/74044/. + // during converting pixel to dip in + // RWHVAuraOffscreenHelperEfl::GetViewBounds. So we ignore when + // scroll size is 1. It is also same for height. Please refer to + // https://review.tizen.org/gerrit/#/c/74044/. if (device_scale_factor_ > 1.0f && width == 1) width = 0; } @@ -1110,4 +1111,9 @@ const gfx::Size RWHVAuraOffscreenHelperEfl::GetScrollableSize() const { return gfx::Size(width, height); } +void RWHVAuraOffscreenHelperEfl::OnGetFocusedNodeBounds( + const gfx::RectF& rect) { + web_contents_->GetDelegate()->OnDidChangeFocusedNodeBounds(rect); +} + } // namespace content diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h index 1f24974..5bba8fb 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h @@ -66,6 +66,8 @@ class CONTENT_EXPORT RWHVAuraOffscreenHelperEfl { gfx::Rect GetViewBounds(); void SetCustomViewportSize(const gfx::Size& size); gfx::Size GetPhysicalBackingSize() const; + void OnGetFocusedNodeBounds(const gfx::RectF& rect); + gfx::Rect GetViewBoundsInPix() const; const gfx::Size GetScrollableSize() const; void SetScaledContentSize(const gfx::SizeF& size) { diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index feee814..d5e87fb 100755 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -6,10 +6,6 @@ import("//base/allocator/allocator.gni") import("//build/config/features.gni") import("//printing/buildflags/buildflags.gni") -# [M48_2564] Temporary disabling the flag for switching to new chromium -# FIXME: http://web.sec.samsung.net/bugzilla/show_bug.cgi?id=15382 -tizen_autofill_support = false - # Components used to auto generate CHROMIUM_VERSION preprocessor define. version_file = "//chrome/VERSION" version_script = "//build/util/version.py" @@ -155,10 +151,6 @@ shared_library("chromium-ewk") { public_configs += [ "../../build:capi-system-device-public" ] } - if (tizen_autofill_support) { - defines = [ "TIZEN_AUTOFILL_SUPPORT=true" ] - } - if (use_allocator == "tcmalloc") { deps += [ "//base/allocator" ] } @@ -293,6 +285,8 @@ shared_library("chromium-ewk") { "web_contents_view_delegate_ewk.h", # Make use of Android webview"s simplified pref class. + "browser/autofill/autocomplete_history_manager_factory.cc", + "browser/autofill/autocomplete_history_manager_factory.h", "browser/autofill/autofill_client_efl.cc", "browser/autofill/autofill_client_efl.h", "browser/autofill/personal_data_manager_factory.cc", @@ -325,6 +319,8 @@ shared_library("chromium-ewk") { "browser/notification/notification_controller_efl.h", "browser/notification/notification_helper.cc", "browser/notification/notification_helper.h", + "browser/password_manager/password_helper_efl.cc", + "browser/password_manager/password_helper_efl.h", "browser/password_manager/password_manager_client_efl.cc", "browser/password_manager/password_manager_client_efl.h", "browser/password_manager/password_store_factory.cc", diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.cc b/tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.cc new file mode 100644 index 0000000..692b5d1 --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.cc @@ -0,0 +1,66 @@ +// Copyright 2020 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(TIZEN_AUTOFILL_SUPPORT) + +#include "browser/autofill/autocomplete_history_manager_factory.h" + +#include "browser/webdata/web_data_service_factory.h" +#include "components/autofill/core/browser/autocomplete_history_manager.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/browser_context.h" + +namespace autofill { + +// static +AutocompleteHistoryManagerFactoryEfl* +AutocompleteHistoryManagerFactoryEfl::GetInstance() { + return base::Singleton::get(); +} + +void AutocompleteHistoryManagerFactoryEfl::AutocompleteHistoryManagerAdd( + content::BrowserContext* ctx) { + DCHECK(ctx); + + if (!ctx) + return; + + uint64_t uniqueId = reinterpret_cast(ctx); + auto* mgr = autocomplete_history_manager_id_map_.Lookup(uniqueId); + if (!mgr) { + mgr = new AutocompleteHistoryManager(); + scoped_refptr autofill_webdata_service = + WebDataServiceFactoryEfl::GetInstance()->GetAutofillWebDataForProfile(); + mgr->Init(autofill_webdata_service, user_prefs::UserPrefs::Get(ctx), + ctx->IsOffTheRecord()); + + autocomplete_history_manager_id_map_.AddWithID(mgr, uniqueId); + } +} + +void AutocompleteHistoryManagerFactoryEfl::AutocompleteHistoryManagerRemove( + content::BrowserContext* ctx) { + uint64_t uniqueId = reinterpret_cast(ctx); + autocomplete_history_manager_id_map_.Remove(uniqueId); +} + +AutocompleteHistoryManager* +AutocompleteHistoryManagerFactoryEfl::AutocompleteHistoryManagerForContext( + content::BrowserContext* ctx) { + uint64_t uniqueId = reinterpret_cast(ctx); + return autocomplete_history_manager_id_map_.Lookup(uniqueId); +} + +AutocompleteHistoryManagerFactoryEfl::AutocompleteHistoryManagerFactoryEfl() {} + +AutocompleteHistoryManagerFactoryEfl::~AutocompleteHistoryManagerFactoryEfl() { + if (!autocomplete_history_manager_id_map_.IsEmpty()) + LOG(ERROR) << "Client didn't destroy all WebView objects" + << " before calling ewk_shutdown"; +} + +} // namespace autofill + +#endif // TIZEN_AUTOFILL_SUPPORT diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.h b/tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.h new file mode 100644 index 0000000..e9c381b --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/autofill/autocomplete_history_manager_factory.h @@ -0,0 +1,53 @@ +// Copyright 2020 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_ +#define AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_ + +#if defined(TIZEN_AUTOFILL_SUPPORT) +#include "base/compiler_specific.h" +#include "base/containers/id_map.h" +#include "base/memory/ref_counted.h" +#include "base/memory/singleton.h" + +namespace base { +template +struct DefaultSingletonTraits; +} + +namespace content { +class BrowserContext; +} + +namespace autofill { + +class AutocompleteHistoryManager; + +class AutocompleteHistoryManagerFactoryEfl { + public: + static AutocompleteHistoryManagerFactoryEfl* GetInstance(); + + void AutocompleteHistoryManagerAdd(content::BrowserContext* ctx); + void AutocompleteHistoryManagerRemove(content::BrowserContext* ctx); + AutocompleteHistoryManager* AutocompleteHistoryManagerForContext( + content::BrowserContext* ctx); + + private: + friend struct base::DefaultSingletonTraits< + AutocompleteHistoryManagerFactoryEfl>; + + AutocompleteHistoryManagerFactoryEfl(); + ~AutocompleteHistoryManagerFactoryEfl(); + + AutocompleteHistoryManagerFactoryEfl( + const AutocompleteHistoryManagerFactoryEfl&) = delete; + AutocompleteHistoryManagerFactoryEfl& operator=( + const AutocompleteHistoryManagerFactoryEfl&) = delete; + + base::IDMap autocomplete_history_manager_id_map_; +}; + +} // namespace autofill +#endif // TIZEN_AUTOFILL_SUPPORT +#endif // AUTOFILL_AUTOCOMPLETE_HISTORY_MANAGER_FACTORY_H_ diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.cc b/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.cc index 63fc5a8..5252edf 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.cc @@ -7,34 +7,35 @@ #include "browser/autofill/autofill_client_efl.h" #include "base/logging.h" -#include "base/prefs/pref_service.h" #include "base/strings/utf_string_conversions.h" +#include "browser/autofill/autocomplete_history_manager_factory.h" #include "browser/autofill/personal_data_manager_factory.h" -#include "browser/webdata/web_data_service_factory.h" #include "browser/password_manager/password_manager_client_efl.h" -#include "components/autofill/content/common/autofill_messages.h" -#include "components/autofill/core/common/autofill_pref_names.h" +#include "browser_context_efl.h" +#include "common/render_messages_ewk.h" +#include "components/autofill/content/browser/content_autofill_driver.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_client.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/autofill/core/common/autofill_prefs.h" +#include "components/prefs/pref_service.h" #include "components/user_prefs/user_prefs.h" -#include "content/public/browser/render_view_host.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/ssl_status.h" +#include "private/ewk_context_private.h" #include "tizen/system_info.h" +#include "ui/display/screen.h" +#include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/rect.h" -#include "private/ewk_context_private.h" - -DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::AutofillClientEfl); - namespace autofill { AutofillClientEfl::AutofillClientEfl(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) - , web_contents_(web_contents) - , webview_(NULL) - , database_(WebDataServiceFactory::GetInstance()->GetAutofillWebDataForProfile()) - , popup_controller_(NULL) { + : content::WebContentsObserver(web_contents), + content::WebContentsUserData(*web_contents), + web_contents_(web_contents) { DCHECK(web_contents); } @@ -44,17 +45,13 @@ AutofillClientEfl::~AutofillClientEfl() { popup_controller_ = NULL; } -void AutofillClientEfl::TabActivated() { - NOTIMPLEMENTED(); -} - PersonalDataManager* AutofillClientEfl::GetPersonalDataManager() { if (webview_ && webview_->context()) { content::BrowserContextEfl* ctx = webview_->context()->GetImpl()->browser_context(); - PersonalDataManagerFactory* factory = - PersonalDataManagerFactory::GetInstance(); + PersonalDataManagerFactoryEfl* factory = + PersonalDataManagerFactoryEfl::GetInstance(); return factory->PersonalDataManagerForContext(ctx); } @@ -62,11 +59,17 @@ PersonalDataManager* AutofillClientEfl::GetPersonalDataManager() { return NULL; } -scoped_refptr AutofillClientEfl::GetDatabase() { - return database_; +PrefService* AutofillClientEfl::GetPrefs() { + if (webview_ && webview_->context()) { + content::BrowserContextEfl* ctx = + webview_->context()->GetImpl()->browser_context(); + return user_prefs::UserPrefs::Get(ctx); + } + + return NULL; } -PrefService* AutofillClientEfl::GetPrefs() { +const PrefService* AutofillClientEfl::GetPrefs() const { if (webview_ && webview_->context()) { content::BrowserContextEfl* ctx = webview_->context()->GetImpl()->browser_context(); @@ -76,74 +79,60 @@ PrefService* AutofillClientEfl::GetPrefs() { return NULL; } -void AutofillClientEfl::ShowAutofillSettings() { +syncer::SyncService* AutofillClientEfl::GetSyncService() { NOTIMPLEMENTED(); + return nullptr; } -void AutofillClientEfl::ConfirmSaveCreditCardLocally( - const base::Closure& callback) { +void AutofillClientEfl::ShowAutofillSettings(bool show_credit_card_settings) { NOTIMPLEMENTED(); } -void AutofillClientEfl::ConfirmSaveCreditCardToCloud( - const base::Closure& callback, - scoped_ptr legal_message) { +void AutofillClientEfl::ConfirmSaveCreditCardLocally( + const CreditCard& card, + SaveCreditCardOptions options, + LocalSaveCardPromptCallback callback) { NOTIMPLEMENTED(); } -void AutofillClientEfl::LoadRiskData( - const base::OnceCallback& callback) { +void AutofillClientEfl::ConfirmSaveCreditCardToCloud( + const CreditCard& card, + const LegalMessageLines& legal_message_lines, + SaveCreditCardOptions options, + UploadSaveCardPromptCallback callback) { NOTIMPLEMENTED(); } -void AutofillClientEfl::ShowRequestAutocompleteDialog( - const autofill::FormData& form, - content::RenderFrameHost* rfh, - const ResultCallback& callback) { - HideRequestAutocompleteDialog(); +void AutofillClientEfl::ConfirmCreditCardFillAssist( + const CreditCard& card, + base::OnceClosure callback) { NOTIMPLEMENTED(); } void AutofillClientEfl::ShowAutofillPopup( - const gfx::RectF& element_bounds, - base::i18n::TextDirection text_direction, - const std::vector& suggestions, + const PopupOpenArgs& open_args, base::WeakPtr delegate) { DCHECK(web_contents_); // Do not show sugestions when Remember form data is disabled if (!IsAutocompleteSavingEnabled()) return; - int x, y; - double scale_factor = 1.0; - - if (IsMobileProfile() || IsWearableProfile()) { - scale_factor = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(). - device_scale_factor(); - } else if (IsTvProfile()) { - scale_factor = webview_->GetScale(); - } - -#if BUILDFLAG(IS_TIZEN) - evas_object_geometry_get(webview_->evas_object(), &x, &y, 0, 0); - gfx::Rect client_area = web_contents_->GetContainerBounds(); - gfx::RectF element_bounds_in_screen_space = element_bounds + - client_area.OffsetFromOrigin() + gfx::Vector2d(x/scale_factor, y/scale_factor); -#endif if (GetOrCreatePopupController()) { - popup_controller_->InitFormData(suggestions, delegate); + popup_controller_->InitFormData(open_args.suggestions, delegate); #if BUILDFLAG(IS_TIZEN) - popup_controller_->UpdateFormDataPopup(element_bounds_in_screen_space); + popup_controller_->UpdateFormDataPopup( + GetElementBoundsInScreen(open_args.element_bounds)); #else - popup_controller_->UpdateFormDataPopup(element_bounds); + popup_controller_->UpdateFormDataPopup(open_args.element_bounds); #endif popup_controller_->Show(); } } void AutofillClientEfl::ShowUnmaskPrompt( - const autofill::CreditCard& card, - base::WeakPtr delegate) { + const CreditCard& card, + AutofillClient::UnmaskCardReason reason, + base::WeakPtr delegate) { NOTIMPLEMENTED(); } @@ -161,40 +150,63 @@ bool AutofillClientEfl::HasCreditCardScanFeature() { return false; } -void AutofillClientEfl::ScanCreditCard( - const CreditCardScanCallback& callback) { +void AutofillClientEfl::ScanCreditCard(CreditCardScanCallback callback) { NOTIMPLEMENTED(); } -void AutofillClientEfl::OnFirstUserGestureObserved() { - web_contents_->SendToAllFrames( - new AutofillMsg_FirstUserGestureObservedInTab(routing_id())); -} - -bool AutofillClientEfl::IsContextSecure(const GURL& form_origin) { +bool AutofillClientEfl::IsContextSecure() const { + content::SSLStatus ssl_status; content::NavigationEntry* navigation_entry = web_contents_->GetController().GetLastCommittedEntry(); if (!navigation_entry) return false; - content::SSLStatus ssl_status = navigation_entry->GetSSL(); + ssl_status = navigation_entry->GetSSL(); // Note: If changing the implementation below, also change // AwAutofillClient::IsContextSecure. See crbug.com/505388 - return - ssl_status.security_style == content::SECURITY_STYLE_AUTHENTICATED && - ssl_status.content_status == content::SSLStatus::NORMAL_CONTENT; + return navigation_entry->GetURL().SchemeIsCryptographic() && + ssl_status.certificate && + (!net::IsCertStatusError(ssl_status.cert_status)) && + !(ssl_status.content_status & + content::SSLStatus::RAN_INSECURE_CONTENT); } -IdentityProvider* AutofillClientEfl::GetIdentityProvider() { +signin::IdentityManager* AutofillClientEfl::GetIdentityManager() { + NOTIMPLEMENTED(); return nullptr; } -rappor::RapporService* AutofillClientEfl::GetRapporService() { +ukm::UkmRecorder* AutofillClientEfl::GetUkmRecorder() { + NOTIMPLEMENTED(); + return nullptr; +} + +ukm::SourceId AutofillClientEfl::GetUkmSourceId() { + NOTIMPLEMENTED(); + return ukm::kInvalidSourceId; +} + +AddressNormalizer* AutofillClientEfl::GetAddressNormalizer() { NOTIMPLEMENTED(); return nullptr; } -void AutofillClientEfl::HideAutofillPopup() { +security_state::SecurityLevel +AutofillClientEfl::GetSecurityLevelForUmaHistograms() { + NOTIMPLEMENTED(); + return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; +} + +bool AutofillClientEfl::AreServerCardsSupported() const { + NOTIMPLEMENTED(); + return false; +} + +void AutofillClientEfl::ExecuteCommand(int id) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::HideAutofillPopup(PopupHidingReason reason) { if (popup_controller_) { popup_controller_->Hide(); } @@ -207,8 +219,8 @@ bool AutofillClientEfl::IsAutocompleteEnabled() { } void AutofillClientEfl::PropagateAutofillPredictions( - content::RenderFrameHost* rfh, - const std::vector& forms) { + autofill::AutofillDriver* autofill_driver, + const std::vector& forms) { NOTIMPLEMENTED(); } @@ -218,24 +230,68 @@ bool AutofillClientEfl::IsAutocompleteSavingEnabled() { return false; } -void AutofillClientEfl::HideRequestAutocompleteDialog() { - if (popup_controller_) { - popup_controller_->Hide(); - } +FormDataImporter* AutofillClientEfl::GetFormDataImporter() { + NOTIMPLEMENTED(); + return nullptr; } -void AutofillClientEfl::DidNavigateMainFrame(const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { - HideRequestAutocompleteDialog(); +StrikeDatabase* AutofillClientEfl::GetStrikeDatabase() { + NOTIMPLEMENTED(); + return nullptr; +} + +void AutofillClientEfl::ShowLocalCardMigrationDialog( + base::OnceClosure show_migration_dialog_closure) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::ConfirmMigrateLocalCardToCloud( + std::unique_ptr legal_message, + const std::string& user_email, + const std::vector& migratable_credit_cards, + LocalCardMigrationCallback start_migrating_cards_callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::ShowLocalCardMigrationResults( + const bool has_server_error, + const std::u16string& tip_message, + const std::vector& migratable_credit_cards, + MigrationDeleteCardCallback delete_local_card_callback) { + NOTIMPLEMENTED(); +} + +AutocompleteHistoryManager* AutofillClientEfl::GetAutocompleteHistoryManager() { + if (!webview_) + return nullptr; + + content::BrowserContextEfl* ctx = + webview_->context()->GetImpl()->browser_context(); + auto* factory = AutocompleteHistoryManagerFactoryEfl::GetInstance(); + return factory->AutocompleteHistoryManagerForContext(ctx); +} + +payments::PaymentsClient* AutofillClientEfl::GetPaymentsClient() { + NOTIMPLEMENTED(); + return nullptr; } void AutofillClientEfl::ShowSavePasswordPopup( - scoped_ptr form_to_save) { + std::unique_ptr form_to_save) { if (GetOrCreatePopupController()) - popup_controller_->ShowSavePasswordPopup(form_to_save.Pass()); + popup_controller_->ShowSavePasswordPopup(std::move(form_to_save)); +} + +void AutofillClientEfl::PrimaryMainFrameWasResized(bool width_changed) { + // Ignore virtual keyboard showing and hiding a strip of suggestions. + if (!width_changed) + return; + + HideAutofillPopup(PopupHidingReason::kNavigation); } void AutofillClientEfl::WebContentsDestroyed() { - HideAutofillPopup(); + HideAutofillPopup(PopupHidingReason::kViewDestroyed); } AutofillPopupViewEfl * AutofillClientEfl::GetOrCreatePopupController() { @@ -250,6 +306,154 @@ void AutofillClientEfl::DidFillOrPreviewField( NOTIMPLEMENTED(); } +bool AutofillClientEfl::ShouldShowSigninPromo() { + NOTIMPLEMENTED(); + return false; +} + +void AutofillClientEfl::UpdateAutofillIfRequired() { + if (popup_controller_ && popup_controller_->IsVisible()) { + auto* rwhva = static_cast( + web_contents_->GetRenderWidgetHostView()); + if (rwhva) + rwhva->host()->UpdateFocusedNodeBounds(); + } +} + +void AutofillClientEfl::DidChangeFocusedNodeBounds( + const gfx::RectF& node_bounds) { + if (popup_controller_) + popup_controller_->UpdateLocation(GetElementBoundsInScreen(node_bounds)); +} + +gfx::RectF AutofillClientEfl::GetElementBoundsInScreen( + const gfx::RectF& element_bounds) { + auto* rwhva = static_cast( + web_contents_->GetRenderWidgetHostView()); + if (!rwhva) + return gfx::RectF(); + + double scale_factor = 1.0; + if (IsTvProfile()) { + scale_factor = webview_->GetScale(); + } else { + scale_factor = + display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); + } + + gfx::Vector2d view_offset = + gfx::ToEnclosingRect( + gfx::ConvertRectToDips( + rwhva->offscreen_helper()->GetViewBoundsInPix(), scale_factor)) + .OffsetFromOrigin(); + return element_bounds + view_offset; +} + +void AutofillClientEfl::ConfirmMigrateLocalCardToCloud( + const LegalMessageLines& legal_message_lines, + const std::string& user_email, + const std::vector& migratable_credit_cards, + LocalCardMigrationCallback start_migrating_cards_callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::ShowWebauthnOfferDialog( + WebauthnDialogCallback offer_dialog_callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::ShowWebauthnVerifyPendingDialog( + WebauthnDialogCallback verify_pending_dialog_callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::UpdateWebauthnOfferDialogWithError() { + NOTIMPLEMENTED(); +} + +bool AutofillClientEfl::CloseWebauthnDialog() { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::ConfirmSaveUpiIdLocally( + const std::string& upi_id, + base::OnceCallback callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::OfferVirtualCardOptions( + const std::vector& candidates, + base::OnceCallback callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::CreditCardUploadCompleted(bool card_saved) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::PinPopupView() { + NOTIMPLEMENTED(); +} + +AutofillClient::PopupOpenArgs AutofillClientEfl::GetReopenPopupArgs() const { + NOTIMPLEMENTED(); + return {}; +} + +base::span AutofillClientEfl::GetPopupSuggestions() const { + NOTIMPLEMENTED(); + return base::span(); +} + +void AutofillClientEfl::UpdatePopup(const std::vector& suggestions, + PopupType popup_type) { + NOTIMPLEMENTED(); +} + +const GURL& AutofillClientEfl::GetLastCommittedPrimaryMainFrameURL() const { + DCHECK(web_contents_); + content::NavigationEntry* entry = + web_contents_->GetController().GetLastCommittedEntry(); + if (!entry) + return GURL::EmptyGURL(); + + return entry->GetURL(); +} + +std::vector +AutofillClientEfl::GetAllowedMerchantsForVirtualCards() { + NOTIMPLEMENTED(); + return std::vector(); +} + +std::vector +AutofillClientEfl::GetAllowedBinRangesForVirtualCards() { + NOTIMPLEMENTED(); + return std::vector(); +} + +const translate::LanguageState* AutofillClientEfl::GetLanguageState() { + NOTIMPLEMENTED(); + return nullptr; +} +translate::TranslateDriver* AutofillClientEfl::GetTranslateDriver() { + NOTIMPLEMENTED(); + return nullptr; +} +void AutofillClientEfl::ConfirmSaveAddressProfile( + const AutofillProfile& profile, + const AutofillProfile* original_profile, + AutofillClient::SaveAddressProfilePromptOptions options, + AddressProfileSavePromptCallback callback) { + NOTIMPLEMENTED(); +} + +void AutofillClientEfl::LoadRiskData( + base::OnceCallback callback) { + NOTIMPLEMENTED(); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(AutofillClientEfl); } // namespace autofill #endif // TIZEN_AUTOFILL_SUPPORT diff --git a/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.h b/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.h index 0a270e9..fc70981 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.h +++ b/tizen_src/ewk/efl_integration/browser/autofill/autofill_client_efl.h @@ -6,17 +6,17 @@ #if defined(TIZEN_AUTOFILL_SUPPORT) -#include "eweb_view.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/i18n/rtl.h" #include "base/memory/weak_ptr.h" +#include "browser/autofill_popup_view_efl.h" #include "components/autofill/core/browser/autofill_client.h" -#include "components/autofill/core/browser/autofill_metrics.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/password_manager/core/browser/password_form_manager.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" -#include "autofill_popup_view_efl.h" +#include "eweb_view.h" namespace content { struct FrameNavigateParams; @@ -26,80 +26,153 @@ class WebContents; namespace autofill { -struct FormData; - -// Chrome implementation of AutofillManagerDelegate. class AutofillClientEfl - : public content::WebContentsUserData, - public autofill::AutofillClient, + : public AutofillClient, + public content::WebContentsUserData, public content::WebContentsObserver { public: - virtual ~AutofillClientEfl(); + ~AutofillClientEfl() override; AutofillClientEfl(const AutofillClientEfl&) = delete; AutofillClientEfl& operator=(const AutofillClientEfl&) = delete; - // Called when the tab corresponding to |this| instance is activated. - void TabActivated(); - // AutofillManagerDelegate implementation. + // AutofillClient implementation. PersonalDataManager* GetPersonalDataManager() override; - scoped_refptr GetDatabase() override; PrefService* GetPrefs() override; - void HideRequestAutocompleteDialog() override; - void ShowAutofillSettings() override; - void ConfirmSaveCreditCardLocally(const base::Closure& callback) override; + virtual const PrefService* GetPrefs() const override; + syncer::SyncService* GetSyncService() override; + void ShowAutofillSettings(bool show_credit_card_settings) override; + void ConfirmSaveCreditCardLocally( + const CreditCard& card, + SaveCreditCardOptions options, + LocalSaveCardPromptCallback callback) override; void ConfirmSaveCreditCardToCloud( - const base::Closure& callback, - scoped_ptr legal_message) override; - void LoadRiskData( - const base::OnceCallback& callback) override; - void ShowRequestAutocompleteDialog( - const autofill::FormData& form, - content::RenderFrameHost* rfh, - const ResultCallback& callback) override; + const CreditCard& card, + const LegalMessageLines& legal_message_lines, + SaveCreditCardOptions options, + UploadSaveCardPromptCallback callback) override; + void ConfirmCreditCardFillAssist(const CreditCard& card, + base::OnceClosure callback) override; void ShowAutofillPopup( - const gfx::RectF& element_bounds, - base::i18n::TextDirection text_direction, - const std::vector& suggestions, + const PopupOpenArgs& open_args, base::WeakPtr delegate) override; - void ShowUnmaskPrompt( - const autofill::CreditCard& card, - base::WeakPtr delegate) override; + void ShowUnmaskPrompt(const CreditCard& card, + AutofillClient::UnmaskCardReason reason, + base::WeakPtr delegate) override; void UpdateAutofillPopupDataListValues( const std::vector& values, const std::vector& labels) override; void OnUnmaskVerificationResult(PaymentsRpcResult result) override; bool HasCreditCardScanFeature() override; - void ScanCreditCard(const CreditCardScanCallback& callback) override; - void OnFirstUserGestureObserved() override; - bool IsContextSecure(const GURL& form_origin) override; + void ScanCreditCard(CreditCardScanCallback callback) override; + bool IsContextSecure() const override; + + signin::IdentityManager* GetIdentityManager() override; + ukm::UkmRecorder* GetUkmRecorder() override; + ukm::SourceId GetUkmSourceId() override; + AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; - IdentityProvider* GetIdentityProvider() override; - rappor::RapporService* GetRapporService() override; - void HideAutofillPopup() override; + bool AreServerCardsSupported() const override; + void ExecuteCommand(int id) override; + void HideAutofillPopup(PopupHidingReason reason) override; bool IsAutocompleteEnabled() override; void PropagateAutofillPredictions( - content::RenderFrameHost* rfh, - const std::vector& forms) override; - bool IsAutocompleteSavingEnabled(); + autofill::AutofillDriver* autofill_driver, + const std::vector& forms) override; + void DidFillOrPreviewField(const std::u16string& autofilled_value, + const std::u16string& profile_full_name) override; + bool ShouldShowSigninPromo() override; + void ConfirmMigrateLocalCardToCloud( + const LegalMessageLines& legal_message_lines, + const std::string& user_email, + const std::vector& migratable_credit_cards, + LocalCardMigrationCallback start_migrating_cards_callback) override; + void ShowWebauthnOfferDialog( + WebauthnDialogCallback offer_dialog_callback) override; + void ShowWebauthnVerifyPendingDialog( + WebauthnDialogCallback verify_pending_dialog_callback) override; + void UpdateWebauthnOfferDialogWithError() override; + bool CloseWebauthnDialog() override; + void ConfirmSaveUpiIdLocally( + const std::string& upi_id, + base::OnceCallback callback) override; + void OfferVirtualCardOptions( + const std::vector& candidates, + base::OnceCallback callback) override; + void CreditCardUploadCompleted(bool card_saved) override; + void PinPopupView() override; + PopupOpenArgs GetReopenPopupArgs() const override; + base::span GetPopupSuggestions() const override; + void UpdatePopup(const std::vector& suggestions, + PopupType popup_type) override; + const GURL& GetLastCommittedPrimaryMainFrameURL() const override; + const translate::LanguageState* GetLanguageState() override; + translate::TranslateDriver* GetTranslateDriver() override; + std::vector GetAllowedMerchantsForVirtualCards() override; + std::vector GetAllowedBinRangesForVirtualCards() override; + void ConfirmSaveAddressProfile( + const AutofillProfile& profile, + const AutofillProfile* original_profile, + AutofillClient::SaveAddressProfilePromptOptions options, + AddressProfileSavePromptCallback callback) override; + payments::PaymentsClient* GetPaymentsClient() override; + url::Origin GetLastCommittedPrimaryMainFrameOrigin() const {}; + bool IsFastCheckoutSupported() {} + bool IsFastCheckoutTriggerForm(const FormData& form, + const FormFieldData& field) {} + bool FastCheckoutScriptSupportsConsentlessExecution( + const url::Origin& origin) {} + bool FastCheckoutClientSupportsConsentlessExecution() {} + bool ShowFastCheckout(base::WeakPtr delegate) {} + + bool IsTouchToFillCreditCardSupported() {} + void HideFastCheckout() {} + bool ShowTouchToFillCreditCard(base::WeakPtr delegate) {} + void OpenPromoCodeOfferDetailsURL(const GURL& url) {} + + bool IsPasswordManagerEnabled() {} + void HideTouchToFillCreditCard() {} + // content::WebContentsObserver implementation. - void DidNavigateMainFrame(const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) override; + void PrimaryMainFrameWasResized(bool width_changed) override; void WebContentsDestroyed() override; - void ShowSavePasswordPopup(scoped_ptr form_to_save); + void LoadRiskData( + base::OnceCallback callback) override; + + void ShowSavePasswordPopup( + std::unique_ptr form_to_save); void SetEWebView(EWebView* view) { webview_ = view; } - AutofillPopupViewEfl* GetOrCreatePopupController(); - void DidFillOrPreviewField(const std::u16string& autofilled_value, - const std::u16string& profile_full_name) override; + void UpdateAutofillIfRequired(); + void DidChangeFocusedNodeBounds(const gfx::RectF& node_bounds); + bool IsAutocompleteSavingEnabled(); + FormDataImporter* GetFormDataImporter(); + StrikeDatabase* GetStrikeDatabase(); + void ShowLocalCardMigrationDialog( + base::OnceClosure show_migration_dialog_closure); + void ConfirmMigrateLocalCardToCloud( + std::unique_ptr legal_message, + const std::string& user_email, + const std::vector& migratable_credit_cards, + LocalCardMigrationCallback start_migrating_cards_callback); + void ShowLocalCardMigrationResults( + const bool has_server_error, + const std::u16string& tip_message, + const std::vector& migratable_credit_cards, + MigrationDeleteCardCallback delete_local_card_callback); + AutocompleteHistoryManager* GetAutocompleteHistoryManager(); private: explicit AutofillClientEfl(content::WebContents* web_contents); friend class content::WebContentsUserData; + AutofillPopupViewEfl* GetOrCreatePopupController(); + gfx::RectF GetElementBoundsInScreen(const gfx::RectF& element_bounds); content::WebContents* const web_contents_; - EWebView* webview_; - scoped_refptr database_; - AutofillPopupViewEfl* popup_controller_; + EWebView* webview_ = nullptr; + AutofillPopupViewEfl* popup_controller_ = nullptr; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); }; } // namespace autofill diff --git a/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.cc b/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.cc index e31cefb..0bf0c5b 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.cc +++ b/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.cc @@ -18,11 +18,12 @@ namespace autofill { // static -PersonalDataManagerFactory* PersonalDataManagerFactory::GetInstance() { - return base::Singleton::get(); +PersonalDataManagerFactoryEfl* PersonalDataManagerFactoryEfl::GetInstance() { + return base::Singleton::get(); } -void PersonalDataManagerFactory::PersonalDataManagerAdd(content::BrowserContext* ctx) { +void PersonalDataManagerFactoryEfl::PersonalDataManagerAdd( + content::BrowserContext* ctx) { DCHECK(ctx); if (ctx) { @@ -32,12 +33,14 @@ void PersonalDataManagerFactory::PersonalDataManagerAdd(content::BrowserContext* // TODO: LOCALE! PrefService* srv = user_prefs::UserPrefs::Get(ctx); CHECK(srv); - content::ContentBrowserClient* client = content::GetContentClientExport()->browser(); + auto* client = content::GetContentClientExport()->browser(); mgr = new PersonalDataManager(client->GetApplicationLocale()); - mgr->Init(WebDataServiceFactory::GetAutofillWebDataForProfile(), - srv, - NULL, - NULL, + mgr->Init(WebDataServiceFactoryEfl::GetAutofillWebDataForProfile(), + nullptr, srv, nullptr, + nullptr, // TODO(djmix.kim) : pass nullptr for bringup + nullptr, // TODO(djmix.kim) : pass nullptr for bringup + nullptr, // TODO(djmix.kim) : pass nullptr for bringup + nullptr, // TODO(djmix.kim) : pass nullptr for bringup ctx->IsOffTheRecord()); mgr->AddObserver(this); personal_data_manager_id_map_.AddWithID(mgr, uniqueId); @@ -45,36 +48,36 @@ void PersonalDataManagerFactory::PersonalDataManagerAdd(content::BrowserContext* } } -void PersonalDataManagerFactory::PersonalDataManagerRemove(content::BrowserContext* ctx) { +void PersonalDataManagerFactoryEfl::PersonalDataManagerRemove( + content::BrowserContext* ctx) { uint64_t uniqueId = reinterpret_cast(ctx); personal_data_manager_id_map_.Remove(uniqueId); } -PersonalDataManager* PersonalDataManagerFactory::PersonalDataManagerForContext( +PersonalDataManager* +PersonalDataManagerFactoryEfl::PersonalDataManagerForContext( content::BrowserContext* ctx) { uint64_t uniqueId = reinterpret_cast(ctx); return personal_data_manager_id_map_.Lookup(uniqueId); } -PersonalDataManagerFactory::PersonalDataManagerFactory() - : callback_(NULL) - , callback_user_data_(NULL) { -} +PersonalDataManagerFactoryEfl::PersonalDataManagerFactoryEfl() + : callback_(NULL), callback_user_data_(NULL) {} -PersonalDataManagerFactory::~PersonalDataManagerFactory() { +PersonalDataManagerFactoryEfl::~PersonalDataManagerFactoryEfl() { if (!personal_data_manager_id_map_.IsEmpty()) LOG(ERROR) << "Client didn't destroy all WebView objects" << " before calling ewk_shutdown"; } -void PersonalDataManagerFactory::SetCallback( +void PersonalDataManagerFactoryEfl::SetCallback( Ewk_Context_Form_Autofill_Profile_Changed_Callback callback, void* user_data) { callback_ = callback; callback_user_data_ = user_data; } -void PersonalDataManagerFactory::OnPersonalDataChanged() { +void PersonalDataManagerFactoryEfl::OnPersonalDataChanged() { if(!callback_) return; callback_(callback_user_data_); diff --git a/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.h b/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.h index 662449e..205581d 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.h +++ b/tizen_src/ewk/efl_integration/browser/autofill/personal_data_manager_factory.h @@ -6,8 +6,8 @@ #define PERSONAL_DATA_MANAGER_FACTORY_H #if defined(TIZEN_AUTOFILL_SUPPORT) -#include "base/id_map.h" #include "base/compiler_specific.h" +#include "base/containers/id_map.h" #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" @@ -28,9 +28,9 @@ class PersonalDataManager; class AutofillProfile; class CreditCard; -class PersonalDataManagerFactory : public PersonalDataManagerObserver { +class PersonalDataManagerFactoryEfl : public PersonalDataManagerObserver { public: - static PersonalDataManagerFactory* GetInstance(); + static PersonalDataManagerFactoryEfl* GetInstance(); void PersonalDataManagerAdd(content::BrowserContext* ctx); void PersonalDataManagerRemove(content::BrowserContext* ctx); @@ -44,16 +44,16 @@ class PersonalDataManagerFactory : public PersonalDataManagerObserver { void OnPersonalDataChanged() override; private: - friend struct base::DefaultSingletonTraits; + friend struct base::DefaultSingletonTraits; - PersonalDataManagerFactory(); - ~PersonalDataManagerFactory(); + PersonalDataManagerFactoryEfl(); + ~PersonalDataManagerFactoryEfl(); - PersonalDataManagerFactory(const PersonalDataManagerFactory&) = delete; - PersonalDataManagerFactory& operator=(const PersonalDataManagerFactory&) = - delete; + PersonalDataManagerFactoryEfl(const PersonalDataManagerFactoryEfl&) = delete; + PersonalDataManagerFactoryEfl& operator=( + const PersonalDataManagerFactoryEfl&) = delete; - IDMap personal_data_manager_id_map_; + base::IDMap personal_data_manager_id_map_; Ewk_Context_Form_Autofill_Profile_Changed_Callback callback_; void* callback_user_data_; diff --git a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc index 7bb79f9..2d36be4 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.cc @@ -5,13 +5,16 @@ #if defined(TIZEN_AUTOFILL_SUPPORT) #include "autofill_popup_view_efl.h" -#include "base/path_service.h" #include "base/files/file_path.h" +#include "base/path_service.h" #include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/popup_item_ids.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" +#include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/common/paths_efl.h" #include "eweb_view.h" -#include "tizen/profile_info.h" +#include "tizen/system_info.h" +#include "ui/display/screen.h" +#include "ui/gfx/geometry/rect_f.h" #define AUTOFILL_POPUP_LABEL_COUNT 6 // Autofill component send 6 at max #define AUTOFILL_POPUP_LABEL_LEN 100 @@ -80,46 +83,60 @@ void AutofillPopupViewEfl::Hide() } void AutofillPopupViewEfl::ShowSavePasswordPopup( - scoped_ptr form_to_save) -{ + std::unique_ptr form_to_save) { if (password_popup_) { evas_object_del(password_popup_); password_popup_ = NULL; } - form_manager_ = form_to_save.Pass(); + form_manager_ = std::move(form_to_save); password_popup_ = elm_popup_add(webview_->evas_object()); - elm_popup_allow_events_set(password_popup_, EINA_TRUE); elm_popup_content_text_wrap_type_set(password_popup_, ELM_WRAP_CHAR); - elm_object_part_text_set(password_popup_, "title,text", "Save Your Password?"); + elm_object_domain_translatable_part_text_set( + password_popup_, "title,text", "WebKit", + "IDS_WEBVIEW_HEADER_SAVE_SIGN_IN_INFO"); + +#if BUILDFLAG(IS_EFL) && !BUILDFLAG(IS_TIZEN) + // Fix the positioning of the password popup on desktop build + auto* rwhv = webview_->web_contents().GetRenderWidgetHostView(); + auto* rwhva = static_cast(rwhv); + if (rwhva) { + int w = 0, h = 0; + evas_object_geometry_get(password_popup_, 0, 0, &w, &h); + gfx::Size size = rwhva->offscreen_helper()->GetVisibleViewportSize(); + evas_object_move(password_popup_, (size.width() - w) / 2, + (size.height() - h) / 2); + } +#endif + evas_object_show(password_popup_); - Evas_Object *btn_never = elm_button_add(password_popup_); - elm_object_text_set(btn_never, "Never"); + Evas_Object* btn_never = elm_button_add(password_popup_); + elm_object_domain_translatable_part_text_set(btn_never, NULL, "WebKit", + "IDS_WEBVIEW_BUTTON2_NEVER"); elm_object_part_content_set(password_popup_, "button1", btn_never); evas_object_smart_callback_add(btn_never, "clicked", savePasswordNeverCb, this); - Evas_Object *btn_yes = elm_button_add(password_popup_); - elm_object_text_set(btn_yes, "Yes"); - elm_object_part_content_set(password_popup_, "button2", btn_yes); - evas_object_smart_callback_add(btn_yes, - "clicked", - savePasswordYesCb, - this); - - Evas_Object *btn_not_now = elm_button_add(password_popup_); - elm_object_text_set(btn_not_now, "Not Now"); - elm_object_part_content_set(password_popup_, "button3", btn_not_now); - evas_object_smart_callback_add(btn_not_now, - "clicked", - savePasswordNotNowCb, - this); + Evas_Object* btn_not_now = elm_button_add(password_popup_); + elm_object_domain_translatable_part_text_set(btn_not_now, NULL, "WebKit", + "IDS_WEBVIEW_BUTTON_LATER_ABB"); + elm_object_part_content_set(password_popup_, "button2", btn_not_now); + evas_object_smart_callback_add(btn_not_now, "clicked", savePasswordNotNowCb, + this); + + Evas_Object* btn_yes = elm_button_add(password_popup_); + elm_object_domain_translatable_part_text_set(btn_yes, NULL, "WebKit", + "IDS_WEBVIEW_BUTTON_SAVE"); + elm_object_part_content_set(password_popup_, "button3", btn_yes); + evas_object_smart_callback_add(btn_yes, "clicked", savePasswordYesCb, this); } - -void AutofillPopupViewEfl::UpdateFormDataPopup(const gfx::RectF& bounds) -{ + +void AutofillPopupViewEfl::UpdateFormDataPopup(const gfx::RectF& bounds) { + if (bounds.IsEmpty()) + return; + Elm_Genlist_Item_Class* list_Items = NULL; double scale_factor = 1.0; if (!autofill_list_) @@ -146,8 +163,8 @@ void AutofillPopupViewEfl::UpdateFormDataPopup(const gfx::RectF& bounds) static_cast(this)); } if (IsMobileProfile() || IsWearableProfile()) { - scale_factor = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(). - device_scale_factor(); + scale_factor = + display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); } else if (IsTvProfile()) { scale_factor = webview_->GetScale(); } @@ -198,8 +215,20 @@ void AutofillPopupViewEfl::UpdateFormDataPopup(const gfx::RectF& bounds) evas_object_propagate_events_set(autofill_popup_, false); } +void AutofillPopupViewEfl::UpdateLocation(const gfx::RectF& bounds) { + if (bounds.IsEmpty()) + return; + + double scale_factor = + display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); + + evas_object_move(autofill_popup_, bounds.x() * scale_factor, + (bounds.y() + bounds.height()) * scale_factor); +} + bool isAutofillSpecial(const autofill::Suggestion& suggestion) { - return suggestion.frontend_id != POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY && + return suggestion.frontend_id <= 0 && + suggestion.frontend_id != POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY && suggestion.frontend_id != POPUP_ITEM_ID_DATALIST_ENTRY; } @@ -216,9 +245,10 @@ void AutofillPopupViewEfl::InitFormData( for (size_t i = 0; i < values_.size() && i < AUTOFILL_POPUP_LABEL_COUNT; ++i) { - labels_[i] = UTF16ToUTF8(values_[i].value); - if (!values_[i].label.empty()) - labels_[i].append(" (" + UTF16ToUTF8(values_[i].label) + ")"); + labels_[i] = base::UTF16ToUTF8(values_[i].main_text.value); + if (!values_[i].labels.empty() && !values_[i].labels[0][0].value.empty()) + labels_[i].append(" (" + + base::UTF16ToUTF8(values_[i].labels[0][0].value) + ")"); // To keep compatibility with webkit2-efl if (AUTOFILL_POPUP_LABEL_LEN < labels_[i].length()) labels_[i].resize(AUTOFILL_POPUP_LABEL_LEN); @@ -226,16 +256,13 @@ void AutofillPopupViewEfl::InitFormData( delegate_ = delegate; } -void AutofillPopupViewEfl::AcceptSuggestion(size_t index) -{ - if (delegate_) { - if (index < values_.size()) - delegate_->DidAcceptSuggestion(values_[index].value, values_[index].frontend_id, index); +void AutofillPopupViewEfl::AcceptSuggestion(size_t index) { + if (delegate_ && index < values_.size()) { + delegate_->DidAcceptSuggestion(values_[index], index); } } -void AutofillPopupViewEfl::AcceptPasswordSuggestion(int option) -{ +void AutofillPopupViewEfl::AcceptPasswordSuggestion(int option) { if (password_popup_) { evas_object_del(password_popup_); password_popup_ = NULL; @@ -244,7 +271,7 @@ void AutofillPopupViewEfl::AcceptPasswordSuggestion(int option) return; switch (static_cast(option)) { case AUTOFILL_SAVE_PASS_NEVER: { - form_manager_->PermanentlyBlacklist(); + form_manager_->Blocklist(); break; } case AUTOFILL_SAVE_PASS_YES: { @@ -265,8 +292,9 @@ void AutofillPopupViewEfl::SetSelectedLine(size_t selected_line) selected_line_ = selected_line; if (delegate_) { if (selected_line_ < values_.size()) { - delegate_->DidSelectSuggestion(values_[selected_line].value, - selected_line); + delegate_->DidSelectSuggestion(values_[selected_line].main_text.value, + selected_line, + autofill::Suggestion::BackendId()); } else { delegate_->ClearPreviewedForm(); @@ -292,23 +320,29 @@ void AutofillPopupViewEfl::itemSelectCb(void* data, Evas_Object* obj, void* even autofill_popup->AcceptSuggestion(index); } -void AutofillPopupViewEfl::savePasswordNeverCb(void *data, Evas_Object *obj, void *event_info) -{ - AutofillPopupViewEfl * autofill_popup = static_cast(data); +void AutofillPopupViewEfl::savePasswordNeverCb(void* data, + Evas_Object* obj, + void* event_info) { + AutofillPopupViewEfl* autofill_popup = + static_cast(data); if (autofill_popup) autofill_popup->AcceptPasswordSuggestion(AUTOFILL_SAVE_PASS_NEVER); } -void AutofillPopupViewEfl::savePasswordYesCb(void *data, Evas_Object *obj, void *event_info) -{ - AutofillPopupViewEfl * autofill_popup = static_cast(data); +void AutofillPopupViewEfl::savePasswordYesCb(void* data, + Evas_Object* obj, + void* event_info) { + AutofillPopupViewEfl* autofill_popup = + static_cast(data); if (autofill_popup) autofill_popup->AcceptPasswordSuggestion(AUTOFILL_SAVE_PASS_YES); } -void AutofillPopupViewEfl::savePasswordNotNowCb(void *data, Evas_Object *obj, void *event_info) -{ - AutofillPopupViewEfl * autofill_popup = static_cast(data); +void AutofillPopupViewEfl::savePasswordNotNowCb(void* data, + Evas_Object* obj, + void* event_info) { + AutofillPopupViewEfl* autofill_popup = + static_cast(data); if (autofill_popup) autofill_popup->AcceptPasswordSuggestion(AUTOFILL_SAVE_PASS_NOTNOW); } diff --git a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h index 5320a43..c7b4fd1 100644 --- a/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h +++ b/tizen_src/ewk/efl_integration/browser/autofill_popup_view_efl.h @@ -14,11 +14,11 @@ #include #include -#include "components/autofill/core/browser/autofill_popup_delegate.h" -#include "components/autofill/core/browser/suggestion.h" -#include "components/password_manager/core/browser/password_form_manager.h" +#include "base/memory/weak_ptr.h" +#include "components/autofill/core/browser/ui/autofill_popup_delegate.h" +#include "components/autofill/core/browser/ui/suggestion.h" +#include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "ui/gfx/geometry/point.h" -#include "ui/gfx/screen.h" class EWebView; @@ -29,26 +29,29 @@ class RectF; namespace autofill { class AutofillPopupViewEfl { -public: + public: AutofillPopupViewEfl(EWebView* view); ~AutofillPopupViewEfl(); void Show(); void Hide(); void ShowSavePasswordPopup( - scoped_ptr form_to_save); + std::unique_ptr form_to_save); void UpdateFormDataPopup(const gfx::RectF& bounds); + void UpdateLocation(const gfx::RectF& focused_element_bounds); void InitFormData( const std::vector& suggestions, base::WeakPtr delegate); void AcceptSuggestion(size_t index); void AcceptPasswordSuggestion(int option); void SetSelectedLine(size_t index); + bool IsVisible() const { return evas_object_visible_get(autofill_popup_); } static char* getItemLabel(void* data, Evas_Object* obj, const char* part); static void itemSelectCb(void* data, Evas_Object* obj, void* event_info); static void savePasswordNeverCb(void *data, Evas_Object *obj, void *event_info); static void savePasswordYesCb(void *data, Evas_Object *obj, void *event_info); static void savePasswordNotNowCb(void *data, Evas_Object *obj, void *event_info); -private: + + private: EWebView* webview_; Evas_Object* autofill_popup_; Evas_Object* autofill_list_; @@ -56,7 +59,7 @@ private: std::vector values_; size_t selected_line_; base::WeakPtr delegate_; - scoped_ptr form_manager_; + std::unique_ptr form_manager_; }; } //namespace autofill diff --git a/tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.cc b/tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.cc new file mode 100644 index 0000000..439022b --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.cc @@ -0,0 +1,106 @@ +// Copyright 2016 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(TIZEN_AUTOFILL_SUPPORT) + +#include "password_helper_efl.h" + +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "components/password_manager/core/browser/password_form.h" +#include "components/password_manager/core/browser/password_store.h" +#include "components/password_manager/core/browser/password_store_consumer.h" +#include "url/gurl.h" + +using password_manager::PasswordStore; + +namespace password_helper { + +namespace { + +class PasswordFormGetter : public password_manager::PasswordStoreConsumer { + public: + PasswordFormGetter(const password_helper::GetLoginsCallback& callback) + : callback_(callback) {} + + PasswordFormGetter(const PasswordFormGetter&) = delete; + PasswordFormGetter& operator=(const PasswordFormGetter&) = delete; + + void OnGetPasswordStoreResults( + std::vector> results) + override { + DCHECK(!callback_.is_null()); + callback_.Run(results); + + delete this; + } + + base::WeakPtr GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + password_helper::GetLoginsCallback callback_; + base::WeakPtrFactory weak_ptr_factory_{this}; +}; + +class PasswordFormRemover : public password_manager::PasswordStoreConsumer { + public: + PasswordFormRemover(scoped_refptr store, const GURL& origin) + : store_(store), origin_(origin) {} + + PasswordFormRemover(const PasswordFormRemover&) = delete; + PasswordFormRemover& operator=(const PasswordFormRemover&) = delete; + + void OnGetPasswordStoreResults( + std::vector> results) + override { + for (const auto& form : results) { + if (form->url == origin_) { + store_->RemoveLogin(*form); + break; + } + } + + delete this; + } + + base::WeakPtr GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + scoped_refptr store_; + GURL origin_; + base::WeakPtrFactory weak_ptr_factory_{this}; +}; + +} // namespace + +void GetLogins(const scoped_refptr& store, + const GetLoginsCallback& callback) { + if (store.get()) { + auto password_form_getter = new PasswordFormGetter(callback); + store->GetAutofillableLogins(password_form_getter->GetWeakPtr()); + } +} + +void RemoveLogin(const scoped_refptr& store, + const GURL& origin) { + if (store.get()) { + auto password_form_remover = new PasswordFormRemover(store, origin); + store->GetAutofillableLogins(password_form_remover->GetWeakPtr()); + } +} + +void RemoveLogins(const scoped_refptr& store) { + if (store.get()) { + store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(), + base::NullCallback()); + } +} + +} // namespace password_helper + +#endif // TIZEN_AUTOFILL_SUPPORT diff --git a/tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.h b/tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.h new file mode 100644 index 0000000..1018ec1 --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/password_manager/password_helper_efl.h @@ -0,0 +1,43 @@ +// Copyright 2016 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_ +#define EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_ + +#if defined(TIZEN_AUTOFILL_SUPPORT) + +#include + +#include "base/callback.h" +#include "base/memory/ref_counted.h" + +class GURL; + +namespace password_manager { +class PasswordStore; +struct PasswordForm; +} // namespace password_manager + +namespace password_helper { + +typedef base::RepeatingCallback>& + results)> + GetLoginsCallback; + +// Get all password forms from the password store. +void GetLogins(const scoped_refptr& store, + const GetLoginsCallback& callback); + +// Removes password form which is matched with |origin] from the password store. +void RemoveLogin(const scoped_refptr& store, + const GURL& origin); + +// Removes all password forms from the password store. +void RemoveLogins(const scoped_refptr& store); + +} // namespace password_helper + +#endif // TIZEN_AUTOFILL_SUPPORT +#endif // EWK_EFL_INTEGRATION_BROWSER_PASSWORD_MANAGER_PASSWORD_HELPER_EFL_H_ diff --git a/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.cc b/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.cc index b537857..a28d1f9 100644 --- a/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.cc @@ -6,22 +6,26 @@ #if defined(TIZEN_AUTOFILL_SUPPORT) #include "browser/password_manager/password_manager_client_efl.h" -#include "browser/autofill/autofill_client_efl.h" -#include "autofill_popup_view_efl.h" -#include "base/bind_helpers.h" + #include "base/command_line.h" #include "base/memory/singleton.h" #include "base/metrics/histogram.h" -#include "base/prefs/pref_service.h" +#include "browser/autofill/autofill_client_efl.h" +#include "browser/autofill_popup_view_efl.h" #include "browser/password_manager/password_store_factory.h" +#include "components/password_manager/content/browser/bad_message.h" +#include "components/password_manager/content/browser/content_password_manager_driver.h" +#include "components/password_manager/core/browser/password_feature_manager.h" #include "components/password_manager/core/browser/password_form_manager.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/prefs/pref_service.h" #include "components/user_prefs/user_prefs.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" - -DEFINE_WEB_CONTENTS_USER_DATA_KEY(password_manager::PasswordManagerClientEfl); +#include "content/public/common/origin_util.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" namespace password_manager { @@ -33,15 +37,32 @@ void PasswordManagerClientEfl::CreateForWebContentsWithAutofillClient( if (FromWebContents(contents)) return; - contents->SetUserData( - UserDataKey(), - new PasswordManagerClientEfl(contents, autofill_client)); + contents->SetUserData(UserDataKey(), + std::move(base::WrapUnique(new PasswordManagerClientEfl( + contents, autofill_client)))); +} + +const GURL& PasswordManagerClientEfl::GetLastCommittedURL() const { + DCHECK(web_contents_); + content::NavigationEntry* entry = + web_contents_->GetController().GetLastCommittedEntry(); + if (!entry) + return GURL::EmptyGURL(); + + return entry->GetURL(); } PasswordManagerClientEfl::PasswordManagerClientEfl( - content::WebContents* web_contents, autofill::AutofillClient* autofill_client) - : web_contents_(web_contents), + content::WebContents* web_contents, + autofill::AutofillClient* autofill_client) + : content::WebContentsUserData(*web_contents), + web_contents_(web_contents), + password_manager_driver_bindings_(web_contents, this), password_manager_(this), + password_feature_manager_( + GetPrefs(), + nullptr, + nullptr /*ProfileSyncServiceFactory::GetForProfile(profile_)*/), driver_factory_(nullptr), weak_factory_(this) { ContentPasswordManagerDriverFactory::CreateForWebContents(web_contents, this, @@ -54,76 +75,294 @@ PasswordManagerClientEfl::~PasswordManagerClientEfl() { } bool PasswordManagerClientEfl::PromptUserToSaveOrUpdatePassword( - scoped_ptr form_to_save, - CredentialSourceType type, + std::unique_ptr form_to_save, bool update_password) { autofill::AutofillClientEfl * autofill_manager = autofill::AutofillClientEfl::FromWebContents(web_contents_); if (autofill_manager) { - autofill_manager->ShowSavePasswordPopup(form_to_save.Pass()); + autofill_manager->ShowSavePasswordPopup(std::move(form_to_save)); return true; } return false; } -PasswordStore* PasswordManagerClientEfl::GetPasswordStore() const { - return PasswordStoreFactory::GetPasswordStore().get(); -} - -const PasswordManager* PasswordManagerClientEfl::GetPasswordManager() const { - return &password_manager_; +void PasswordManagerClientEfl::ShowManualFallbackForSaving( + std::unique_ptr form_to_save, + bool has_generated_password, + bool is_update) { + NOTIMPLEMENTED(); } -bool PasswordManagerClientEfl::IsSavingAndFillingEnabledForCurrentPage() - const { - return !IsOffTheRecord() && IsFillingEnabledForCurrentPage(); +PasswordStore* PasswordManagerClientEfl::GetProfilePasswordStore() const { + return PasswordStoreFactory::GetProfilePasswordStore().get(); } -bool PasswordManagerClientEfl::IsFillingEnabledForCurrentPage() const { - PrefService* prefs = - user_prefs::UserPrefs::Get(web_contents_->GetBrowserContext()); - return prefs->GetBoolean( - password_manager::prefs::kPasswordManagerSavingEnabled); +const PasswordManager* PasswordManagerClientEfl::GetPasswordManager() const { + return &password_manager_; } bool PasswordManagerClientEfl::PromptUserToChooseCredentials( - ScopedVector local_forms, - ScopedVector federated_forms, - const GURL& origin, - base::OnceCallback callback) { + std::vector> local_forms, + const url::Origin& origin, + CredentialsCallback callback) { NOTIMPLEMENTED(); return false; } void PasswordManagerClientEfl::NotifyUserAutoSignin( - ScopedVector local_forms) { + std::vector> local_forms, + const url::Origin& origin) { DCHECK(!local_forms.empty()); NOTIMPLEMENTED(); } -void PasswordManagerClientEfl::AutomaticPasswordSave( - scoped_ptr saved_form_manager) { +void PasswordManagerClientEfl::NotifyUserCouldBeAutoSignedIn( + std::unique_ptr form) { NOTIMPLEMENTED(); } -const GURL& PasswordManagerClientEfl::GetLastCommittedEntryURL() const { - DCHECK(web_contents_); - content::NavigationEntry* entry = - web_contents_->GetController().GetLastCommittedEntry(); - if (!entry) - return GURL::EmptyGURL(); +void PasswordManagerClientEfl::NotifySuccessfulLoginWithExistingPassword( + std::unique_ptr + submitted_manager) { + NOTIMPLEMENTED(); +} - return entry->GetURL(); +void PasswordManagerClientEfl::NotifyStorePasswordCalled() { + NOTIMPLEMENTED(); } -const CredentialsFilter* PasswordManagerClientEfl::GetStoreResultFilter() const { +void PasswordManagerClientEfl::AutomaticPasswordSave( + std::unique_ptr saved_form_manager) { + NOTIMPLEMENTED(); +} + +const CredentialsFilter* PasswordManagerClientEfl::GetStoreResultFilter() + const { return &credentials_filter_; } -PrefService* PasswordManagerClientEfl::GetPrefs() { +PrefService* PasswordManagerClientEfl::GetPrefs() const { return user_prefs::UserPrefs::Get(web_contents_->GetBrowserContext()); } +autofill::LogManager* PasswordManagerClientEfl::GetLogManager() { + return &log_manager_; +} + +ukm::SourceId PasswordManagerClientEfl::GetUkmSourceId() { + NOTIMPLEMENTED(); + return ukm::kInvalidSourceId; +} + +PasswordManagerMetricsRecorder* PasswordManagerClientEfl::GetMetricsRecorder() { + if (!metrics_recorder_) { + metrics_recorder_.emplace(GetUkmSourceId()); + } + return base::OptionalToPtr(metrics_recorder_); +} + +bool PasswordManagerClientEfl::IsIsolationForPasswordSitesEnabled() const { + NOTIMPLEMENTED(); + return false; +} + +bool PasswordManagerClientEfl::IsNewTabPage() const { + NOTIMPLEMENTED(); + return false; +} + +void PasswordManagerClientEfl::PasswordFormsParsed( + const std::vector& forms) { + if (!bad_message::CheckChildProcessSecurityPolicy( + password_manager_driver_bindings_.GetCurrentTargetFrame(), forms, + BadMessageReason::CPMD_BAD_ORIGIN_FORMS_PARSED_OBSOLETE)) { + return; + } + password_manager::PasswordManagerDriver* driver = + driver_factory_->GetDriverForFrame( + password_manager_driver_bindings_.GetCurrentTargetFrame()); + GetPasswordManager()->OnPasswordFormsParsed(driver, forms); +} + +void PasswordManagerClientEfl::PasswordFormsRendered( + const std::vector& visible_forms) { + if (!bad_message::CheckChildProcessSecurityPolicy( + password_manager_driver_bindings_.GetCurrentTargetFrame(), + visible_forms, + BadMessageReason::CPMD_BAD_ORIGIN_FORMS_RENDERED_OBSOLETE)) { + return; + } + password_manager::PasswordManagerDriver* driver = + driver_factory_->GetDriverForFrame( + password_manager_driver_bindings_.GetCurrentTargetFrame()); + GetPasswordManager()->OnPasswordFormsRendered(driver, visible_forms); +} + +void PasswordManagerClientEfl::ShowPasswordSuggestions( + base::i18n::TextDirection text_direction, + const std::u16string& typed_username, + int options, + const gfx::RectF& bounds) { + password_manager::PasswordManagerDriver* driver = + driver_factory_->GetDriverForFrame( + password_manager_driver_bindings_.GetCurrentTargetFrame()); + driver->GetPasswordAutofillManager()->OnShowPasswordSuggestions( + text_direction, typed_username, options, + TransformToRootCoordinates( + password_manager_driver_bindings_.GetCurrentTargetFrame(), bounds)); +} + +void PasswordManagerClientEfl::PasswordFormSubmitted( + const autofill::FormData& password_form) { + if (!bad_message::CheckChildProcessSecurityPolicyForURL( + password_manager_driver_bindings_.GetCurrentTargetFrame(), + password_form.url, + BadMessageReason::CPMD_BAD_ORIGIN_FORM_SUBMITTED)) { + return; + } + password_manager::PasswordManagerDriver* driver = + driver_factory_->GetDriverForFrame( + password_manager_driver_bindings_.GetCurrentTargetFrame()); + GetPasswordManager()->OnPasswordFormSubmitted(driver, password_form); +} + +void PasswordManagerClientEfl::HideManualFallbackForSaving() { + NOTIMPLEMENTED(); +} + +void PasswordManagerClientEfl::RecordSavePasswordProgress( + const std::string& log) { + LOG_AF(GetLogManager()) << log; +} + +void PasswordManagerClientEfl::UserModifiedPasswordField() { + GetMetricsRecorder()->RecordUserModifiedPasswordField(); +} + +void PasswordManagerClientEfl::FocusedInputChanged( + password_manager::PasswordManagerDriver* driver, + autofill::FieldRendererId focused_field_id, + autofill::mojom::FocusedFieldType focused_field_type) { + NOTIMPLEMENTED(); +} + +PasswordManager* PasswordManagerClientEfl::GetPasswordManager() { + return &password_manager_; +} + +gfx::RectF PasswordManagerClientEfl::TransformToRootCoordinates( + content::RenderFrameHost* frame_host, + const gfx::RectF& bounds_in_frame_coordinates) { + content::RenderWidgetHostView* rwhv = frame_host->GetView(); + if (!rwhv) + return bounds_in_frame_coordinates; + return gfx::RectF(rwhv->TransformPointToRootCoordSpaceF( + bounds_in_frame_coordinates.origin()), + bounds_in_frame_coordinates.size()); +} + +void PasswordManagerClientEfl::PromptUserToMovePasswordToAccount( + std::unique_ptr form_to_move) { + NOTIMPLEMENTED(); +} + +PasswordStore* PasswordManagerClientEfl::GetAccountPasswordStore() const { + NOTIMPLEMENTED(); + return nullptr; +} + +url::Origin PasswordManagerClientEfl::GetLastCommittedOrigin() const { + NOTIMPLEMENTED(); + return url::Origin(); +} + +signin::IdentityManager* PasswordManagerClientEfl::GetIdentityManager() { + NOTIMPLEMENTED(); + return nullptr; +} + +scoped_refptr +PasswordManagerClientEfl::GetURLLoaderFactory() { + NOTIMPLEMENTED(); + return nullptr; +} + +FieldInfoManager* PasswordManagerClientEfl::GetFieldInfoManager() const { + NOTIMPLEMENTED(); + return nullptr; +} + +void PasswordManagerClientEfl::LogFirstFillingResult( + autofill::FormRendererId form_renderer_id, + int32_t result) { + NOTIMPLEMENTED(); +} + +bool PasswordManagerClientEfl::IsCommittedMainFrameSecure() const { + return network::IsOriginPotentiallyTrustworthy( + web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin()); +} + +void PasswordManagerClientEfl::CheckProtectedPasswordEntry( + metrics_util::PasswordType reused_password_type, + const std::string& username, + const std::vector& matching_reused_credentials, + bool password_field_exists, + uint64_t reused_password_hash, + const std::string& domain) { + NOTIMPLEMENTED(); +} + +PasswordReuseManager* PasswordManagerClientEfl::GetPasswordReuseManager() + const { + NOTIMPLEMENTED(); + return nullptr; +} +safe_browsing::PasswordProtectionService* +PasswordManagerClientEfl::GetPasswordProtectionService() const { + NOTIMPLEMENTED(); + return nullptr; +} +void PasswordManagerClientEfl::LogPasswordReuseDetectedEvent() { + NOTIMPLEMENTED(); +} +bool PasswordManagerClientEfl::IsAutofillAssistantUIVisible() const { + NOTIMPLEMENTED(); + return false; +} + +void PasswordManagerClientEfl::InformAboutUserInput( + const autofill::FormData& form_data) { + NOTIMPLEMENTED(); +} +void PasswordManagerClientEfl::DynamicFormSubmission( + autofill::mojom::SubmissionIndicatorEvent submission_indication_event) { + NOTIMPLEMENTED(); +} +void PasswordManagerClientEfl::PasswordFormCleared( + const autofill::FormData& form_data) { + NOTIMPLEMENTED(); +} +void PasswordManagerClientEfl::UserModifiedNonPasswordField( + autofill::FieldRendererId renderer_id, + const std::u16string& field_name, + const std::u16string& value) { + NOTIMPLEMENTED(); +} + +void PasswordManagerClientEfl::FocusedInputChanged( + autofill::FieldRendererId focused_field_id, + autofill::mojom::FocusedFieldType focused_field_type) { + NOTIMPLEMENTED(); +} + +void PasswordManagerClientEfl::CheckSafeBrowsingReputation( + const GURL& form_action, + const GURL& frame_url) { + NOTIMPLEMENTED(); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(PasswordManagerClientEfl); } #endif // TIZEN_AUTOFILL_SUPPORT diff --git a/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.h b/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.h index f3a26a2..1690168 100644 --- a/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.h +++ b/tizen_src/ewk/efl_integration/browser/password_manager/password_manager_client_efl.h @@ -9,9 +9,16 @@ #if defined(TIZEN_AUTOFILL_SUPPORT) #include "base/compiler_specific.h" -#include "components/password_manager/content/browser/content_password_manager_driver_factory.h" +#include "components/autofill/core/browser/logging/log_manager.h" +#include "components/autofill/core/browser/logging/stub_log_manager.h" #include "components/password_manager/content/browser/content_password_manager_driver.h" +#include "components/password_manager/content/browser/content_password_manager_driver_factory.h" +#include "components/password_manager/core/browser/password_feature_manager_impl.h" #include "components/password_manager/core/browser/password_manager_client.h" +#include "components/password_manager/core/browser/password_manager_metrics_recorder.h" +#include "components/password_manager/core/browser/password_store.h" +#include "components/password_manager/core/browser/stub_credentials_filter.h" +#include "content/public/browser/render_frame_host_receiver_set.h" #include "content/public/browser/web_contents_user_data.h" class PasswordManager; @@ -24,40 +31,87 @@ class WebContents; namespace password_manager { class PasswordManagerClientEfl : public PasswordManagerClient, - public content::WebContentsUserData { -public: + public content::WebContentsUserData, + public autofill::mojom::PasswordManagerDriver { + public: virtual ~PasswordManagerClientEfl(); + using CredentialsCallback = base::OnceCallback; static void CreateForWebContentsWithAutofillClient( content::WebContents* contents, autofill::AutofillClient* autofill_client); // PasswordManagerClient implementation. - virtual bool PromptUserToSaveOrUpdatePassword( - std::unique_ptr form_to_save, - CredentialSourceType type, - bool update_password) override; - - PasswordStore* GetPasswordStore() const override; - + bool PromptUserToSaveOrUpdatePassword( + std::unique_ptr form_to_save, + bool is_update) override; + void ShowManualFallbackForSaving( + std::unique_ptr form_to_save, + bool has_generated_password, + bool is_update) override; + PasswordStore* GetProfilePasswordStore() const override; bool PromptUserToChooseCredentials( - ScopedVector local_forms, - ScopedVector federated_forms, - const GURL& origin, - base::OnceCallback callback) override; + std::vector> local_forms, + const url::Origin& origin, + CredentialsCallback callback) override; void NotifyUserAutoSignin( - ScopedVector local_forms) override; + std::vector> local_forms, + const url::Origin& origin) override; + void NotifyUserCouldBeAutoSignedIn( + std::unique_ptr form) override; + void NotifySuccessfulLoginWithExistingPassword( + std::unique_ptr + submitted_manager) override; + void NotifyStorePasswordCalled() override; void AutomaticPasswordSave( - std::unique_ptr saved_form_manager) override; + std::unique_ptr saved_form_manager) override; const PasswordManager* GetPasswordManager() const override; const CredentialsFilter* GetStoreResultFilter() const override; - const GURL& GetLastCommittedEntryURL() const override; - PrefService* GetPrefs() override; - - bool IsFillingEnabledForCurrentPage() const override; - bool IsSavingAndFillingEnabledForCurrentPage() const override; + PrefService* GetPrefs() const override; + + autofill::LogManager* GetLogManager() override; + + void CheckProtectedPasswordEntry( + metrics_util::PasswordType reused_password_type, + const std::string& username, + const std::vector& matching_reused_credentials, + bool password_field_exists, + uint64_t reused_password_hash, + const std::string& domain) override; + + ukm::SourceId GetUkmSourceId() override; + PasswordManagerMetricsRecorder* GetMetricsRecorder() override; + bool IsIsolationForPasswordSitesEnabled() const override; + bool IsNewTabPage() const override; + void PromptUserToMovePasswordToAccount( + std::unique_ptr form_to_move) override; + PasswordStore* GetAccountPasswordStore() const override; + const GURL& GetLastCommittedURL() const override; + url::Origin GetLastCommittedOrigin() const override; + signin::IdentityManager* GetIdentityManager() override; + scoped_refptr GetURLLoaderFactory() override; + FieldInfoManager* GetFieldInfoManager() const override; + void FocusedInputChanged( + password_manager::PasswordManagerDriver* driver, + autofill::FieldRendererId focused_field_id, + autofill::mojom::FocusedFieldType focused_field_type) override; + bool IsCommittedMainFrameSecure() const override; + PasswordReuseManager* GetPasswordReuseManager() const override; + safe_browsing::PasswordProtectionService* GetPasswordProtectionService() + const override; + void LogPasswordReuseDetectedEvent() override; + bool IsAutofillAssistantUIVisible() const override; + void HideManualFallbackForSaving() override; + const password_manager::PasswordFeatureManager* GetPasswordFeatureManager() + const override { + return &password_feature_manager_; + } + PrefService* GetLocalStatePrefs() const {} + const syncer::SyncService* GetSyncService() const {} + PasswordScriptsFetcher* GetPasswordScriptsFetcher() {} + PasswordChangeSuccessTracker* GetPasswordChangeSuccessTracker() {} private: explicit PasswordManagerClientEfl(content::WebContents* web_contents, @@ -68,31 +122,59 @@ public: friend class content::WebContentsUserData; - // This filter does not filter out anything, it is a dummy implementation of - // the filter interface. - class PassThroughCredentialsFilter : public CredentialsFilter { - public: - PassThroughCredentialsFilter() {} - - // CredentialsFilter: - ScopedVector FilterResults( - ScopedVector results) const override { - return results.Pass(); - } - bool ShouldSave(const autofill::PasswordForm& form) const override { - return true; - } - }; - PassThroughCredentialsFilter credentials_filter_; + // autofill::mojom::PasswordManagerDriver: + // Note that these messages received from a potentially compromised renderer. + // For that reason, any access to form data should be validated via + // bad_message::CheckChildProcessSecurityPolicy. + void PasswordFormsParsed( + const std::vector& forms) override; + void PasswordFormsRendered( + const std::vector& visible_forms) override; + void PasswordFormSubmitted(const autofill::FormData& password_form) override; + void RecordSavePasswordProgress(const std::string& log) override; + void UserModifiedPasswordField() override; + void ShowPasswordSuggestions(base::i18n::TextDirection text_direction, + const std::u16string& typed_username, + int options, + const gfx::RectF& bounds) override; + void LogFirstFillingResult(autofill::FormRendererId form_renderer_id, + int32_t result) override; + void InformAboutUserInput(const autofill::FormData& form_data) override; + void DynamicFormSubmission(autofill::mojom::SubmissionIndicatorEvent + submission_indication_event) override; + void PasswordFormCleared(const autofill::FormData& form_data) override; + void UserModifiedNonPasswordField(autofill::FieldRendererId renderer_id, + const std::u16string& field_name, + const std::u16string& value) override; + void FocusedInputChanged( + autofill::FieldRendererId focused_field_id, + autofill::mojom::FocusedFieldType focused_field_type) override; + void CheckSafeBrowsingReputation(const GURL& form_action, + const GURL& frame_url) override; + + password_manager::PasswordManager* GetPasswordManager(); + + gfx::RectF TransformToRootCoordinates( + content::RenderFrameHost* frame_host, + const gfx::RectF& bounds_in_frame_coordinates); + + const StubCredentialsFilter credentials_filter_; + autofill::StubLogManager log_manager_; + absl::optional metrics_recorder_; content::WebContents* web_contents_; - password_manager::PasswordManager password_manager_; + content::RenderFrameHostReceiverSet + password_manager_driver_bindings_; + password_manager::PasswordManager password_manager_; + password_manager::PasswordFeatureManagerImpl password_feature_manager_; password_manager::ContentPasswordManagerDriverFactory* driver_factory_; // Allows authentication callbacks to be destroyed when this client is gone. base::WeakPtrFactory weak_factory_; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); }; } diff --git a/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.cc b/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.cc index af9cf1f..4a55a7b 100644 --- a/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.cc +++ b/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.cc @@ -9,14 +9,14 @@ #include "base/command_line.h" #include "base/environment.h" -#include "base/prefs/pref_service.h" -#include "base/path_service.h" #include "base/files/file_path.h" +#include "base/path_service.h" #include "browser/webdata/web_data_service.h" #include "browser/webdata/web_data_service_factory.h" #include "components/password_manager/core/browser/login_database.h" #include "components/password_manager/core/browser/password_store.h" -#include "components/password_manager/core/browser/password_store_default.h" +#include "components/password_manager/core/browser/password_store_built_in_backend.h" +#include "components/sync/model/syncable_service.h" #include "content/common/paths_efl.h" #include "content/public/browser/browser_thread.h" @@ -25,64 +25,52 @@ using password_manager::PasswordStore; PasswordStoreService::PasswordStoreService( scoped_refptr password_store) - : password_store_(password_store) -{ -} + : password_store_(password_store) {} -PasswordStoreService::~PasswordStoreService() -{ -} +PasswordStoreService::~PasswordStoreService() {} -scoped_refptr PasswordStoreService::GetPasswordStore() -{ +scoped_refptr PasswordStoreService::GetProfilePasswordStore() { return password_store_; } // static -scoped_refptr PasswordStoreFactory::GetPasswordStore() -{ +scoped_refptr PasswordStoreFactory::GetProfilePasswordStore() { PasswordStoreService* service = GetInstance()->GetService(); if (!service) - return NULL; - return service->GetPasswordStore(); + return nullptr; + return service->GetProfilePasswordStore(); } // static -PasswordStoreFactory* PasswordStoreFactory::GetInstance() -{ +PasswordStoreFactory* PasswordStoreFactory::GetInstance() { return base::Singleton::get(); } PasswordStoreFactory::PasswordStoreFactory() { - WebDataServiceFactory::GetInstance(); + WebDataServiceFactoryEfl::GetInstance(); Init(); } -PasswordStoreFactory::~PasswordStoreFactory() -{ -} +PasswordStoreFactory::~PasswordStoreFactory() {} -void PasswordStoreFactory::Init() -{ +void PasswordStoreFactory::Init() { base::FilePath db_path; if (!base::PathService::Get(PathsEfl::WEB_DATABASE_DIR, &db_path)) { LOG(ERROR) << "Could not access login database path."; return; } - base::FilePath login_db_file_path = db_path.Append(FILE_PATH_LITERAL(".LoginData.db")); - scoped_ptr login_db(new LoginDatabase(login_db_file_path)); + base::FilePath login_db_file_path = + db_path.Append(FILE_PATH_LITERAL(".LoginData.db")); + std::unique_ptr login_db( + new LoginDatabase(login_db_file_path, IsAccountStore(false))); - scoped_refptr main_thread_runner( - base::ThreadTaskRunnerHandle::Get()); - scoped_refptr db_thread_runner( - content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::DB)); + scoped_refptr ps = new password_manager::PasswordStore( + std::make_unique( + std::move(login_db))); - scoped_refptr ps = new PasswordStoreDefault( - main_thread_runner, db_thread_runner, login_db.Pass()); - if (!ps.get() || !ps->Init(syncer::SyncableService::StartSyncFlare())) { - NOTREACHED() << "Could not initialize password manager."; + if (!ps.get() || !ps->Init(nullptr, nullptr)) { + LOG(ERROR) << "Could not initialize password manager."; return; } diff --git a/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.h b/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.h index 4f5d05e..58bb14e 100644 --- a/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.h +++ b/tizen_src/ewk/efl_integration/browser/password_manager/password_store_factory.h @@ -10,6 +10,7 @@ #include "base/memory/singleton.h" #include "components/password_manager/core/browser/password_manager_driver.h" +#include "components/prefs/pref_service.h" namespace password_manager { class PasswordStore; @@ -25,7 +26,7 @@ class PasswordStoreService { PasswordStoreService(const PasswordStoreService&) = delete; PasswordStoreService& operator=(const PasswordStoreService&) = delete; - scoped_refptr GetPasswordStore(); + scoped_refptr GetProfilePasswordStore(); private: scoped_refptr password_store_; @@ -35,7 +36,7 @@ class PasswordStoreService { // Profiles. class PasswordStoreFactory { public: - static scoped_refptr GetPasswordStore(); + static scoped_refptr GetProfilePasswordStore(); static PasswordStoreFactory* GetInstance(); PasswordStoreService* GetService() { return service_.get(); } diff --git a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.cc b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.cc index 559af0c..554dabf 100644 --- a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.cc +++ b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.cc @@ -7,15 +7,17 @@ #include "browser/webdata/web_data_service.h" -#include "base/bind.h" +#include "base/callback.h" +#include "base/command_line.h" #include "base/stl_util.h" +#include "base/task/thread_pool.h" #include "components/webdata/common/web_database_service.h" +#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" -using base::Bind; using base::Time; using content::BrowserThread; @@ -23,14 +25,14 @@ WebDataService::WebDataService(scoped_refptr wdbs, const ProfileErrorCallback& callback) : WebDataServiceBase( wdbs, - callback, - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)) {} + base::ThreadPool::CreateSingleThreadTaskRunner({BrowserThread::UI})) { +} WebDataService::WebDataService() : WebDataServiceBase( - NULL, - ProfileErrorCallback(), - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)) {} + nullptr, + base::ThreadPool::CreateSingleThreadTaskRunner({BrowserThread::UI})) { +} WebDataService::~WebDataService() { } diff --git a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.h b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.h index cb6a2a9..34ae1a6 100644 --- a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.h +++ b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service.h @@ -17,7 +17,6 @@ #include "base/files/file_path.h" #include "base/location.h" #include "base/memory/ref_counted.h" -#include "base/sequenced_task_runner_helpers.h" #include "components/webdata/common/web_data_results.h" #include "components/webdata/common/web_data_service_base.h" #include "components/webdata/common/web_data_service_consumer.h" @@ -43,8 +42,6 @@ class BrowserContext; // //////////////////////////////////////////////////////////////////////////////// -typedef base::OnceCallback(void)> ResultTask; - class WebDataServiceConsumer; class WebDataService : public WebDataServiceBase { diff --git a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.cc b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.cc index 158d011..ab37e60 100644 --- a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.cc +++ b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.cc @@ -7,24 +7,24 @@ #include "browser/webdata/web_data_service_factory.h" -#include "eweb_view.h" #include "base/bind.h" -#include "base/path_service.h" #include "base/files/file_path.h" -#include "components/autofill/core/browser/autofill_country.h" +#include "base/path_service.h" +#include "base/task/thread_pool.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/autofill/core/browser/geo/autofill_country.h" #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/webdata/common/webdata_constants.h" #include "content/common/paths_efl.h" -#include "content/public/browser/browser_thread.h" +#include "eweb_view.h" using autofill::AutofillWebDataService; -using content::BrowserThread; namespace { // Callback to show error dialog on profile load error. -void ProfileErrorCallback(int type, sql::InitStatus status) { +void ProfileErrorCallback(sql::InitStatus status, const std::string& str) { //TODO:Need to check what type of error to show NOTIMPLEMENTED(); } @@ -39,95 +39,70 @@ void InitSyncableServicesOnDBThread( } // namespace -WebDataServiceWrapper* WebDataServiceWrapper::GetInstance(){ - return base::Singleton::get(); +WebDataServiceWrapperEfl* WebDataServiceWrapperEfl::GetInstance() { + return base::Singleton::get(); } -WebDataServiceWrapper::WebDataServiceWrapper() { +WebDataServiceWrapperEfl::WebDataServiceWrapperEfl() { base::FilePath db_path; base::PathService::Get(PathsEfl::WEB_DATABASE_DIR, &db_path); base::FilePath path = db_path.Append(FILE_PATH_LITERAL(".FormData.db")); - web_database_ = new WebDatabaseService( - path, BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup - BrowserThread::GetTaskRunnerForThread(BrowserThread::DB)); -#else - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)); -#endif + auto ui_task_runner = base::ThreadTaskRunnerHandle::Get(); + // TODO(pkasting): http://crbug.com/740773 This should likely be sequenced, + // not single-threaded; it's also possible these objects can each use their + // own sequences instead of sharing this one. + auto db_task_runner = base::ThreadPool::CreateSingleThreadTaskRunner( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); + + web_database_ = new WebDatabaseService(path, ui_task_runner, db_task_runner); // All tables objects that participate in managing the database must // be added here. - web_database_->AddTable(make_scoped_ptr(new autofill::AutofillTable)); + web_database_->AddTable(base::WrapUnique(new autofill::AutofillTable)); web_database_->LoadDatabase(); - autofill_web_data_ = new AutofillWebDataService( - web_database_, BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), -#if !defined(EWK_BRINGUP) // FIXME: m67 bringup - BrowserThread::GetTaskRunnerForThread(BrowserThread::DB), -#else - BrowserThread::GetTaskRunnerForThread(BrowserThread::DB), -#endif - base::BindOnce(&ProfileErrorCallback, 0)); - autofill_web_data_->Init(); - - web_data_ = new WebDataService(web_database_, - base::BindOnce(&ProfileErrorCallback, 0)); - web_data_->Init(); + autofill_web_data_ = + new AutofillWebDataService(web_database_, ui_task_runner, db_task_runner); + autofill_web_data_->Init(base::BindOnce(&ProfileErrorCallback)); autofill_web_data_->GetAutofillBackend( base::BindOnce(&InitSyncableServicesOnDBThread, autofill_web_data_, db_path, EWebView::GetPlatformLocale())); } -WebDataServiceWrapper::~WebDataServiceWrapper() { -} +WebDataServiceWrapperEfl::~WebDataServiceWrapperEfl() {} scoped_refptr -WebDataServiceWrapper::GetAutofillWebData() { +WebDataServiceWrapperEfl::GetAutofillWebData() { return autofill_web_data_.get(); } -scoped_refptr WebDataServiceWrapper::GetWebData() { - return web_data_.get(); -} - - -// static -scoped_refptr WebDataService::FromBrowserContext( - content::BrowserContext* context) { - WebDataServiceWrapper* wrapper = WebDataServiceFactory::GetDataService(); - if (wrapper) - return wrapper->GetWebData(); - // |wrapper| can be NULL in Incognito mode. - return scoped_refptr(NULL); -} - -WebDataServiceFactory::WebDataServiceFactory(){ - // WebDataServiceFactory has no dependecies. +WebDataServiceFactoryEfl::WebDataServiceFactoryEfl() { + // WebDataServiceFactoryEfl has no dependecies. } -WebDataServiceFactory::~WebDataServiceFactory() {} +WebDataServiceFactoryEfl::~WebDataServiceFactoryEfl() {} // static -WebDataServiceWrapper* WebDataServiceFactory::GetDataService() { - return WebDataServiceWrapper::GetInstance(); +WebDataServiceWrapperEfl* WebDataServiceFactoryEfl::GetDataService() { + return WebDataServiceWrapperEfl::GetInstance(); } // static scoped_refptr -WebDataServiceFactory::GetAutofillWebDataForProfile() { - WebDataServiceWrapper* wrapper = - WebDataServiceFactory::GetDataService(); +WebDataServiceFactoryEfl::GetAutofillWebDataForProfile() { + WebDataServiceWrapperEfl* wrapper = + WebDataServiceFactoryEfl::GetDataService(); // |wrapper| can be NULL in Incognito mode. - return wrapper ? - wrapper->GetAutofillWebData() : - scoped_refptr(NULL); + return wrapper ? wrapper->GetAutofillWebData() + : scoped_refptr(nullptr); } // static -WebDataServiceFactory* WebDataServiceFactory::GetInstance() { - return base::Singleton::get(); +WebDataServiceFactoryEfl* WebDataServiceFactoryEfl::GetInstance() { + return base::Singleton::get(); } #endif // TIZEN_AUTOFILL_SUPPORT diff --git a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.h b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.h index 14a1e2b..9ee9c67 100644 --- a/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.h +++ b/tizen_src/ewk/efl_integration/browser/webdata/web_data_service_factory.h @@ -19,46 +19,43 @@ namespace autofill { class AutofillWebDataService; } // namespace autofill -class WebDataServiceWrapper{ +class WebDataServiceWrapperEfl { public: - explicit WebDataServiceWrapper(); + explicit WebDataServiceWrapperEfl(); - virtual ~WebDataServiceWrapper(); + virtual ~WebDataServiceWrapperEfl(); - WebDataServiceWrapper(const WebDataServiceWrapper&) = delete; - WebDataServiceWrapper& operator=(const WebDataServiceWrapper&) = delete; + WebDataServiceWrapperEfl(const WebDataServiceWrapperEfl&) = delete; + WebDataServiceWrapperEfl& operator=(const WebDataServiceWrapperEfl&) = delete; virtual scoped_refptr GetAutofillWebData(); - virtual scoped_refptr GetWebData(); + static WebDataServiceWrapperEfl* GetInstance(); - static WebDataServiceWrapper* GetInstance(); private: scoped_refptr web_database_; - scoped_refptr autofill_web_data_; scoped_refptr web_data_; }; -// Singleton that owns all WebDataServiceWrappers -class WebDataServiceFactory { +// Singleton that owns all WebDataServiceWrapperEfls +class WebDataServiceFactoryEfl { public: - - static WebDataServiceWrapper* GetDataService(); + static WebDataServiceWrapperEfl* GetDataService(); static scoped_refptr GetAutofillWebDataForProfile(); - static WebDataServiceFactory* GetInstance(); + static WebDataServiceFactoryEfl* GetInstance(); private: - friend struct base::DefaultSingletonTraits; + friend struct base::DefaultSingletonTraits; - WebDataServiceFactory(); - virtual ~WebDataServiceFactory(); + WebDataServiceFactoryEfl(); + virtual ~WebDataServiceFactoryEfl(); - WebDataServiceFactory(const WebDataServiceFactory&) = delete; - WebDataServiceFactory& operator=(const WebDataServiceFactory&) = delete; + WebDataServiceFactoryEfl(const WebDataServiceFactoryEfl&) = delete; + WebDataServiceFactoryEfl& operator=(const WebDataServiceFactoryEfl&) = delete; }; #endif // TIZEN_AUTOFILL_SUPPORT diff --git a/tizen_src/ewk/efl_integration/browser_context_efl.cc b/tizen_src/ewk/efl_integration/browser_context_efl.cc index ff0ea68..42348cf 100644 --- a/tizen_src/ewk/efl_integration/browser_context_efl.cc +++ b/tizen_src/ewk/efl_integration/browser_context_efl.cc @@ -8,11 +8,13 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/synchronization/waitable_event.h" +#include "browser/autofill/autocomplete_history_manager_factory.h" #include "browser/autofill/personal_data_manager_factory.h" #include "browser/background_sync_controller_efl.h" #include "browser/geolocation/geolocation_permission_context_efl.h" #include "browser/webdata/web_data_service_factory.h" #include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/common/autofill_prefs.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/in_memory_pref_store.h" #include "components/prefs/pref_registry_simple.h" @@ -29,7 +31,7 @@ #include "network_delegate_efl.h" #include "permission_controller_delegate_efl.h" -using namespace prefs; +using namespace autofill::prefs; using namespace password_manager::prefs; using std::pair; @@ -58,8 +60,10 @@ BrowserContextEfl::ResourceContextEfl::ResourceContextEfl( BrowserContextEfl::~BrowserContextEfl() { NotifyWillBeDestroyed(); #if defined(TIZEN_AUTOFILL_SUPPORT) - autofill::PersonalDataManagerFactory::GetInstance() + autofill::PersonalDataManagerFactoryEfl::GetInstance() ->PersonalDataManagerRemove(this); + autofill::AutocompleteHistoryManagerFactoryEfl::GetInstance() + ->AutocompleteHistoryManagerRemove(this); #endif ShutdownStoragePartitions(); if (resource_context_) @@ -134,11 +138,16 @@ BrowserContextEfl::BrowserContextEfl(EWebContext* web_context, bool incognito) PrefRegistrySimple* pref_registry = new PrefRegistrySimple(); -#if !defined(EWK_BRINGUP) // FIXME: m71 bringup - pref_registry->RegisterBooleanPref(kAutofillEnabled, true); +#if defined(TIZEN_AUTOFILL_SUPPORT) + // autofill preferences + pref_registry->RegisterBooleanPref(kAutofillProfileEnabled, true); pref_registry->RegisterBooleanPref(kAutofillWalletImportEnabled, true); -#endif + pref_registry->RegisterBooleanPref(kAutofillCreditCardEnabled, true); + + // password manager preferences pref_registry->RegisterBooleanPref(kCredentialsEnableService, true); + pref_registry->RegisterBooleanPref(kCredentialsEnableAutosignin, true); +#endif PrefServiceFactory pref_service_factory; pref_service_factory.set_user_prefs( @@ -150,8 +159,10 @@ BrowserContextEfl::BrowserContextEfl(EWebContext* web_context, bool incognito) user_prefs::UserPrefs::Set(this, user_pref_service_.get()); #if defined(TIZEN_AUTOFILL_SUPPORT) - autofill::PersonalDataManagerFactory::GetInstance()->PersonalDataManagerAdd( - this); + autofill::PersonalDataManagerFactoryEfl::GetInstance() + ->PersonalDataManagerAdd(this); + autofill::AutocompleteHistoryManagerFactoryEfl::GetInstance() + ->AutocompleteHistoryManagerAdd(this); #endif #if !defined(EWK_BRINGUP) // FIXME: m85 bringup BrowserContext::Initialize(this, GetPath()); diff --git a/tizen_src/ewk/efl_integration/command_line_efl.cc b/tizen_src/ewk/efl_integration/command_line_efl.cc index 8ed5784..63b9e7d 100644 --- a/tizen_src/ewk/efl_integration/command_line_efl.cc +++ b/tizen_src/ewk/efl_integration/command_line_efl.cc @@ -13,6 +13,7 @@ #include "base/logging.h" #include "cc/base/switches.h" #include "common/content_switches_efl.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/viz/common/switches.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc index 837b144..00ab5fa 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.cc +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.cc @@ -20,8 +20,10 @@ #include "common/content_switches_efl.h" #include "common/version_info.h" #include "common/web_contents_utils.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/error_page/common/error.h" #include "components/error_page/common/localized_error.h" +#include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_process_host.h" @@ -32,11 +34,16 @@ #include "content/public/common/content_switches.h" #include "devtools_manager_delegate_efl.h" #include "eweb_context.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "services/network/public/cpp/features.h" #include "shared_url_loader_factory_efl.h" #include "web_contents_delegate_efl.h" #include "web_contents_view_delegate_ewk.h" +#if defined(TIZEN_AUTOFILL_SUPPORT) +#include "components/autofill/core/common/autofill_switches.h" +#endif + #if BUILDFLAG(IS_TIZEN) #include #include "content/browser/speech/tts_message_filter_efl.h" @@ -487,6 +494,35 @@ ContentBrowserClientEfl::GetWebContentsViewDelegate(WebContents* web_contents) { WebViewFromWebContents(web_contents)); } +bool ContentBrowserClientEfl::BindAssociatedReceiverFromFrame( + RenderFrameHost* render_frame_host, + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { +#if defined(TIZEN_AUTOFILL_SUPPORT) + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + autofill::switches::kDisableAutofill)) { + return false; + } + + if (interface_name == autofill::mojom::AutofillDriver::Name_) { + autofill::ContentAutofillDriverFactory::BindAutofillDriver( + mojo::PendingAssociatedReceiver( + std::move(*handle)), + render_frame_host); + return true; + } + if (interface_name == autofill::mojom::PasswordManagerDriver::Name_) { + password_manager::ContentPasswordManagerDriverFactory:: + BindPasswordManagerDriver( + mojo::PendingAssociatedReceiver< + autofill::mojom::PasswordManagerDriver>(std::move(*handle)), + render_frame_host); + return true; + } +#endif + return false; +} + scoped_refptr ContentBrowserClientEfl::CreateQuotaPermissionContext() { return new QuotaPermissionContextEfl(); diff --git a/tizen_src/ewk/efl_integration/content_browser_client_efl.h b/tizen_src/ewk/efl_integration/content_browser_client_efl.h index 5ba1b1a..3482caa 100644 --- a/tizen_src/ewk/efl_integration/content_browser_client_efl.h +++ b/tizen_src/ewk/efl_integration/content_browser_client_efl.h @@ -8,6 +8,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "net/cookies/canonical_cookie.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/web/web_window_features.h" @@ -123,6 +124,12 @@ class ContentBrowserClientEfl : public ContentBrowserClient { scoped_refptr response_headers, bool first_auth_attempt, LoginAuthRequiredCallback auth_required_callback) override; + + bool BindAssociatedReceiverFromFrame( + RenderFrameHost* render_frame_host, + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; + std::string GetProduct() override; std::string GetUserAgent() override; NotificationControllerEfl* GetNotificationController() const; diff --git a/tizen_src/ewk/efl_integration/eweb_context.cc b/tizen_src/ewk/efl_integration/eweb_context.cc index 6e0ef15..6c33ec4 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.cc +++ b/tizen_src/ewk/efl_integration/eweb_context.cc @@ -14,9 +14,13 @@ #include "base/synchronization/waitable_event.h" #include "base/task/thread_pool.h" #include "browser/favicon/favicon_database.h" +#include "browser/password_manager/password_helper_efl.h" #include "browser/tizen_extensible_host.h" #include "browser/webdata/web_data_service_factory.h" #include "components/autofill/content/browser/content_autofill_driver.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/password_manager/core/browser/password_form.h" +#include "components/password_manager/core/browser/password_store.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -193,6 +197,24 @@ void OnGetFileSystemOrigins( base::BindOnce(callback, origin_list, user_data)); } +void OnGetPasswordDataList( + Ewk_Context_Form_Password_Data_List_Get_Callback callback, + void* user_data, + const std::vector>& + results) { + Eina_List* list = nullptr; + + for (const auto& form : results) { + auto data = new Ewk_Password_Data; + data->url = strdup(form->federation_origin.Serialize().c_str()); + // NOTE: Fingerprint is not supported yet, so it is always FALSE. + data->useFingerprint = EINA_FALSE; + list = eina_list_append(list, data); + } + + callback(list, user_data); +} + } // namespace void EwkDidStartDownloadCallback::TriggerCallback(const string& url) { @@ -727,8 +749,8 @@ void EWebContext::ClearCandidateData() { base::Unretained(this))); return; } - WebDataServiceFactory* webDataServiceInstance = - WebDataServiceFactory::GetInstance(); + WebDataServiceFactoryEfl* webDataServiceInstance = + WebDataServiceFactoryEfl::GetInstance(); scoped_refptr autofillWebDataService = webDataServiceInstance->GetAutofillWebDataForProfile(); if (autofillWebDataService.get()) { @@ -746,11 +768,31 @@ void EWebContext::ClearCandidateData() { void EWebContext::ClearPasswordData() { #if defined(TIZEN_AUTOFILL_SUPPORT) - scoped_refptr store = - password_manager::PasswordStoreFactory::GetPasswordStore(); - if (store.get()) - store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(), - base::Closure()); + password_helper::RemoveLogins( + password_manager::PasswordStoreFactory::GetProfilePasswordStore()); +#else + DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled"; +#endif +} + +void EWebContext::ClearPasswordDataForUrl(const char* url) { +#if defined(TIZEN_AUTOFILL_SUPPORT) + password_helper::RemoveLogin( + password_manager::PasswordStoreFactory::GetProfilePasswordStore(), + GURL(url)); +#else + DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled"; +#endif +} + +void EWebContext::GetPasswordDataList( + Ewk_Context_Form_Password_Data_List_Get_Callback callback, + void* user_data) { +#if defined(TIZEN_AUTOFILL_SUPPORT) + password_helper::GetLogins( + password_manager::PasswordStoreFactory::GetProfilePasswordStore(), + base::BindRepeating(&OnGetPasswordDataList, base::Unretained(callback), + base::Unretained(user_data))); #else DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled"; #endif diff --git a/tizen_src/ewk/efl_integration/eweb_context.h b/tizen_src/ewk/efl_integration/eweb_context.h index 560b3aa..b43a6fb 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.h +++ b/tizen_src/ewk/efl_integration/eweb_context.h @@ -149,6 +149,11 @@ class EWebContext { void ClearCandidateData(); void ClearPasswordData(); + void ClearPasswordDataForUrl(const char* url); + void GetPasswordDataList( + Ewk_Context_Form_Password_Data_List_Get_Callback callback, + void* user_data); + EwkFaviconDatabase* GetFaviconDatabase() const { return ewk_favicon_database_.get(); } diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc b/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc index 182d00a..7f09a38 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc +++ b/tizen_src/ewk/efl_integration/private/ewk_context_form_autofill_profile_private.cc @@ -21,7 +21,7 @@ #include "private/ewk_context_private.h" namespace autofill { -class PersonalDataManagerFactory; +class PersonalDataManagerFactoryEfl; } namespace { @@ -70,14 +70,8 @@ static std::map create_EWK_to_Autofill_prof profile_map[PROFILE_CITY_TOWN] = autofill::ADDRESS_HOME_CITY; profile_map[PROFILE_STATE_PROVINCE_REGION] = autofill::ADDRESS_HOME_STATE; profile_map[PROFILE_ZIPCODE] = autofill::ADDRESS_HOME_ZIP; - - // ADDRESS_HOME_COUNTRY is not saved in the database, so we use - // ADDRESS_BILLING_DEPENDENT_LOCALITY instead, that isn't used - profile_map[PROFILE_COUNTRY] = autofill::ADDRESS_BILLING_DEPENDENT_LOCALITY; - - // PHONE_HOME_WHOLE_NUMBER is not saved in the database, so we use - // ADDRESS_BILLING_LINE3 instead, that isn't used - profile_map[PROFILE_PHONE] = autofill::ADDRESS_BILLING_LINE3; + profile_map[PROFILE_COUNTRY] = autofill::ADDRESS_HOME_COUNTRY; + profile_map[PROFILE_PHONE] = autofill::PHONE_HOME_WHOLE_NUMBER; profile_map[PROFILE_EMAIL] = autofill::EMAIL_ADDRESS; return profile_map; } @@ -90,8 +84,11 @@ void to_Autofill_Profile_set_data(const Ewk_Autofill_Profile* oldStyleProfile, static std::map profile_map = create_EWK_to_Autofill_profile_map(); if (0 < (value = oldStyleProfile->get16Data(DataName)).length()) { - ret.SetInfo(autofill::AutofillType(profile_map.find(DataName)->second), - value, locale); + if (DataName == PROFILE_NAME || DataName == PROFILE_COUNTRY) { + ret.SetInfo(autofill::AutofillType(profile_map.find(DataName)->second), + value, locale); + } else + ret.SetRawInfo(profile_map.find(DataName)->second, value); } } @@ -146,11 +143,15 @@ void to_EWK_Profile_set_data(const autofill::AutofillProfile& newStyleProfile, std::u16string value; static std::map profile_map = create_Autofill_to_EWK_profile_map(); - if (0 < (value = newStyleProfile.GetInfo(autofill::AutofillType( - DataName), locale)).length()) { - ret->setData(profile_map.find(DataName)->second, - base::UTF16ToASCII(value)); + if (DataName == autofill::NAME_FULL || + DataName == autofill::ADDRESS_HOME_COUNTRY) { + value = newStyleProfile.GetInfo(autofill::AutofillType(DataName), locale); + } else { + value = newStyleProfile.GetRawInfo(DataName); } + + if (value.length()) + ret->setData(profile_map.find(DataName)->second, base::UTF16ToASCII(value)); } Ewk_Autofill_Profile* to_Ewk_Autofill_Profile( @@ -174,16 +175,10 @@ Ewk_Autofill_Profile* to_Ewk_Autofill_Profile( autofill::ADDRESS_HOME_STATE, locale, ret); to_EWK_Profile_set_data(newStyleProfile, autofill::ADDRESS_HOME_ZIP, locale, ret); - - // ADDRESS_HOME_COUNTRY is not saved in the database, so we use - // ADDRESS_BILLING_DEPENDENT_LOCALITY instead, that isn't used - to_EWK_Profile_set_data(newStyleProfile, - autofill::ADDRESS_BILLING_DEPENDENT_LOCALITY, locale, ret); - - // PHONE_HOME_WHOLE_NUMBER is not saved in the database, so we use - // ADDRESS_BILLING_LINE3 instead, that isn't used - to_EWK_Profile_set_data(newStyleProfile, - autofill::ADDRESS_BILLING_LINE3, locale, ret); + to_EWK_Profile_set_data(newStyleProfile, autofill::ADDRESS_HOME_COUNTRY, + locale, ret); + to_EWK_Profile_set_data(newStyleProfile, autofill::PHONE_HOME_WHOLE_NUMBER, + locale, ret); to_EWK_Profile_set_data(newStyleProfile, autofill::EMAIL_ADDRESS, locale, ret); return ret; @@ -193,8 +188,8 @@ autofill::PersonalDataManager* PersonalDataManagerForEWKContext( Ewk_Context* ewk_context) { EINA_SAFETY_ON_NULL_RETURN_VAL(ewk_context, nullptr); - autofill::PersonalDataManagerFactory* personal_data_manager_factory = - autofill::PersonalDataManagerFactory::GetInstance(); + autofill::PersonalDataManagerFactoryEfl* personal_data_manager_factory = + autofill::PersonalDataManagerFactoryEfl::GetInstance(); content::BrowserContext* context = ewk_context->browser_context(); EINA_SAFETY_ON_NULL_RETURN_VAL(context, nullptr); @@ -287,8 +282,8 @@ void EwkContextFormAutofillProfileManager::priv_form_autofill_profile_changed_callback_set( Ewk_Context_Form_Autofill_Profile_Changed_Callback callback, void* user_data) { - autofill::PersonalDataManagerFactory* personalDataManagerFactory = - autofill::PersonalDataManagerFactory::GetInstance(); + autofill::PersonalDataManagerFactoryEfl* personalDataManagerFactory = + autofill::PersonalDataManagerFactoryEfl::GetInstance(); personalDataManagerFactory->SetCallback(callback, user_data); } diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_private.cc b/tizen_src/ewk/efl_integration/private/ewk_context_private.cc index f10f434..922eb928 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_private.cc +++ b/tizen_src/ewk/efl_integration/private/ewk_context_private.cc @@ -247,6 +247,16 @@ void Ewk_Context::ClearPasswordData() { impl->ClearPasswordData(); } +void Ewk_Context::ClearPasswordDataForUrl(const char* url) { + impl->ClearPasswordDataForUrl(url); +} + +void Ewk_Context::GetPasswordDataList( + Ewk_Context_Form_Password_Data_List_Get_Callback callback, + void* user_data) { + impl->GetPasswordDataList(callback, user_data); +} + unsigned int Ewk_Context::InspectorServerStart(unsigned int port) const { return impl->InspectorServerStart(port); } diff --git a/tizen_src/ewk/efl_integration/private/ewk_context_private.h b/tizen_src/ewk/efl_integration/private/ewk_context_private.h index d6daffc..ee969bf 100644 --- a/tizen_src/ewk/efl_integration/private/ewk_context_private.h +++ b/tizen_src/ewk/efl_integration/private/ewk_context_private.h @@ -113,6 +113,10 @@ struct Ewk_Context : public base::RefCounted { // Password void ClearPasswordData(); + void ClearPasswordDataForUrl(const char* url); + void GetPasswordDataList( + Ewk_Context_Form_Password_Data_List_Get_Callback callback, + void* user_data); // Extensible bool SetExtensibleAPI(const std::string& api_name, bool enable); diff --git a/tizen_src/ewk/efl_integration/public/ewk_context.cc b/tizen_src/ewk/efl_integration/public/ewk_context.cc index 358a9679..3353d91 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_context.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_context.cc @@ -411,18 +411,30 @@ void ewk_context_form_password_data_delete_all(Ewk_Context* context) void ewk_context_form_password_data_delete(Ewk_Context* ewkContext, const char* url) { - LOG_EWK_API_MOCKUP(); + EINA_SAFETY_ON_NULL_RETURN(ewkContext); + EINA_SAFETY_ON_NULL_RETURN(url); + ewkContext->ClearPasswordDataForUrl(url); } -Eina_List* ewk_context_form_password_data_list_get(Ewk_Context* ewkContext) -{ - LOG_EWK_API_MOCKUP(); - return NULL; +void ewk_context_form_password_data_list_get( + Ewk_Context* ewkContext, + Ewk_Context_Form_Password_Data_List_Get_Callback callback, + void* user_data) { + EINA_SAFETY_ON_NULL_RETURN(ewkContext); + EINA_SAFETY_ON_NULL_RETURN(callback); + ewkContext->GetPasswordDataList(callback, user_data); } void ewk_context_form_password_data_list_free(Ewk_Context* ewkContext, Eina_List* list) { - LOG_EWK_API_MOCKUP(); + EINA_SAFETY_ON_NULL_RETURN(ewkContext); + EINA_SAFETY_ON_NULL_RETURN(list); + + void* item; + EINA_LIST_FREE(list, item) { + delete[] (static_cast(item))->url; + delete static_cast(item); + } } void ewk_context_form_candidate_data_delete_all(Ewk_Context* context) @@ -789,11 +801,6 @@ void ewk_context_password_confirm_popup_reply(Ewk_Context* context, Ewk_Context_ LOG_EWK_API_MOCKUP(); } -void ewk_context_form_password_data_list_get(Ewk_Context* context, Ewk_Context_Form_Password_Data_List_Get_Callback callback, void* user_data) -{ - LOG_EWK_API_MOCKUP(); -} - void ewk_context_icon_database_delete_all(Ewk_Context* context) { LOG_EWK_API_MOCKUP(); diff --git a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc index aaf4c52..b182d0b 100644 --- a/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc +++ b/tizen_src/ewk/efl_integration/renderer/content_renderer_client_efl.cc @@ -50,8 +50,10 @@ #if defined(TIZEN_AUTOFILL_SUPPORT) #include "components/autofill/content/renderer/autofill_agent.h" +#include "components/autofill/content/renderer/autofill_assistant_agent.h" #include "components/autofill/content/renderer/password_autofill_agent.h" #include "components/autofill/content/renderer/password_generation_agent.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/password_generation_util.h" #endif @@ -66,6 +68,7 @@ #if defined(TIZEN_AUTOFILL_SUPPORT) using autofill::AutofillAgent; +using autofill::AutofillAssistantAgent; using autofill::PasswordAutofillAgent; using autofill::PasswordGenerationAgent; #endif @@ -146,19 +149,29 @@ void ContentRendererClientEfl::RenderThreadStarted() { } void ContentRendererClientEfl::RenderFrameCreated(content::RenderFrame* render_frame) { - new content::RenderFrameObserverEfl(render_frame); + content::RenderFrameObserverEfl* render_frame_observer = + new content::RenderFrameObserverEfl(render_frame); new content::ContentSettingsClientEfl(render_frame); // Deletes itself when render_frame is destroyed. new content::GinNativeBridgeDispatcher(render_frame); #if defined(TIZEN_AUTOFILL_SUPPORT) - PasswordAutofillAgent* password_autofill_agent = - new PasswordAutofillAgent(render_frame); - PasswordGenerationAgent* password_generation_agent = - new PasswordGenerationAgent(render_frame, password_autofill_agent); - new AutofillAgent(render_frame, - password_autofill_agent, - password_generation_agent); + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + autofill::switches::kDisableAutofill)) { + blink::AssociatedInterfaceRegistry* registry = + render_frame_observer->associated_interfaces(); + + AutofillAssistantAgent* autofill_assistant_agent = + new AutofillAssistantAgent(render_frame); + PasswordAutofillAgent* password_autofill_agent = + new PasswordAutofillAgent(render_frame, registry); + PasswordGenerationAgent* password_generation_agent = + new PasswordGenerationAgent(render_frame, password_autofill_agent, + registry); + new AutofillAgent(render_frame, password_autofill_agent, + password_generation_agent, autofill_assistant_agent, + registry); + } #endif } diff --git a/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.cc b/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.cc index 170608a..f5f3208 100644 --- a/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.cc +++ b/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.cc @@ -62,6 +62,18 @@ RenderFrameObserverEfl::RenderFrameObserverEfl(RenderFrame* render_frame) RenderFrameObserverEfl::~RenderFrameObserverEfl() { } +void RenderFrameObserverEfl::OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) { + registry_.TryBindInterface(interface_name, interface_pipe); +} + +bool RenderFrameObserverEfl::OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { + return associated_interfaces_.TryBindInterface(interface_name, handle); +} + void RenderFrameObserverEfl::OnDestruct() { delete this; } diff --git a/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.h b/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.h index ebd5523..9b56cb3 100644 --- a/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.h +++ b/tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.h @@ -8,6 +8,8 @@ #include #include "content/public/renderer/render_frame_observer.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "ui/gfx/geometry/size.h" namespace blink { @@ -21,11 +23,25 @@ class RenderFrameImpl; class RenderFrameObserverEfl : public RenderFrameObserver { public: explicit RenderFrameObserverEfl(RenderFrame* render_frame); - virtual ~RenderFrameObserverEfl(); + ~RenderFrameObserverEfl() override; + + RenderFrameObserverEfl(const RenderFrameObserverEfl&) = delete; + RenderFrameObserverEfl& operator=(const RenderFrameObserverEfl&) = delete; + + service_manager::BinderRegistry* registry() { return ®istry_; } + blink::AssociatedInterfaceRegistry* associated_interfaces() { + return &associated_interfaces_; + } + + void OnInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe) override; + bool OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; void OnDestruct() override; - // IPC::Listener implementation. bool OnMessageReceived(const IPC::Message& message) override; void DidChangeScrollOffset() override; @@ -50,6 +66,8 @@ class RenderFrameObserverEfl : public RenderFrameObserver { gfx::Size max_scroll_offset_; gfx::Size last_scroll_offset_; gfx::Size last_sent_contents_size_; + service_manager::BinderRegistry registry_; + blink::AssociatedInterfaceRegistry associated_interfaces_; }; } // namespace content diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc index c1d6e59..16b6108 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc @@ -50,11 +50,13 @@ #endif #if defined(TIZEN_AUTOFILL_SUPPORT) +#include "base/command_line.h" #include "browser/autofill/autofill_client_efl.h" -#include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "browser/password_manager/password_manager_client_efl.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/autofill_manager.h" +#include "components/autofill/core/common/autofill_switches.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" using autofill::AutofillManager; @@ -86,15 +88,19 @@ WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view) web_contents_(view->web_contents()), contents_observer_(std::make_unique(view, this)) { #if defined(TIZEN_AUTOFILL_SUPPORT) - AutofillClientEfl::CreateForWebContents(&web_contents_); - AutofillClientEfl* autofill_client = - AutofillClientEfl::FromWebContents(&web_contents_); - autofill_client->SetEWebView(view); - PasswordManagerClientEfl::CreateForWebContentsWithAutofillClient( - &web_contents_, autofill_client); - ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( - &web_contents_, autofill_client, EWebView::GetPlatformLocale(), - AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER); + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + autofill::switches::kDisableAutofill)) { + AutofillClientEfl::CreateForWebContents(&web_contents_); + AutofillClientEfl* autofill_client = + AutofillClientEfl::FromWebContents(&web_contents_); + autofill_client->SetEWebView(view); + PasswordManagerClientEfl::CreateForWebContentsWithAutofillClient( + &web_contents_, autofill_client); + ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( + &web_contents_, autofill_client, + base::BindRepeating(&autofill::BrowserDriverInitHook, autofill_client, + EWebView::GetPlatformLocale())); + } #endif } @@ -410,6 +416,25 @@ void WebContentsDelegateEfl::SetContentSecurityPolicy( contents_observer_->SetContentSecurityPolicy(policy, header_type); } +#if defined(TIZEN_AUTOFILL_SUPPORT) +void WebContentsDelegateEfl::UpdateAutofillIfRequired() { + if (AutofillClientEfl* autofill_client = + AutofillClientEfl::FromWebContents(&web_contents_)) { + autofill_client->UpdateAutofillIfRequired(); + } +} +#endif + +void WebContentsDelegateEfl::OnDidChangeFocusedNodeBounds( + const gfx::RectF& focused_node_bounds) { +#if defined(TIZEN_AUTOFILL_SUPPORT) + if (AutofillClientEfl* autofill_client = + AutofillClientEfl::FromWebContents(&web_contents_)) { + autofill_client->DidChangeFocusedNodeBounds(focused_node_bounds); + } +#endif +} + void WebContentsDelegateEfl::FindReply(WebContents* web_contents, int request_id, int number_of_matches, @@ -452,7 +477,7 @@ void WebContentsDelegateEfl::OnUpdateSettings(const Ewk_Settings* settings) { PasswordManagerClientEfl::FromWebContents(&web_contents_); if (client) { PrefService* prefs = client->GetPrefs(); - prefs->SetBoolean(password_manager::prefs::kPasswordManagerSavingEnabled, + prefs->SetBoolean(password_manager::prefs::kCredentialsEnableService, settings->autofillPasswordForm()); } #endif diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h index add0161..dcb7068 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h @@ -138,12 +138,15 @@ class WebContentsDelegateEfl : public WebContentsDelegate { MediaResponseCallback callback); #endif +#if defined(TIZEN_AUTOFILL_SUPPORT) + void UpdateAutofillIfRequired(); +#endif private: void OnDidGetManifest(Ewk_View_Request_Manifest_Callback callback, void* user_data, const GURL& manifest_url, blink::mojom::ManifestPtr manifest); - + void OnDidChangeFocusedNodeBounds(const gfx::RectF& focused_node_bounds); EWebView* web_view_; bool is_fullscreen_; WebContents& web_contents_; diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index d5d0875..686e21d 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc @@ -1169,6 +1169,15 @@ std::u16string ResourceBundle::GetLocalizedStringImpl(int resource_id) const { // Fall back on the main data pack (shouldn't be any strings here except // in unittests). data = GetRawDataResource(resource_id); +#if BUILDFLAG(IS_EFL) + // Accessing autofill component resources causes crash in chromium-efl. + // Hence we retain the code same as M85 for now. + if (data.empty()) { + LOG(WARNING) << "unable to find resource: " << resource_id; + NOTREACHED(); + return std::u16string(); + } +#else CHECK(!data.empty()) << "Unable to find resource: " << resource_id << ". If this happens in a browser test running on Windows, it may " @@ -1176,6 +1185,7 @@ std::u16string ResourceBundle::GetLocalizedStringImpl(int resource_id) const { " resource, causing the resource to be stripped out because the " "resource is not used by chrome.dll. See " "https://crbug.com/1181150."; +#endif } } -- 2.7.4 From a2ed26101c1ea7b8380a36703d0062dda96a7dee Mon Sep 17 00:00:00 2001 From: v-saha Date: Tue, 24 Jan 2023 12:19:37 +0530 Subject: [PATCH 16/16] [M108 Migration] Support unlimitedstorage privilege for Indexed DB The unlimitedstorage privilege can be granted when temporary quota is exceeded during indexedDB transaction. The minimum preserve space for system is changed to 10% of the total disk space from 1GB. The unlimitedstorage quota is the amount of available disk space excluding 10% of the total disk space. the maximum quota is less than or equal to 2GB. Reference: https://review.tizen.org/gerrit/277648 Change-Id: Ib2a05423c1d2b3ed7cb8db44caad8705941d99b9 Signed-off-by: v-saha --- .../background_fetch_test_data_manager.cc | 4 +- content/browser/indexed_db/transaction_impl.cc | 3 +- storage/browser/quota/quota_client_type.h | 1 + storage/browser/quota/quota_manager_impl.cc | 51 ++++++++++++++ storage/browser/quota/quota_manager_impl.h | 18 +++++ storage/browser/quota/quota_manager_proxy.cc | 19 ++++- storage/browser/quota/quota_manager_proxy.h | 4 +- storage/browser/quota/special_storage_policy.h | 12 ++++ storage/browser/test/mock_quota_manager_proxy.cc | 4 +- storage/browser/test/mock_quota_manager_proxy.h | 4 +- tizen_src/ewk/efl_integration/BUILD.gn | 2 + .../browser/special_storage_policy_efl.cc | 82 ++++++++++++++++++++++ .../browser/special_storage_policy_efl.h | 52 ++++++++++++++ .../ewk/efl_integration/browser_context_efl.cc | 6 ++ .../ewk/efl_integration/browser_context_efl.h | 5 +- tizen_src/ewk/efl_integration/eweb_view.cc | 48 +++++++++++++ tizen_src/ewk/efl_integration/eweb_view.h | 38 ++++++++++ tizen_src/ewk/efl_integration/public/ewk_view.cc | 10 +-- tizen_src/ewk/ubrowser/window.cc | 11 +++ tizen_src/ewk/ubrowser/window.h | 5 ++ 20 files changed, 366 insertions(+), 13 deletions(-) create mode 100644 tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc create mode 100644 tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h diff --git a/content/browser/background_fetch/background_fetch_test_data_manager.cc b/content/browser/background_fetch/background_fetch_test_data_manager.cc index 46107c2..ed03054 100644 --- a/content/browser/background_fetch/background_fetch_test_data_manager.cc +++ b/content/browser/background_fetch/background_fetch_test_data_manager.cc @@ -41,7 +41,9 @@ class MockBGFQuotaManagerProxy : public storage::MockQuotaManagerProxy { const blink::StorageKey& storage_key, blink::mojom::StorageType type, scoped_refptr callback_task_runner, - UsageAndQuotaCallback callback) override { + UsageAndQuotaCallback callback, + storage::QuotaClientType id, + int64_t transaction_size) override { DCHECK(callback_task_runner); // While this DCHECK is true, the PostTask() below isn't strictly necessary. diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc index 510e70c..feb5ee3 100644 --- a/content/browser/indexed_db/transaction_impl.cc +++ b/content/browser/indexed_db/transaction_impl.cc @@ -246,7 +246,8 @@ void TransactionImpl::Commit(int64_t num_errors_handled) { bucket_locator_.storage_key, blink::mojom::StorageType::kTemporary, indexed_db_context_->IDBTaskRunner(), base::BindOnce(&TransactionImpl::OnGotUsageAndQuotaForCommit, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + storage::QuotaClientType::kIndexedDatabase, transaction_->size()); } void TransactionImpl::OnGotUsageAndQuotaForCommit( diff --git a/storage/browser/quota/quota_client_type.h b/storage/browser/quota/quota_client_type.h index ccd83b1..fe3149a 100644 --- a/storage/browser/quota/quota_client_type.h +++ b/storage/browser/quota/quota_client_type.h @@ -15,6 +15,7 @@ namespace storage { // Values are not expected to be persisted or logged. Enum members may be added, // removed, and reordered without warning. enum class QuotaClientType { + kUnknown = 0, kFileSystem = 1, kDatabase = 2, kIndexedDatabase = 3, diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc index 28e4554..af881c2 100644 --- a/storage/browser/quota/quota_manager_impl.cc +++ b/storage/browser/quota/quota_manager_impl.cc @@ -214,8 +214,14 @@ class QuotaManagerImpl::UsageAndQuotaInfoGatherer : public QuotaTask { manager()->GetStorageCapacity( base::BindOnce(&UsageAndQuotaInfoGatherer::OnGotCapacity, weak_factory_.GetWeakPtr(), barrier)); +#if BUILDFLAG(IS_TIZEN) + // max quota size is 2 GB on Tizen + SetDesiredStorageKeyQuota(barrier, blink::mojom::QuotaStatusCode::kOk, + 2 * 1024 * kMBytes); +#else SetDesiredStorageKeyQuota(barrier, blink::mojom::QuotaStatusCode::kOk, kNoLimit); +#endif } else if (type_ == StorageType::kSyncable) { SetDesiredStorageKeyQuota(barrier, blink::mojom::QuotaStatusCode::kOk, kSyncableStorageDefaultHostQuota); @@ -1339,12 +1345,16 @@ void QuotaManagerImpl::GetUsageAndQuota(const StorageKey& storage_key, DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(callback); +#if !BUILDFLAG(IS_TIZEN) + // it needs maximum quota for unlimitedstorage policy. the max quota will be + // calculated in GetUsageAndQuotaForWebApps(). if (IsStorageUnlimited(storage_key, type)) { // TODO(michaeln): This seems like a non-obvious odd behavior, probably for // apps/extensions, but it would be good to eliminate this special case. std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk, 0, kNoLimit); return; } +#endif GetUsageAndQuotaWithBreakdown( storage_key, type, @@ -3077,4 +3087,45 @@ QuotaAvailability QuotaManagerImpl::GetVolumeInfo(const base::FilePath& path) { base::SysInfo::AmountOfFreeDiskSpace(path)); } +#if BUILDFLAG(IS_TIZEN) +void QuotaManagerImpl::GetTizenUnlimitedStoragePrivilege( + const GURL& origin, + QuotaClientType id, + int64_t transaction_size, + UsageAndQuotaCallback callback, + blink::mojom::QuotaStatusCode status, + int64_t usage, + int64_t quota) { + if (id == storage::QuotaClientType::kIndexedDatabase && + status == blink::mojom::QuotaStatusCode::kOk && + transaction_size + usage > quota) { + if (special_storage_policy_.get()) { + special_storage_policy_->RequestUnlimitedStoragePolicy( + origin, quota, + base::BindOnce( + &QuotaManagerImpl::DidGetTizenUnlimitedStoragePrivilege, + weak_factory_.GetWeakPtr(), origin, std::move(callback), status, + usage, quota)); + // callback will be invoked after checking unlimitedstorage privilege. + return; + } + } + std::move(callback).Run(status, usage, quota); +} + +void QuotaManagerImpl::DidGetTizenUnlimitedStoragePrivilege( + const GURL& origin, + UsageAndQuotaCallback callback, + blink::mojom::QuotaStatusCode status, + int64_t usage, + int64_t quota, + bool policy_changed) { + if (policy_changed) + GetUsageAndQuota(StorageKey(url::Origin::Create(origin)), + StorageType::kTemporary, std::move(callback)); + else + std::move(callback).Run(status, usage, quota); +} +#endif + } // namespace storage diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h index b6dfe1f..e214300 100644 --- a/storage/browser/quota/quota_manager_impl.h +++ b/storage/browser/quota/quota_manager_impl.h @@ -434,6 +434,24 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // DevTools clients/QuotaOverrideHandle with an active override. void WithdrawOverridesForHandle(int handle_id); +#if BUILDFLAG(IS_TIZEN) + void GetTizenUnlimitedStoragePrivilege(const GURL& origin, + QuotaClientType id, + int64_t transaction_size, + UsageAndQuotaCallback callback, + blink::mojom::QuotaStatusCode status, + int64_t usage, + int64_t quota); + + void DidGetTizenUnlimitedStoragePrivilege( + const GURL& origin, + UsageAndQuotaCallback callback, + blink::mojom::QuotaStatusCode status, + int64_t usage, + int64_t quota, + bool policy_changed); +#endif + // Cap size for per-host persistent quota determined by the histogram. // Cap size for per-host persistent quota determined by the histogram. // This is a bit lax value because the histogram says nothing about per-host diff --git a/storage/browser/quota/quota_manager_proxy.cc b/storage/browser/quota/quota_manager_proxy.cc index a447f5b..6bf3767 100644 --- a/storage/browser/quota/quota_manager_proxy.cc +++ b/storage/browser/quota/quota_manager_proxy.cc @@ -32,6 +32,7 @@ #include "storage/browser/quota/storage_directory_util.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" +#include "url/gurl.h" using ::blink::StorageKey; @@ -528,7 +529,9 @@ void QuotaManagerProxy::GetUsageAndQuota( const StorageKey& storage_key, blink::mojom::StorageType type, scoped_refptr callback_task_runner, - UsageAndQuotaCallback callback) { + UsageAndQuotaCallback callback, + QuotaClientType id, + int64_t transaction_size) { DCHECK(callback_task_runner); DCHECK(callback); @@ -537,7 +540,7 @@ void QuotaManagerProxy::GetUsageAndQuota( FROM_HERE, base::BindOnce(&QuotaManagerProxy::GetUsageAndQuota, this, storage_key, type, std::move(callback_task_runner), - std::move(callback))); + std::move(callback), id, transaction_size)); return; } @@ -550,7 +553,17 @@ void QuotaManagerProxy::GetUsageAndQuota( return; } - quota_manager_impl_->GetUsageAndQuota(storage_key, type, std::move(respond)); + UsageAndQuotaCallback wrapped_callback = +#if BUILDFLAG(IS_TIZEN) + (type == blink::mojom::StorageType::kTemporary) + ? base::BindOnce(&QuotaManagerImpl::GetTizenUnlimitedStoragePrivilege, + quota_manager_impl_, storage_key.origin().GetURL(), + id, transaction_size, std::move(callback)) + : +#endif + std::move(callback); + + quota_manager_impl_->GetUsageAndQuota(storage_key, type, std::move(wrapped_callback)); } void QuotaManagerProxy::GetBucketUsageAndQuota( diff --git a/storage/browser/quota/quota_manager_proxy.h b/storage/browser/quota/quota_manager_proxy.h index 6f626c7..59e3790 100644 --- a/storage/browser/quota/quota_manager_proxy.h +++ b/storage/browser/quota/quota_manager_proxy.h @@ -228,7 +228,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy const blink::StorageKey& storage_key, blink::mojom::StorageType type, scoped_refptr callback_task_runner, - UsageAndQuotaCallback callback); + UsageAndQuotaCallback callback, + QuotaClientType id = QuotaClientType::kUnknown, + int64_t transaction_size = 0); void GetBucketUsageAndQuota( const BucketInfo& bucket, diff --git a/storage/browser/quota/special_storage_policy.h b/storage/browser/quota/special_storage_policy.h index 30b3826..16d0079 100644 --- a/storage/browser/quota/special_storage_policy.h +++ b/storage/browser/quota/special_storage_policy.h @@ -5,6 +5,7 @@ #ifndef STORAGE_BROWSER_QUOTA_SPECIAL_STORAGE_POLICY_H_ #define STORAGE_BROWSER_QUOTA_SPECIAL_STORAGE_POLICY_H_ +#include "base/callback.h" #include "base/component_export.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" @@ -28,6 +29,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SpecialStoragePolicy : public base::RefCountedThreadSafe { public: REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); + using QuotaExceededReplyCallback = + base::OnceCallback; using StoragePolicy = int; enum ChangeFlags { @@ -79,6 +82,15 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SpecialStoragePolicy // Returns true if some origins are only allowed session-only storage. virtual bool HasSessionOnlyOrigins() = 0; +#if BUILDFLAG(IS_TIZEN) + virtual void RequestUnlimitedStoragePolicy( + const GURL& origin, + int64_t quota, + QuotaExceededReplyCallback callback) { + return; + } +#endif + // Adds/removes an observer, the policy does not take // ownership of the observer. Should only be called on the IO thread. void AddObserver(Observer* observer); diff --git a/storage/browser/test/mock_quota_manager_proxy.cc b/storage/browser/test/mock_quota_manager_proxy.cc index 0809ff1..49b5132 100644 --- a/storage/browser/test/mock_quota_manager_proxy.cc +++ b/storage/browser/test/mock_quota_manager_proxy.cc @@ -89,7 +89,9 @@ void MockQuotaManagerProxy::GetUsageAndQuota( const blink::StorageKey& storage_key, blink::mojom::StorageType type, scoped_refptr callback_task_runner, - QuotaManager::UsageAndQuotaCallback callback) { + QuotaManager::UsageAndQuotaCallback callback, + QuotaClientType id, + int64_t transaction_size) { if (mock_quota_manager_) { mock_quota_manager_->GetUsageAndQuota(storage_key, type, std::move(callback)); diff --git a/storage/browser/test/mock_quota_manager_proxy.h b/storage/browser/test/mock_quota_manager_proxy.h index aad73e7..46d6b7b 100644 --- a/storage/browser/test/mock_quota_manager_proxy.h +++ b/storage/browser/test/mock_quota_manager_proxy.h @@ -74,7 +74,9 @@ class MockQuotaManagerProxy : public QuotaManagerProxy { const blink::StorageKey& storage_key, blink::mojom::StorageType type, scoped_refptr callback_task_runner, - UsageAndQuotaCallback callback) override; + UsageAndQuotaCallback callback, + QuotaClientType id = QuotaClientType::kUnknown, + int64_t transaction_size = 0) override; void GetUsageAndQuota( const storage::BucketLocator& bucket_locator, diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index d5e87fb..3c4b39e 100755 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -209,6 +209,8 @@ shared_library("chromium-ewk") { "browser/sound_effect.cc", "browser/sound_effect.h", "browser/sound_effect_tizen.cc", + "browser/special_storage_policy_efl.cc", + "browser/special_storage_policy_efl.h", "browser/ssl_host_state_delegate_efl.cc", "browser/ssl_host_state_delegate_efl.h", "browser/tizen_extensible_host.cc", diff --git a/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc b/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc new file mode 100644 index 0000000..9e1e926 --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.cc @@ -0,0 +1,82 @@ +// Copyright (c) 2018 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "special_storage_policy_efl.h" + +#include "base/containers/contains.h" +#include "base/stl_util.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "url/origin.h" + +using content::BrowserThread; + +SpecialStoragePolicyEfl::SpecialStoragePolicyEfl() {} + +SpecialStoragePolicyEfl::~SpecialStoragePolicyEfl() { + quota_exceeded_callback_.Reset(); +} + +bool SpecialStoragePolicyEfl::IsStorageUnlimited(const GURL& origin) { + base::AutoLock locker(lock_); + if (!base::Contains(unlimited_, origin)) + return false; + return unlimited_.find(origin)->second; +} + +#if BUILDFLAG(IS_TIZEN) +void SpecialStoragePolicyEfl::RequestUnlimitedStoragePolicy( + const GURL& origin, + int64_t quota, + QuotaExceededReplyCallback callback) { + { + base::AutoLock locker(lock_); + if (base::Contains(unlimited_, origin) || + quota_exceeded_callback_.is_null()) { + LOG(INFO) << __func__ << " unlimited."; + std::move(callback).Run(false /* policy_changed */); + return; + } + } + LOG(INFO) << __func__ << " quota exceeded callback run."; + std::move(quota_exceeded_callback_).Run(origin, quota); + quota_exceeded_reply_callback_ = std::move(callback); +} +#endif + +void SpecialStoragePolicyEfl::SetQuotaExceededCallback( + QuotaExceededCallback callback) { + quota_exceeded_callback_ = std::move(callback); +} + +void SpecialStoragePolicyEfl::SetUnlimitedStoragePolicy(const GURL& origin, + bool allow) { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&SpecialStoragePolicyEfl::SetUnlimitedStoragePolicy, + base::Unretained(this), origin, allow)); + return; + } + + bool policy_changed = IsStorageUnlimited(origin) != allow; + LOG(INFO) << __func__ << "() allow:" << allow + << ", changed:" << policy_changed; + { + base::AutoLock locker(lock_); + unlimited_[origin] = allow; + } + if (policy_changed) { + if (allow) + NotifyGranted(url::Origin::Create(origin), + SpecialStoragePolicy::STORAGE_UNLIMITED); + else + NotifyRevoked(url::Origin::Create(origin), + SpecialStoragePolicy::STORAGE_UNLIMITED); + } + if (!quota_exceeded_reply_callback_.is_null()) { + LOG(INFO) << __func__ << " quota exceeded reply callback run."; + std::move(quota_exceeded_reply_callback_).Run(policy_changed); + } +} diff --git a/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h b/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h new file mode 100644 index 0000000..81c530f --- /dev/null +++ b/tizen_src/ewk/efl_integration/browser/special_storage_policy_efl.h @@ -0,0 +1,52 @@ +// Copyright (c) 2018 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SPECIAL_STORAGE_POLICY_EFL_H_ +#define SPECIAL_STORAGE_POLICY_EFL_H_ + +#include + +#include "base/callback.h" +#include "base/synchronization/lock.h" +#include "storage/browser/quota/special_storage_policy.h" +#include "url/gurl.h" + +class SpecialStoragePolicyEfl : public storage::SpecialStoragePolicy { + public: + using QuotaExceededCallback = + base::OnceCallback; + SpecialStoragePolicyEfl(); + + // storage::SpecialStoragePolicy implementation. + bool IsStorageProtected(const GURL& origin) override { return false; } + bool IsStorageUnlimited(const GURL& origin) override; + bool IsStorageSessionOnly(const GURL& origin) override { return false; } + bool HasIsolatedStorage(const GURL& origin) override { return false; } + bool HasSessionOnlyOrigins() override { return false; } + bool IsStorageDurable(const GURL& origin) override { return false; } + +// for quota exceeded callback +#if BUILDFLAG(IS_TIZEN) + void RequestUnlimitedStoragePolicy( + const GURL& origin, + int64_t quota, + QuotaExceededReplyCallback callback) override; +#endif + void SetQuotaExceededCallback(QuotaExceededCallback callback); + void SetUnlimitedStoragePolicy(const GURL& origin, bool allow); + + protected: + ~SpecialStoragePolicyEfl() override; + + SpecialStoragePolicyEfl(const SpecialStoragePolicyEfl&) = delete; + SpecialStoragePolicyEfl& operator=(const SpecialStoragePolicyEfl&) = delete; + + private: + base::Lock lock_; + std::map unlimited_; + QuotaExceededCallback quota_exceeded_callback_; + QuotaExceededReplyCallback quota_exceeded_reply_callback_; +}; + +#endif // SPECIAL_STORAGE_POLICY_EFL_H_ diff --git a/tizen_src/ewk/efl_integration/browser_context_efl.cc b/tizen_src/ewk/efl_integration/browser_context_efl.cc index 42348cf..2c50667 100644 --- a/tizen_src/ewk/efl_integration/browser_context_efl.cc +++ b/tizen_src/ewk/efl_integration/browser_context_efl.cc @@ -321,4 +321,10 @@ BrowsingDataRemoverDelegate* BrowserContextEfl::GetBrowsingDataRemoverDelegate() { return nullptr; } + +SpecialStoragePolicyEfl* BrowserContextEfl::GetSpecialStoragePolicyEfl() { + if (!special_storage_policy_efl_.get()) + special_storage_policy_efl_ = new SpecialStoragePolicyEfl(); + return special_storage_policy_efl_.get(); +} } diff --git a/tizen_src/ewk/efl_integration/browser_context_efl.h b/tizen_src/ewk/efl_integration/browser_context_efl.h index bef9a1e..47668bc 100644 --- a/tizen_src/ewk/efl_integration/browser_context_efl.h +++ b/tizen_src/ewk/efl_integration/browser_context_efl.h @@ -10,6 +10,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/synchronization/lock.h" #include "browser/geolocation/geolocation_permission_context_efl.h" +#include "browser/special_storage_policy_efl.h" #include "browser/ssl_host_state_delegate_efl.h" #include "components/visitedlink/browser/visitedlink_delegate.h" #include "content/public/browser/browser_context.h" @@ -101,8 +102,9 @@ class BrowserContextEfl : public BrowserContext, } BrowserPluginGuestManager* GetGuestManager() override { return 0; } storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override { - return 0; + return GetSpecialStoragePolicyEfl(); } + SpecialStoragePolicyEfl* GetSpecialStoragePolicyEfl(); PushMessagingService* GetPushMessagingService() override { return 0; } base::FilePath GetPath() override; base::FilePath GetCachePath() const; @@ -151,6 +153,7 @@ class BrowserContextEfl : public BrowserContext, std::unique_ptr ssl_host_state_delegate_; std::unique_ptr background_sync_controller_; std::unique_ptr permission_controller_delegate_; + scoped_refptr special_storage_policy_efl_; }; } diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index e28f0fe..9dbc816 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -2540,3 +2540,51 @@ void EWebView::DidRespondRequestManifest( void* user_data) { callback(evas_object_, manifest, user_data); } + +void EWebView::SetExceededIndexedDatabaseQuotaCallback( + Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback, + void* user_data) { + exceeded_indexed_db_quota_callback_.Set(callback, user_data); + content::BrowserContextEfl* browser_context = + static_cast( + web_contents_->GetBrowserContext()); + if (browser_context) { + browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback( + base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback, + base::Unretained(this))); + } +} + +void EWebView::InvokeExceededIndexedDatabaseQuotaCallback( + const GURL& origin, + int64_t current_quota) { + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + base::ThreadPool::PostTask( + FROM_HERE, {BrowserThread::UI}, + base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback, + base::Unretained(this), origin, current_quota)); + return; + } + LOG(INFO) << __func__ << "()" << origin << ", " << current_quota; + CHECK(!exceeded_indexed_db_quota_origin_.get()); + exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin)); + exceeded_indexed_db_quota_callback_.Run( + evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota); +} + +void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) { + if (!exceeded_indexed_db_quota_origin_.get()) { + LOG(WARNING) << __func__ << "() : callback is not invoked!"; + return; + } + LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL() + << ", " << allow; + content::BrowserContextEfl* browser_context = + static_cast( + web_contents_->GetBrowserContext()); + if (browser_context) { + browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy( + exceeded_indexed_db_quota_origin_->GetURL(), allow); + } + exceeded_indexed_db_quota_origin_.reset(); +} diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index 3fd06db..53a930f 100755 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -114,6 +114,30 @@ class WebViewCallback { void* user_data_; }; +template +class WebViewExceededQuotaCallback { + public: + WebViewExceededQuotaCallback() { Set(nullptr, nullptr); } + + void Set(CallbackPtr cb, void* data) { + callback_ = cb; + user_data_ = data; + } + + bool IsCallbackSet() const { return callback_; } + + /* LCOV_EXCL_START */ + void Run(Evas_Object* webview, CallbackParameter... param) { + if (IsCallbackSet()) + callback_(webview, param..., user_data_); + } + /* LCOV_EXCL_STOP */ + + private: + CallbackPtr callback_; + void* user_data_; +}; + class WebApplicationIconUrlGetCallback { public: WebApplicationIconUrlGetCallback(Ewk_Web_App_Icon_URL_Get_Callback func, @@ -485,6 +509,13 @@ class EWebView { return gin_native_bridge_dispatcher_host_.get(); } + void SetExceededIndexedDatabaseQuotaCallback( + Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback, + void* user_data); + void InvokeExceededIndexedDatabaseQuotaCallback(const GURL& origin, + int64_t current_quota); + void ExceededIndexedDatabaseQuotaReply(bool allow); + /// ---- Event handling bool HandleShow(); bool HandleHide(); @@ -636,6 +667,13 @@ class EWebView { std::unique_ptr gin_native_bridge_dispatcher_host_; + WebViewExceededQuotaCallback< + Ewk_View_Exceeded_Indexed_Database_Quota_Callback, + Ewk_Security_Origin*, + long long> + exceeded_indexed_db_quota_callback_; + std::unique_ptr exceeded_indexed_db_quota_origin_; + #if BUILDFLAG(IS_TIZEN) blink::mojom::FileChooserParams::Mode filechooser_mode_; #endif diff --git a/tizen_src/ewk/efl_integration/public/ewk_view.cc b/tizen_src/ewk/efl_integration/public/ewk_view.cc index 0e7b349..3ebd7f3 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_view.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_view.cc @@ -813,20 +813,22 @@ void ewk_view_application_cache_permission_reply(Evas_Object* ewkView, Eina_Bool LOG_EWK_API_MOCKUP("Not Supported by chromium"); } -void ewk_view_exceeded_indexed_database_quota_callback_set(Evas_Object* ewkView, Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback, void* userData) +void ewk_view_exceeded_indexed_database_quota_callback_set(Evas_Object* view, Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback, void* user_data) { // Chromium does not support quota for Indexed DB only. // IndexedDB uses temporary storage that is shared // between other features. - LOG_EWK_API_MOCKUP("Not Supported by chromium"); + EWK_VIEW_IMPL_GET_OR_RETURN(view, impl); + impl->SetExceededIndexedDatabaseQuotaCallback(callback, user_data); } -void ewk_view_exceeded_indexed_database_quota_reply(Evas_Object* ewkView, Eina_Bool allow) +void ewk_view_exceeded_indexed_database_quota_reply(Evas_Object* view, Eina_Bool allow) { // Chromium does not support quota for Indexed DB only. // IndexedDB uses temporary storage that is shared // between other features. - LOG_EWK_API_MOCKUP("Not Supported by chromium"); + EWK_VIEW_IMPL_GET_OR_RETURN(view, impl); + impl->ExceededIndexedDatabaseQuotaReply(allow); } Eina_Bool ewk_view_text_find(Evas_Object *view, const char *text, Ewk_Find_Options options, unsigned int max_match_count) diff --git a/tizen_src/ewk/ubrowser/window.cc b/tizen_src/ewk/ubrowser/window.cc index f34e706..393a104 100644 --- a/tizen_src/ewk/ubrowser/window.cc +++ b/tizen_src/ewk/ubrowser/window.cc @@ -195,6 +195,8 @@ Window::Window(Browser& browser, int width, int height, bool incognito) web_view_, &Window::OnQuotaPermissionRequest, this); ewk_view_did_change_theme_color_callback_set( web_view_, &Window::OnThemeColorChanged, this); + ewk_view_exceeded_indexed_database_quota_callback_set( + web_view_, Window::OnQuotaExceededIndexedDB, this); ewk_settings_form_profile_data_enabled_set(GetEwkSettings(), true); ewk_settings_form_candidate_data_enabled_set(GetEwkSettings(), true); @@ -844,6 +846,15 @@ void Window::OnScreenshotCaptured(Evas_Object* image, void* user_data) { log_info("Screenshot image could not be saved"); } +void Window::OnQuotaExceededIndexedDB(Evas_Object*, + Ewk_Security_Origin* origin, + long long currentQuota, + void* data) { + log_trace("%s", __PRETTY_FUNCTION__); + Window* thiz = static_cast(data); + ewk_view_exceeded_indexed_database_quota_reply(thiz->web_view_, true); +} + void Window::Exit() const { browser_.Exit(); } diff --git a/tizen_src/ewk/ubrowser/window.h b/tizen_src/ewk/ubrowser/window.h index 9289c70..61c9987 100644 --- a/tizen_src/ewk/ubrowser/window.h +++ b/tizen_src/ewk/ubrowser/window.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "build/build_config.h" @@ -67,6 +68,10 @@ class Window { static void OnOrientationChanged(void*, Evas_Object*, void*); static void OnNewWindowPolicyDecide(void*, Evas_Object*, void*); static void OnBackForwardListChanged(void*, Evas_Object*, void*); + static void OnQuotaExceededIndexedDB(Evas_Object*, + Ewk_Security_Origin* origin, + long long currentQuota, + void* data); static void OnQuotaPermissionRequest(Evas_Object*, const Ewk_Quota_Permission_Request*, void*); static void OnScreenshotCaptured(Evas_Object*, void*); static void OnUserMediaPermissionRequest(void* data, Evas_Object*, void* event_info); -- 2.7.4